<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
		<id>https://rn-wissen.de/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Inrfb2</id>
		<title>RN-Wissen.de - Benutzerbeiträge [de]</title>
		<link rel="self" type="application/atom+xml" href="https://rn-wissen.de/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Inrfb2"/>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Spezial:Beitr%C3%A4ge/Inrfb2"/>
		<updated>2026-04-11T20:44:57Z</updated>
		<subtitle>Benutzerbeiträge</subtitle>
		<generator>MediaWiki 1.25.1</generator>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=11059</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=11059"/>
				<updated>2007-04-09T21:37:26Z</updated>
		
		<summary type="html">&lt;p&gt;Inrfb2: /* &amp;lt;tt&amp;gt;&amp;lt;Parameterliste&amp;gt;&amp;lt;/tt&amp;gt; */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Programmiersprache C wurde 1971 als Gundlage für das Betriebssystem UNIX in den USA entwickelt (UNIX ist zu über 90% in C geschrieben). 1978 wurde von Brian Kernighan und Dennis Ritchie eine eindeutige Sprachdefinition entwickelt. Mittlerweile ist C von ANSI und ISO standardisiert.&lt;br /&gt;
&lt;br /&gt;
Heute sind C und ihr Nachfolger C++ die dominierenden Programmiersprachen. Sehr viele Anwendungen sind in C geschrieben, was inzwischen auch auf eingebettete Systeme zutrifft, die lange in Assembler programmiert werden mussten, da keine ausreichend leistungsfähigen Compiler zur Verfügung standen. &lt;br /&gt;
&lt;br /&gt;
Leider ist C nicht einfach zu lernen &amp;amp;ndash; es wurde weder von noch für Hobby-Programmierer entwickelt &amp;amp;ndash; und eignet sich daher nur bedingt für den Einsteiger. Mit etwas Übung und einem optimierenden Compiler kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
Vom Design her ist C eine Hardware-unabhängig Sprache. Das bedeutet, daß C-Programme mit vertretbarem Aufwand auf ein anderes System portiert werden können. Dazu benötigt man lediglich einen anderen Compiler, und Inline-Assembler-Anweisungen (Assembleranweisungen innerhalb eines C-Programmes) müssen der neuen Hardware (Prozessor) angepasst werden. &lt;br /&gt;
&lt;br /&gt;
==Geschichte==&lt;br /&gt;
;1971: C wird entwickelt&lt;br /&gt;
;1978: Kernighan und Ritchie definieren die Sprache.&lt;br /&gt;
;1983: ANSI und ISO standardisieren C.&lt;br /&gt;
;1992: Bjarne Stroustrup enwickelt die Nachfolgesprache C++.&lt;br /&gt;
&lt;br /&gt;
=Aufbau eines C-Programmes=&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
   C-Programme haben keinen fixen Aufbau wie z.B. Pascal. Es gibt zwar gewisse Regeln, aber sonst sind dem Programmierer alle Freiheiten überlassen. Der folgende &amp;quot;Beispiel-Aufbau&amp;quot; ist daher nicht zwingend und kann durchaus verändert werden.&lt;br /&gt;
&lt;br /&gt;
   Natürlich haben C-Programme einen fixen Aufbau! Ebenso wie Pascal-Programme auch unterliegen sie einer strikten Grammatik! &lt;br /&gt;
Auskommentiert --[[Benutzer:SprinterSB|SprinterSB]] 10:23, 17. Feb 2006 (CET)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Ein einfaches C-Programm könnte folgendermassen aussehen. Das Programm tut eigentlich nichts, aber das Beispiel zeigt den prinzipiellen Aufbau. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 int Zahl1;&lt;br /&gt;
 char Zeichen1;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int zahl2;&lt;br /&gt;
 &lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Beschreibung:'''&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndash; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
 {{comment|void-Definition von main ist nur beim Controller ueblich}}&lt;br /&gt;
 {{comment|spezielle Compilereinstellungen sind noetig, damit bei dieser Definition von main}}&lt;br /&gt;
 {{comment|kein Fehler/Warnung erzeugt wird.}}&lt;br /&gt;
 void main ()&lt;br /&gt;
 {&lt;br /&gt;
     ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
 int main (void)&lt;br /&gt;
 {  {{comment|der Block &amp;quot;main&amp;quot; beginnt}}&lt;br /&gt;
    int zahl;&lt;br /&gt;
    &lt;br /&gt;
    {   {{comment|ein Block beginnt}}&lt;br /&gt;
        {{comment|hier koennen Deklarationen und Anweisungen stehen}}&lt;br /&gt;
    }   {{comment|der Block endet}}&lt;br /&gt;
   &lt;br /&gt;
    return 0;&lt;br /&gt;
 }  {{comment|&amp;quot;main&amp;quot; endet}}&lt;br /&gt;
&lt;br /&gt;
=Datentypen=&lt;br /&gt;
==Elementare Datentypen==&lt;br /&gt;
Der Datentyp einer Variable gibt an, welche Werte eine Variable enthalten kann, welcher Art diese Daten sind und wie sie verarbeitet werden, etwa in arithmetischen Operationen wie einer Addition. So ist es zum Beispiel möglich, in eine Variable vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ganze Zahlen zwischen ca. -32000 und +32000 einzutragen. In einer char-Variable können ASCII-Zeichen gespeichert werden (alles, was Sie mit der Tastatur erzeugen können) oder ganze Zahlen von -128 bis 127.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da C plattformabhängig ist, hängt die Größe eines Datentypes zum Teil von der genutzten Hardware (z.B. 8, 16 oder 32 Bit-Controller) und dem Compiler und dessen Einstellungen ab!&lt;br /&gt;
&lt;br /&gt;
===int, char, short, long (ganze Zahlen)===&lt;br /&gt;
In Variable dieser Typen können Sie ganze Zahlen abspeichern, also z.B. 1, &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;2, 100, 12345. Jeden dieser Typen gibt es in zwei Ausprägungen: als &amp;quot;&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;quot;, also als vorzeichenbehafteten Typ, und als &amp;quot;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&amp;quot;, also ohne Vorzeichen, d.h. das Vorzeichen wird als 0 oder +1 genommen. &lt;br /&gt;
&lt;br /&gt;
Vorzeichenbehaftete Ganzzahl-Typen werden intern im &amp;lt;tt&amp;gt;n-1&amp;lt;/tt&amp;gt;-Komplement dargestellt, das Vorzeichen selbst findet sich also im höchstwertigen Bit. Werden zur Speicherung ''b'' Bits verwendet, dann reicht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;z.B. *zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==Enum==&lt;br /&gt;
&lt;br /&gt;
Über &amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt; können Aufzählungen definiert werden. Die Werte sind &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Werte und beginnen mit&amp;amp;nbsp;0. Der folgende enum hat einen um&amp;amp;nbsp;1 grösseren Wert. Mit einer Zuweisung können auch andere Werte zugeordnet werden. Klarer wird's im Beispiel:&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 enum Farben&lt;br /&gt;
 {&lt;br /&gt;
    ROT,&lt;br /&gt;
    GRUEN,&lt;br /&gt;
    BLAU,&lt;br /&gt;
    BRAUN = 5,&lt;br /&gt;
    SCHWARZ&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
Dies definiert die Konstanten &amp;lt;tt&amp;gt;ROT=0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;GRUEN=1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BLAU=2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BRAUN=5&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;SCHWARZ=6&amp;lt;/tt&amp;gt; und den Typ &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void foo (enum Farben farbe)&lt;br /&gt;
{&lt;br /&gt;
   switch (farbe)&lt;br /&gt;
   {&lt;br /&gt;
      case ROT:&lt;br /&gt;
         ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit kann man anstatt &amp;quot;magischer&amp;quot; Zahlen sprechende Namen im Code verwenden, etwa in Berechnungen und Zuweisungen, Vergleichen oder als Konstante hinter einem &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zusammengesetzte Datentypen==&lt;br /&gt;
===Arrays===&lt;br /&gt;
Oft muß man sehr viele Werte gleichzeitig abspeichern und betrachten, die alle der selben Aufgabe dienen. Man schreibt z.B. ein Programm, das 10 Zahlen einlesen und anschließend wieder ausgeben soll. Man könnte das natürlich mit 10 einzelnen Variablen bewerkstelligen, aber es ist sinnvoller, dabei Arrays &amp;amp;ndash; teilweise auch als ''Felder'' bezeichnet &amp;amp;ndash; zu verwenden.&lt;br /&gt;
&lt;br /&gt;
In einem Array werden mehrere Variablen gleichen Typs zusammengefasst und hintereinander im Speicher abgelegt. So kann man viele tausend Variablen anlegen mit nur einer Zeile Code. Doch es gibt noch größere Vorteile: Sie können das Array mit einer Schleife ganz einfach nach Werten durchsuchen. Stellen Sie sich vor, Sie müssten mit 100 verschiedenen Variablen &amp;lt;tt&amp;gt;Zahl_00&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;Zahl_99&amp;lt;/tt&amp;gt; arbeiten!&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}}&amp;amp;#91;{{Konstante}}&amp;amp;#93;;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 unsigned int werte[100];&lt;br /&gt;
&lt;br /&gt;
Der Name muß natürlich ein gültiger Bezeichner sein, als Datentyp kann jeder Typ genommen werden &amp;amp;ndash; sowohl elementare Datentypen als auch Zeiger, Strukturen, Unions oder selbst definierte Datentypen. In der eckigen Klammer wird die Anzahl der Elemente bekanntgegeben. Ein mit [3] definiertes Array hat Platz für drei Variablen. Da der Index immer bei 0 beginnt, greift man also mit &amp;lt;tt&amp;gt;[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;[1]&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;[2]&amp;lt;/tt&amp;gt; auf den jeweilige Inhalt zu. Um auf eine der im Array enthaltenen Variablen zugreifen zu können, müssen Sie den Variablennamen und in eckigen Klammern den Index (die &amp;quot;Nummer&amp;quot;) der Variablen angeben. Diese Variable verhält sich dann wie eine ganz normale Variable des jeweiligen Datentypes. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #define NZAHLEN 10&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int i;&lt;br /&gt;
    int zahlen[NZAHLEN];  {{comment|zahlen[0] ... zahlen[9]}}&lt;br /&gt;
  &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++)&lt;br /&gt;
    {&lt;br /&gt;
       printf (&amp;quot;Bitte Zahl %d eingeben: &amp;quot;, i);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; zahlen[i]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++) &lt;br /&gt;
       printf (&amp;quot;Zahl %d ist: %d\n&amp;quot;, i, zahlen[i]);&lt;br /&gt;
      &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 10 int-Variablen großes Array angelegt. &lt;br /&gt;
In dieses wird nun der Reihe nach 10 Zahlen eingelesen. &lt;br /&gt;
Anschließend werden alle 10 Zahlen ausgegeben. &lt;br /&gt;
&lt;br /&gt;
Dabei wird die Größe der Arrays und das Schleifenende über das Define &amp;quot;&amp;lt;tt&amp;gt;NZAHLEN&amp;lt;/tt&amp;gt;&amp;quot; angegeben. Dadurch muss nur ''eine Stelle'' im Code geändert werden, wenn die Größe des Arrays einmal einen anderer Wert als 10 haben soll &amp;amp;ndash; dies vermeidet Fehler die dadurch entstehen, wenn man beim Anpassen der Array-Größe eine Codestelle vergisst, zudem wird der Code lesbarer als wenn irgendwo die Zahl &amp;quot;10&amp;quot; auftaucht.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
:Wird ein ungültiger Index angeben (einer, der in der Deklaration nicht enthalten ist) können  undefinierte Dinge passieren, wenn dadurch andere Variableninhalte oder Programmcode überschrieben wird, der hinter oder vor dem Array im Speicher liegt. Schlimmstenfalls kann sogar der Computer/Controller abstürzen. Also darauf achten, daß keine ungültigen Werte als Index auftreten!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Strings (Zeichenketten)===&lt;br /&gt;
Ein String ist nichts anderes als ein Array, das aus einzelnen Zeichen (&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;) gebildet wird. Die Ausgabe auf dem Bildschirm funktioniert am einfachsten mittels Strings.&lt;br /&gt;
&lt;br /&gt;
Die Definition eines Strings erfolgt also genauso wie bei Arrays:&lt;br /&gt;
 char string[21];&lt;br /&gt;
&lt;br /&gt;
Nun haben Sie eine String, in dem Sie 21 Zeichen speichern können. Ganz richtig ist das jedoch nicht. C arbeitet mit &amp;quot;null-terminierten Strings&amp;quot;. Das beudeutet, dass die Länge des Strings nicht abgespeichert wird, sondern das Zeichen mit dem ASCII-Wert 0 das Stringende kennzeichnet. Daher auch die Bezeichnung  &amp;quot;null terminiert&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Das letzte Zeichen eines Strings muß daher immer das ASCII-Zeichen Nr. 0 sein. Ist es das nicht, hat der String kein definiertes Ende, und wenn Sie versuchen, ihn durch eine Standard-Funktion auszugeben zu lassen, könnte es eine Weile dauern, bis sich im Speicher zufällig irgendwo eine 0 befindet. Es stehen ihnen daher bei dem Beispiel nur 20 Zeichen zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
===Mehrdimensionale Arrays===&lt;br /&gt;
Manchmal benötigt man mehr als nur ein eindimensionales Array, wie Sie es bisher kennengelernt haben. Auch dies ist kein Problem. In der Deklaration geben Sie einfach mehrere eckige Klammern hintereinander an. Aber Vorsicht: der Speicherplatz ist begrenzt, ein &amp;quot;&amp;lt;tt&amp;gt;char feld[1024][1024]&amp;lt;/tt&amp;gt;&amp;quot; hat die Speicherplatzgrenzen vermutlich bereits weit überschritten, und der Compiler wird einen (bei gewissen Einstellung auch keinen) Fehler liefern.&lt;br /&gt;
Beim Zugriff auf mehrdimensionale Felder müssen auch mehrere Indizes angeben werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  int x,y;&lt;br /&gt;
  int feld[3][5];&lt;br /&gt;
 &lt;br /&gt;
  for (x=0; x&amp;lt;3; x++) &lt;br /&gt;
  {&lt;br /&gt;
     for (y=0; y&amp;lt;5; y++)&lt;br /&gt;
     {&lt;br /&gt;
       printf (&amp;quot;Feldwert x: %d,  y: %d &amp;quot;, x, y);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; feld[x][y]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  for(x=0; x&amp;lt;3; x++) &lt;br /&gt;
     for (y=0; y&amp;lt;5; y++) &lt;br /&gt;
        printf (&amp;quot;Wert: feld[%d][%d] = %d\n&amp;quot;, x, y, feld[x][y]);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 3 mal 5 &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array angelegt. &lt;br /&gt;
Dann werden die Werte eingegeben: zuerst &amp;lt;tt&amp;gt;feld[0][0]&amp;lt;/tt&amp;gt;, dann &amp;lt;tt&amp;gt;feld[0][1]&amp;lt;/tt&amp;gt;, usw. bis &amp;lt;tt&amp;gt;feld[2][4]&amp;lt;/tt&amp;gt;. &lt;br /&gt;
Zum Schluß werden alle Werte noch einmal ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===Strukturen===&lt;br /&gt;
In C können Sie sogenannte &amp;quot;Strukturen&amp;quot; definieren. Dabei handelt es sich um eine Zusammenfassung mehrerer Datentypen zu einem größeren. Im Unterschied zu Feldern können in Strukturen unterschiedliche Datentypen zusammengestellt und gespeichert werden: &lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 struct {{Bezeichner}}&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur 'Person'}}&lt;br /&gt;
 struct Person &lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;lt;tt&amp;gt;struct Person {&amp;lt;/tt&amp;gt;&amp;quot; leitet die Definition der Struktur mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;Person&amp;lt;/tt&amp;gt;&amp;quot; ein. &lt;br /&gt;
Dann werden in dieser Struktur fünf Komponenten definiert: drei Strings und zwei &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. &lt;br /&gt;
mit &amp;lt;tt&amp;gt;}&amp;lt;/tt&amp;gt; wird die Definition abgeschlossen. Sie haben damit einen Datentyp erstellt. Um eine Variable des Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach an&lt;br /&gt;
 struct Person {{Bezeichner}};&lt;br /&gt;
&lt;br /&gt;
Zum Zugriff auf eine Komponente der Struktur gibt man den Namen der Struktur-Variablen an (im folgenden Beispiel also &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;klaus&amp;lt;/tt&amp;gt;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
 {{comment|Definition zweier Struktur-Variablen}}&lt;br /&gt;
 struct Person hubert, klaus;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Zugriff auf Struktur-Komponenten}}&lt;br /&gt;
 hubert.alter = 32;&lt;br /&gt;
 klaus.alter = hubert.alter + 1;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis:'''&lt;br /&gt;
Der eventuell etwas lästige Gebrauch von &amp;lt;tt&amp;gt;struct&amp;lt;/tt&amp;gt; kann schon bei der Definition der Struktur vermieden werden.&lt;br /&gt;
Der Definition ist ein &amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt; voranzustellen. Der Definition folgt dann ein gültiger (und auch eindeutiger) C-Name.&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 typedef struct {{Bezeichner}}&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 } {{Bezeichner}} ;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur '_Mensch' bzw. 'Mensch'}}&lt;br /&gt;
 struct _Mensch&lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 } Mensch;&lt;br /&gt;
&lt;br /&gt;
Jetzt sind folgende Deklarationen identisch:&lt;br /&gt;
 struct _Mensch {{Bezeichner}};&lt;br /&gt;
 Mensch {{Bezeichner}};&lt;br /&gt;
&lt;br /&gt;
Ist der Struktuname nicht notwendig (im Beispiel oben &amp;lt;tt&amp;gt;_Mensch&amp;lt;/tt&amp;gt;), kann auch kürzer geschrieben werden:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 typedef struct &lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 } {{Bezeichner}} ;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur 'Mensch'}}&lt;br /&gt;
 struct &lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 } Mensch;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall ist lediglich die {{Deklaration}} &amp;lt;tt&amp;gt;Mensch {{Bezeichner}};&amp;lt;/tt&amp;gt; gültig.&lt;br /&gt;
&lt;br /&gt;
Der Hinweis gilt sinngemäß auch für die Definition &amp;lt;tt&amp;gt;union&amp;lt;/tt&amp;gt; im nachfolgenden Abschnitt.&lt;br /&gt;
&lt;br /&gt;
===Unions===&lt;br /&gt;
Eine Union wird ganz analog zu einer Struktur deklariert und verwendet. Sie unterscheidet sich von einer Struktur jedoch dadurch, daß ihre Elemente nicht nacheinander im Speicher abgelegt werden, sondern sich überlagern. Auf die in einer Union enthaltenen Daten gibt es also verschiedene Sichten: je nachdem, welche Sicht bzw. Interpretation der Daten man gerne hätte, wählt man den gewünschten Zugriff.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
union Daten &lt;br /&gt;
{&lt;br /&gt;
   int id;&lt;br /&gt;
&lt;br /&gt;
   struct Person u_person;&lt;br /&gt;
&lt;br /&gt;
   struct u_double&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      double wert;&lt;br /&gt;
   };&lt;br /&gt;
&lt;br /&gt;
   struct u_pointer&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      union Daten * p1;&lt;br /&gt;
      union Daten * p2;&lt;br /&gt;
   };&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
union Daten data;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies definiert eine Union mit den vier Zugriffsmöglichkeiten &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_double&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Größe der Union richtet sich dabei nach der grössten Komponente. In diesem Beispiel sind alle Komponenten so angelegt worden, daß sie an erster Stelle ein &amp;lt;tt&amp;gt;int id&amp;lt;/tt&amp;gt; enthalten. In &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; könnte man sich also merken, wie die Daten in der Union zu interpretieren sind. Würde &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; nicht dieses &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; enthalten, so würde sich &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; mit &amp;lt;tt&amp;gt;data.u_person.vname&amp;lt;/tt&amp;gt; überlagern. Ein Ändern der ersten Buchstaben von &amp;lt;tt&amp;gt;vname&amp;lt;/tt&amp;gt; hätte also ein Ändern von &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; zur Folge, und man könnte es nicht mehr als Merker verwenden. Mit diesem Feld überlagert das &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; die &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;-Felder der anderen Sichten, z.B. ist &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; der selbe Zugriff wie auf &amp;lt;tt&amp;gt;data.u_person.id&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein anderes Beispiel ist eine Union, die es ermöglicht, auf die einzelnen Bytes eines &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; zuzugreifen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef union&lt;br /&gt;
{&lt;br /&gt;
   unsigned long  as_long;&lt;br /&gt;
   unsignen short as_short[2];&lt;br /&gt;
   unsignen char  as_byte[4];&lt;br /&gt;
} data32_t;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies überlagert einen &amp;lt;tt&amp;gt;unsigned long&amp;lt;/tt&amp;gt; &amp;amp;ndash; also eine 32-Bit-Zahl &amp;amp;ndash; mit vier Bytes bzw. zwei Shorts.&lt;br /&gt;
 data32_t wert;&lt;br /&gt;
 &lt;br /&gt;
 wert.as_long = 0x12345678;&lt;br /&gt;
 wert.as_byte[0] = 0xab;&lt;br /&gt;
 {{comment|nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform)}}&lt;br /&gt;
&lt;br /&gt;
==Eigene Datentypen==&lt;br /&gt;
&lt;br /&gt;
=Variablen=&lt;br /&gt;
Eine Variable ist ein Synonym (=anderer Name) für eine Speicherstelle in einem Computer. Einfacher gesagt, eine Variable bietet Raum, um Daten wie Zahlen oder Zeichen zu speichern und wieder zu lesen.&lt;br /&gt;
&lt;br /&gt;
==Variablennamen==&lt;br /&gt;
Ein Variablenname kann zusammengesetzt werden aus den Buchstaben &amp;lt;tt&amp;gt;'''A'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''Z'''&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;'''a'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''z'''&amp;lt;/tt&amp;gt;, den Ziffern &amp;lt;tt&amp;gt;'''0'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''9'''&amp;lt;/tt&amp;gt;, sowie dem Sonderzeichen &amp;quot;Unterstrich&amp;quot; (underscore) &amp;lt;tt&amp;gt;'''_'''&amp;lt;/tt&amp;gt;. Dabei darf an erster Stelle keine Ziffer stehen. Die Bezeichner &amp;lt;tt&amp;gt;hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALLO&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALL0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;_123&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_HALLO&amp;lt;/tt&amp;gt; sind also alle gültige und unterschiedliche Variablennamen.&lt;br /&gt;
&lt;br /&gt;
==Anlegen von Variablen==&lt;br /&gt;
Um eine Variable verwenden zu können, muss sie zuerst vereinbart (&amp;quot;erzeugt&amp;quot;) werden. Dies wird auch als &amp;quot;''Definition der Variablen''&amp;quot; bezeichnet und geht so: Schreiben Sie zuerst den Datentyp, dann den Namen der Variablen. Zum Schluß kommt noch der Strichpunkt, wie nach jeder C-Anweisung oder Deklaration. Und nicht vergessen: C unterscheidet zwischen  Groß- und Kleinschreibung! &lt;br /&gt;
 int Zahl1, Zahl2;&lt;br /&gt;
 char Zeichen;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    float gleitZahl;&lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:'''&lt;br /&gt;
In einer Zeile können auch mehrere Variablen gleichen Types vereinbart werden, wenn man ein Komma dazwischen setzt. Variablen können in jedem Block vereinbart werden. Siehe [[#Gültigkeitsbereich|Gültigkeitsbereich]].&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen==&lt;br /&gt;
Man kann einer vereinbarten Variable Werte [[#Zuweisungen|zuweisen]]. Dazu schreibt man zuerst den Variablennamen, ein Gleichheitszeichen &amp;quot;&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;&amp;quot; und anschliessend den zuzuweisenden [[#Ausdrücke|Ausdruck]]. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, zahl2 = 12;&lt;br /&gt;
  char zeichen1 = 'A';&lt;br /&gt;
&lt;br /&gt;
  zahl1 = 52;&lt;br /&gt;
  zeichen1 = zeichen1 + 1; &lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Zuerst werden drei Variablen angelegt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;: wird gleich bei der Vereinbarung der Wert 12 zugewiesen. &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl1 = 52&amp;lt;/tt&amp;gt;: Hier wird der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; der Wert 52 zugewiesen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;: wird um 1 erhöht. Da in der Variablen &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; gespeichert ist, gibt sich ihr neuer Wert aus &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt;. Weil &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; dem Wert 65 entspricht, ist &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt; gleich 66, was dem Wert für &amp;lt;tt&amp;gt;'B'&amp;lt;/tt&amp;gt; entspricht.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei float==&lt;br /&gt;
Das funktioniert genau wie bei normale Zuweisungen. Nachkommastellen werden durch einen Punkt abgegrenzt: &lt;br /&gt;
 floatVariable = 3.14;&lt;br /&gt;
Zusätzlich kann eine Zehnerpotenz angegeben werden:&lt;br /&gt;
 floatVariable2 = -1.234E-6;&lt;br /&gt;
Dadurch wird der erst Wert mit 10&amp;lt;sup&amp;gt;&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;6&amp;lt;/sup&amp;gt; multipliziert, der Wert der Variablen ist also &lt;br /&gt;
:&amp;lt;math&amp;gt;-1{,}234\cdot10^{-6} = -0.000001234&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei logischen Variablen==&lt;br /&gt;
Wie bereits erwähnt, besitzt C keinen logischen Datentyp. Es müssen also &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; dafür genutzt werden. Die Zuweisung entpricht der Standard-Zuweisung. Wird der Wert 0 zugewiesen, dann ist die Variable &amp;quot;unwahr&amp;quot;, ansonsten ist sie &amp;quot;wahr&amp;quot;. &lt;br /&gt;
 intVariable = !0;   /* entspricht &amp;quot;wahr&amp;quot;   */&lt;br /&gt;
 intVariable = 0;    /* entspricht &amp;quot;unwahr&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
==Konstanten==&lt;br /&gt;
Konstanten können als Variable angesehen werden, die nicht beschrieben, sondern nur gelesen werden können. Ein typisches Beispiel dafür ist die Zahl &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; (rund 3,141592654). Niemand würde in der realen Welt versuchen, ihr einen anderen Wert zuzuweisen. Würde man &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; jedoch wie eine normale Variable anlegen, wäre dies ohne weiteres möglich. Um dies zu verhindern, gibt es das Schlüsselwort &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in C:&lt;br /&gt;
 const {{Type}} {{Bezeichner}} = {{Konstante}};  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Wichtig dabei ist, dass man Konstanten nur bei der Vereinbarung einen Wert zuweisen kann. &lt;br /&gt;
Da Konstanten gewöhnlich im gesamten Programm, zumindest einer Quelldatei genutzt werden, definiert man diese allerdings gewöhnlich außerhalb des main-Blockes entweder am Anfang eines Programmes, oder in einer sogenannten Header-Datei, die per &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; eingebunden wird.&lt;br /&gt;
 const float PI = 3.141592;  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Es sei jedoch erwähnt, daß auch einer Konstanten nachträglich ein anderer Wert zugewieden werden kann. Im obigen Beispiel könnte mit&lt;br /&gt;
 * ((float*) &amp;amp;PI) = 2;&lt;br /&gt;
der Wert von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; im Nachhinein verändert werden. Es wird die Adresse von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; genommen und diese Adresse durch den Cast in eine ganz normale &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;-Adresse umgewandelt, über welche der Wert geändert wird. Die sei der Vollständigkeit halber erwähnt.&lt;br /&gt;
&lt;br /&gt;
Je nachdem, an welcher Stelle sich das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; bei einer Pointer-Deklaration befindet, markiert es den Pointer als konstant oder das Objekt, auf das dieser Pointer zeigt. Eine häufige Parameterdeklaration in Ausgabe-Funktionen, die einen String erhalten, ist&lt;br /&gt;
 void foo (const char * str, ...);&lt;br /&gt;
Dadurch ist &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; der Zeiger auf eine Zeichenkette, die innerhalt der Funktion nicht verändert wird bzw. verändert werden darf. Eine Zuweisung wie &amp;lt;tt&amp;gt;*str = 'a'&amp;lt;/tt&amp;gt; ergibt also einen Fehler. &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; selbst kann aber sehr wohl verändert werden, etwa mit &amp;lt;tt&amp;gt;str++&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Soll ausgedrückt werden, daß &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; unveränderlich ist, dann so:&lt;br /&gt;
 void foo (char * const str, ...);&lt;br /&gt;
Jetzt wäre eine Änderung des Strings in Ordnung, etwa durch &amp;lt;tt&amp;gt;str[10] = 'a'&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Um sich zu merken, worauf das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; wirkt, trennt man die Deklaration in Gedanken beim&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf: Steht das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; links vom&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, dann gehört es zum &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, steht es rechts davon, dann gehört es zum Pointer. Natürlich ist es auch denkbar, beides &amp;amp;ndash; also den Zeiger und sein Ziel &amp;amp;ndash; als konstant zu markieren.&lt;br /&gt;
&lt;br /&gt;
==Gültigkeitsbereich==&lt;br /&gt;
In C können mehrere Variablen den gleichen Namen haben, solange eindeutig ist, welche in welchen Block gültig ist. Dabei gelten folgende Regeln: &lt;br /&gt;
&lt;br /&gt;
;Lokale Variablen: sind Variablen, die innerhalb eines Blockes definiert werden. Jede Variable ist nur in dem Block gültig, in dem sie vereinbart wurde, sowie in allen darin enthaltenen Blöcken; es sei denn, in einem Unter-Block wird eine Variable gleichen Namens definiert. Dann bezieht sich in diesem Unter-Block der Bezeichner auf die im Unter-Block angelegte Variable.&lt;br /&gt;
;Globale Variablen: werden ausserhalb jedes Blockes definiert und gelten ab der Stelle, an der sie deklariert werden, siehe auch [[#Deklaration und Definition|Deklaration und Definition]]. Wird jedoch in einem Block eine Variable gleichen Namens angelegt, gilt ab hier bis zum Ende des Blocks nicht mehr die globale Variable, sondern die im Block deklarierte. Das Spiel kann man weiterspielen: wird in einem Unter-Block wieder eine namensgleiche Variable angelegt, gilt diese in dem Unterblock.&lt;br /&gt;
&lt;br /&gt;
==Speicherklassen==&lt;br /&gt;
Jede Variable in C gehört zu einer bestimmten Speicherklasse&lt;br /&gt;
;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;: Lokale Variablen sind in aller Regal sogenannte ''automatische Variablen''. Das bedeutet, sie werden automatisch angelegt, wenn ein Block bzw. eine Funktion betreten wird und danach wieder entfernt. Das Schlüsselwort &amp;quot;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;&amp;quot; wird praktisch nie hingeschrieben, denn lokale Variablen ohne die ausdrückliche Angabe einer Speicherklasse, sind automatisch automatische Variablen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;: Eine externes Symbol ist im ganzen Programm bekannt bzw. in dem Block, in der die Deklaration steht. In unterschiedlichen Blöcken stehende Deklarationen beziehen sich auf das gleiche Symbol! Obgleich das Datum global zugreifbar ist, ist der Gültigkeitsbereich auf den deklarierenden Block begrenzt bzw. auf das deklarierende Quell-Modul, sofern das Symbol ausserhalb jedes Blocks des Moduls deklariert wird. Siehe auch [[#Deklaration und Definition|Deklaration und Definition]].&lt;br /&gt;
;&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;: Die Variable ist im Block gültig bzw. im Quell-Modul (also in der C-Datei, in der die angelegt wurde), wenn sie nicht innerhalb eines Blockes angelegt wurde. Statische Variablen werden nicht in Registern oder im Frame der Funktion angelegt, sondern im selben Speicherbereich, in dem auch die globalen Variablen liegen; Konstanten evtl. auch im Flash. Eine lokale Variable, die als &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; angelegt wird, &amp;quot;überlebt&amp;quot; also das Verlassen des Blocks und hat beim neuerlichen Betreten des Blockes ihren bisherigen Wert. In unterschiedlichen Blöcken angelegte lokale statische Variablen beziehen sich auf unterschiedliche Speicherstellen, genau wie bei lokalen Variablen auch.&lt;br /&gt;
;&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;: Durch diese Speicherklasse wird eine Variable &amp;amp;ndash; falls möglich &amp;amp;ndash; als Registervariable angelegt, also in einem Maschinenregister des Computer/Controllers gehalten. Dadurch kann auf solche Variablen besonders schnell zugegriffen werden. Dieses Schlüsselwort ist bei modernen Compilern weitgehend überflüssig, da die entsprechenden Optimierungen selbständig vorgenommen werden, wenn ausreichend Register vorhanden sind. Auch globale Variablen können als Register angelegt werden, davon ist dem Anfänger aber dringend abzuraten, weil leicht schwerauffindbare Fehler und Abstürze auftreten, wenn man nicht genau weiss, welche Implikationen in einer solchen Definition stecken!&lt;br /&gt;
;&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;: (FIXME: volatile ist ein Qualifier und keine Speicherklasse) Dies ist das genaue Gegenteil von &amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt; und bewirkt, dass die Variable auf keinen Fall in einem Register zwischengespeichert werden darf, sondern immer aus dem RAM gelesen und ins RAM geschrieben werden soll. &amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt; müssen alle ''globalen'' Variablen markiert werden, die in [[ISR | Interrupt-Handlern]] verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Ausdrücke=&lt;br /&gt;
Eine Variable oder eine Konstante in C stellen einfache Ausdrücke dar.&lt;br /&gt;
Diese elementaren Ausdrücke können durch Operatoren miteinander verknüpft werden und so zu neuen, komplexeren Ausdrücken zusammen gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Einfache Beispiele für Ausdrücke sind also z.B.:&lt;br /&gt;
 1&lt;br /&gt;
 a&lt;br /&gt;
 'a'&lt;br /&gt;
 1 + a&lt;br /&gt;
 a == 1&lt;br /&gt;
&lt;br /&gt;
Auch Funktionen können einen Wert zurückliefern und in Ausdrücken weiter benutzt werden.&lt;br /&gt;
In den folgenden Abschnitten wird gezeigt, welche Operatoren in C vorhanden sind,&lt;br /&gt;
und wei man damit neue Ausdrücke aufbauen kann.&lt;br /&gt;
&lt;br /&gt;
==Lvalues==&lt;br /&gt;
&lt;br /&gt;
Ein Lvalue in C ist ein Ausdruck, dem ein anderer Ausdruck zugewiesen werden kann, dessen Wert also durch eine Zuweisung verändert werden kann.&lt;br /&gt;
das 'L' leitet sich ab von 'left' bwz. 'links' und das 'value' bedeutet Wert: Ein Lvalue ist ein Ausdruck, der auf der linken Seite einer Zuweisung stehen darf. Ein Lvalue ist also immer auch ein gültiger Ausdruck, aber die Umkehrung gilt in alles Regel nicht.&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für einen Lvalue ist eine &amp;quot;normale&amp;quot; Variable, die nicht mit &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; als Konstante markiert ist:&lt;br /&gt;
 a = 1;&lt;br /&gt;
Hingegen ist der Ausdruck &amp;lt;tt&amp;gt;a+1&amp;lt;/tt&amp;gt; kein Lvalue, denn eine Zuweisung wie&lt;br /&gt;
 a+1 = 2;&lt;br /&gt;
die mathematisch durchaus sinnvoll ist, erzeugt einen Compilerfehler, der etwa lauten könnte &amp;quot;illegal lvalue in assignment&amp;quot;:&lt;br /&gt;
&amp;quot;ungültiger Wert in Zuweisung&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Andere Beipiele für Lvalues sind die Komponenten von (nicht-konstanten) [[#Strukturen|Strukturen]] und [[#Unions|Unions]], [[#Arrays|Array]]-Elemente und die Dereferenzierungen von Pointern: Die Konstante&amp;amp;nbsp;4 wird durch den Cast in eine Adresse umgewandelt. Über die Dereferenzierung&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; wird an die Adresse&amp;amp;nbsp;4 im Speicher eine&amp;amp;nbsp;3 geschrieben. Ob das erlaubt bzw. sinnvoll ist, ist abhängig von der jeweiligen Architektur.&lt;br /&gt;
 * ((unsigned int *) 4) = 3;&lt;br /&gt;
Hier ist der gesamte &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;-Ausdruck ein Lvalue&lt;br /&gt;
&lt;br /&gt;
==Logische (boolsche) Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp;amp;&amp;amp;amp; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr oder &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; || gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; || ungleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;= b&amp;lt;/tt&amp;gt; || kleiner oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt; b&amp;lt;/tt&amp;gt; || kleiner als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt;= b&amp;lt;/tt&amp;gt; || glösser oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt; b&amp;lt;/tt&amp;gt; || grösser als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; nicht wahr und vice versa&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine interessante Eigenschaft der Operatoren &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;amp;amp;&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; ist, dass&lt;br /&gt;
sie die Auswertung abbrechen, sobald das Ergebnis feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet. Ein oft anzutreffendes Codestück sieht so aus, dabei sei &amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
  if (p &amp;amp;&amp;amp; *p == 5)&lt;br /&gt;
  {&lt;br /&gt;
     {{comment|mach was}}&lt;br /&gt;
  }&lt;br /&gt;
Zuerst wird in der Bedinung geprüft, ob Zeiger&amp;amp;nbsp;&amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; einen Wert ungleich Null hat, also ob er überhaupt einen gültigen Wert enthält. Es ist weit verbreitete Konvention in C, daß Zeiger, die keinen gültigen Wert haben, die Adresse&amp;amp;nbsp;0 enthalten. '''Nur dann, wenn ein Zeiger nicht ein Null-Pointer ist, darf überhaupt ein Zugriff über ihn erfolgen!'''&lt;br /&gt;
&lt;br /&gt;
==Vergleich von Variablen==&lt;br /&gt;
Skalare Variablen (also ganze Zahlen, Gleitkommazahlen, Zeiger) können miteinander verglichen werden. Dazu gibt es die folgenden Operatoren in C: &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; || ist nicht gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;=&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;=&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das Ergebnis der Auswertung ist eine ganze Zahl. Ist die Bedingung erfüllt, dann ist der Wert ungleich&amp;amp;nbsp;0. Ist die Bedingung nicht erfüllt, dann ist ihr Wert gleich&amp;amp;nbsp;0.&lt;br /&gt;
Meistens wird man diese Operatoren in &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Konstrukten finden wie zum Beispiel&lt;br /&gt;
 if (x &amp;gt;= 10)&lt;br /&gt;
    x = 10;&lt;br /&gt;
oder in Abbruchbedingungen von Schleifen, wie sie weiter unten erklärt werden.&lt;br /&gt;
&lt;br /&gt;
Es ist auch möglich, das Ergebnis der Auswertung in einer &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Variablen zu speichern:&lt;br /&gt;
 int i;&lt;br /&gt;
 int z1, z2;&lt;br /&gt;
 &lt;br /&gt;
 z1 = 5;&lt;br /&gt;
 z2 = 100;&lt;br /&gt;
 i = z1 &amp;lt;= z2;  {{comment|Ein Vergleich. i wird &amp;quot;wahr&amp;quot;, da z1 kleinergleich z2 ist}}&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich&amp;amp;nbsp;0 (&amp;quot;wahr&amp;quot;), wenn &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; kleiner oder gleich &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt; ist. Ist &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; jedoch größer als &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt;, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich&amp;amp;nbsp;0 (&amp;quot;unwahr&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
==Arithmetische Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a + b&amp;lt;/tt&amp;gt; || Summe (Addition)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a - b&amp;lt;/tt&amp;gt; || Differenz (Subtraktion)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a * b&amp;lt;/tt&amp;gt; || Produkt (Multiplikation)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a / b&amp;lt;/tt&amp;gt; || Quotient (Division, evtl. mit Rest)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a % b&amp;lt;/tt&amp;gt; || Rest bei Division (Modulo)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;-a&amp;lt;/tt&amp;gt; || Vorzeichenumkehr (Zweierkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Bit-Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp; b&amp;lt;/tt&amp;gt; || bitweise und (and)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || bitweise oder (or)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a ^ b&amp;lt;/tt&amp;gt; || bitweise exclusiv-oder (xor, exor)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;~a&amp;lt;/tt&amp;gt; || jedes Bit in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; invertieren (not, Einerkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Index-Operator bei Arrays==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a[b]&amp;lt;/tt&amp;gt; || das (b+1)ste Element des Feldes a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Folgendes gilt es bei der Verwendung des Indexoperators zu beachten:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; muss ein [[C-Tutorial#Felder | Feld]] oder [[C-Tutorial#Zeiger | Zeiger]] sein&lt;br /&gt;
# &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; muss ein Integer sein oder ein Datentyp, der sich in einen int umwandeln läßt (z.B. char)&lt;br /&gt;
# Es wird nicht geprüft, ob der Index &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; im Feld &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gültig ist!&lt;br /&gt;
# Der erste Index eines Feldes ist immer 0. Daher ''(b+1)stes Element'' in der Beschreibung&lt;br /&gt;
&lt;br /&gt;
==Komponenten-Auswahl bei Structs und Unions==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a.b&amp;lt;/tt&amp;gt; || Element b der [[C-Tutorial#Strukturen | Struktur]] oder des Unions a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adress-Operator und Dereferenzierung==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&amp;amp;amp;a&amp;lt;/tt&amp;gt; || Speicheradresse der Variablen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;*a&amp;lt;/tt&amp;gt; || Wert, der an der Adresse &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a-&amp;amp;gt;b&amp;lt;/tt&amp;gt; || Wert des Elements &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; der Struktur, deren Adresse in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Adressoperator &amp;amp; kann auf Variablen angewendet werden und&lt;br /&gt;
gibt die Startadresse der Variablen im Speicher zurück.&lt;br /&gt;
&lt;br /&gt;
Handelt es sich bei einer Variable um einen [[C-Tutorial#Zeiger | Zeiger]], so enthält&lt;br /&gt;
sie eine Speicheradresse. Um an den '''Wert''' zu gelangen, der&lt;br /&gt;
an dieser Adresse steht, wird der Operator * vorangestellt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
&lt;br /&gt;
 {{comment|x ist eine Integervariable und hat den Wert 5}}&lt;br /&gt;
 int x = 5;&lt;br /&gt;
     &lt;br /&gt;
 {{comment|z ist ein Zeiger auf eine Integer-Variable und enthaelt somit}}&lt;br /&gt;
 {{comment|die Speicheradresse einer Integer-Variablen}}&lt;br /&gt;
 int *z;       &lt;br /&gt;
  &lt;br /&gt;
 {{comment|Verwendung des Adress-Operators: weist an z die Adresse von x zu}}&lt;br /&gt;
 z = &amp;amp;x;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Verwendung der Dereferenzierung}}&lt;br /&gt;
 {{comment|erhoehe den Wert, der bei Adresse z steht, um eins}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|da z auf x zeigt, hat x jetzt den Wert 6}}&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff auf Struktir- und Union-Elemente eine abkürzende Schreibweise möglich:&lt;br /&gt;
&lt;br /&gt;
Statt &lt;br /&gt;
  (*strukturZeiger).element&lt;br /&gt;
kann geschrieben werden&lt;br /&gt;
  strukturZeiger-&amp;gt;element&lt;br /&gt;
Beide Schreibweisen sind absolut gleichbedeutend, die Klammern bei der ersteren sind notwendig.&lt;br /&gt;
&lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
:Bei der Dereferenzierung durch &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; findet keine Prüfung statt, ob der Zeiger auch auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu einer Änderung '''irgendeiner''' Speicherstelle!&lt;br /&gt;
&lt;br /&gt;
 int *z; {{comment|z ist ein Zeiger auf einen int}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.}}&lt;br /&gt;
 {{comment|z enthaelt irgendeine ungueltige Adresse!!}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|&amp;quot;Erhoehe einen Integer _irgendwo_ im Speicher um 1&amp;quot; -&amp;gt; CRASH !!!}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
&lt;br /&gt;
==Cast-Operator==&lt;br /&gt;
&lt;br /&gt;
Der Cast Operator dient dazu, den Datentyp eines Wertes zu ändern. Dafür wird einfach der neue Datentyp in Klammern vor den Wert geschrieben.&lt;br /&gt;
&lt;br /&gt;
Um zum Beispiel aus einem Float ein Integer zu machen:&lt;br /&gt;
 var  = (int) 5.60;&lt;br /&gt;
Dabei wird der Wert aber auch gerundet, und es findet somit ein Informationsverlust statt.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Umwandeln einer ganzen Zahl in eine Adresse:&lt;br /&gt;
 int * addr;&lt;br /&gt;
 addr = (int*) 0x1234;&lt;br /&gt;
Damit ist &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; an Adresse 0x1234.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
Der Cast-Operator selbst führt ''keine Konvertierung'' von Darstellungen durch, etwa die Umwandlung der ganzen Zahl 123 ein den String &amp;lt;tt&amp;gt;&amp;quot;123&amp;quot;&amp;lt;/tt&amp;gt;, der diese Zahl darstellt! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
  int main(int argc, char ** argv)&lt;br /&gt;
  {&lt;br /&gt;
        char text[] = &amp;quot;5.6&amp;quot;;&lt;br /&gt;
        int zahl = (int) text;&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, zahl);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Anfangsadresse des Strings &amp;lt;tt&amp;gt;&amp;quot;5.6&amp;quot;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Komma-Operator==&lt;br /&gt;
Mit einem &amp;lt;tt&amp;gt;,&amp;lt;/tt&amp;gt; können mehrere Ausdrücke nacheinander ausgewertet werden.&lt;br /&gt;
Die Auswertung erfolgt von links nach rechts.&lt;br /&gt;
&lt;br /&gt;
Solche Konstrukte sieht man manchmal in Abfragen wie&lt;br /&gt;
 FILE  *file;&lt;br /&gt;
 if (file = fopen (&amp;quot;foo.exe&amp;quot;, &amp;quot;r&amp;quot;), file != NULL)&lt;br /&gt;
was erst an &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; einen Wert zuweist und den &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Block nur betritt,&lt;br /&gt;
wenn &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; nicht der Nullpointer ist.&lt;br /&gt;
&lt;br /&gt;
Bequem kann das auch in einer [[#for-Schleife|for-Schleife]] sein, wenn man zwei (oder mehr) Laufvariablen hat oder so:&lt;br /&gt;
 for (i=0, j=0; i &amp;lt; 10; i++, j += 2)&lt;br /&gt;
    &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Zuweisung===&lt;br /&gt;
=== ++ und -- ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; stellen einfachere Schreibweisen dar zum Addieren bzw. Subtrahieren von&amp;amp;nbsp;1.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; (Inkrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo++; &lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo + 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; 3}}&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; (Dekrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo--;&lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo - 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; -1}}&lt;br /&gt;
&lt;br /&gt;
Die beiden Operatoren können sowohl in der Präfix-Schreibweise (vor der Variablen) als auch als Postfix-Schreibweise (hinter der Variablen) notiert werden. &lt;br /&gt;
Der Unterschied liegt darin, dass beim Präfix der Wert zuerst neu berechnet wird und die Variable dann verwendet wird. Beim Postfix wird die Variable zuerst verwendet und erst nach Auswertung des Ausdrucks, in dem sie enthalten ist, neu berechnet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 int ausgabe1, ausgabe2, var1 = 10, var2 = 10;&lt;br /&gt;
 ausgabe1 = 3 * ++var1; {{comment|ausgabe1 &amp;amp;#61; 33; var1 &amp;amp;#61; 11;}}&lt;br /&gt;
 ausgabe2 = 3 * var2++; {{comment|ausgabe2 &amp;amp;#61; 30; var2 &amp;amp;#61; 11;}}&lt;br /&gt;
&lt;br /&gt;
Für Zeiger arbeiten diese Operatoren etwas anders, siehe dazu [[#Zeiger-Arithmetik|Zeiger-Arithmetik]].&lt;br /&gt;
&lt;br /&gt;
===Bedingter Ausdruck===&lt;br /&gt;
 ({{Bedingung}}) ? {{Ausdruck|1}} : {{Ausdruck|2}}&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; erfüllt ist, dann wertet dieser Ausdruck aus zu &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt;. Ist er nicht erfüllt, dann wertet er aus zu &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 x = (x &amp;gt;= 3) ? 0 : x+1;&lt;br /&gt;
Startet man &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; mit dem Wert 0, dann nimmt es bei mehrfacher Anwendung dieser Zeile (z.B. in einer Schleife) nacheinander die folgende Werte an:&lt;br /&gt;
:&amp;lt;tt&amp;gt;1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, ...&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&lt;br /&gt;
Wie auch in der Mathematik gibt es auch in C genaue Regeln über die Abarbeitungsreihenfolge (precedence)&lt;br /&gt;
der Operatoren. Dass sich alle C-Compiler genau an diesen ANSI-Vorschlag halten, ist leider nicht sicher.&lt;br /&gt;
Sicher jedoch ist, dass nicht jeder Programmierer diese Regel jederzeit im Kopf hat. &lt;br /&gt;
Daher ist es sinnvoll, Ausdrücke durch runde Klammern eindeutig zu kennzeichnen. &lt;br /&gt;
Nebenbei stören sich Compiler nicht an überflüssigen Klammerpaaren.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Priorität ||Operator||Assoziativität&lt;br /&gt;
|-&lt;br /&gt;
  &lt;br /&gt;
|&amp;lt;tt&amp;gt;15&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ( ) [ ] -&amp;gt; . &amp;lt;/tt&amp;gt;                      ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;14&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;! ~ ++ -- + - (TYP) * &amp;amp; sizeof &amp;lt;/tt&amp;gt;    ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;13&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; * / % (Rechenoperationen) &amp;lt;/tt&amp;gt;         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;12&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; + - (binär) &amp;lt;/tt&amp;gt;                       ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;11&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;&amp;lt; &amp;gt;&amp;gt; &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;10&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt; &amp;lt;= &amp;gt; &amp;gt;= &amp;lt;/tt&amp;gt;                         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 9&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; == != &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 8&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp; (bit-AND-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 7&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ^ (bit-XOR-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 6&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; (bit-OR-Operator)&amp;lt;/tt&amp;gt;   ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 5&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp;&amp;amp; &amp;lt;/tt&amp;gt;                                ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 4&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; &amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 3&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;? : &amp;lt;/tt&amp;gt;                               ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 2&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; = += -= /= *= %= &amp;gt;&amp;gt;= &amp;lt;&amp;lt;= &amp;amp;= &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;= ^= &amp;lt;/tt&amp;gt; ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 1&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; , (Sequenz-Operator) &amp;lt;/tt&amp;gt;              ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Reihenfolge der Auswertung von Funktionsargumenten ist in der ANSI-Spezifikation nicht angegeben und daher compilerabhängig. Von Konstrukten wie&lt;br /&gt;
 {&lt;br /&gt;
    int i=0;&lt;br /&gt;
    func (i++, i++);&lt;br /&gt;
 }&lt;br /&gt;
ist also dringend abzuraten!&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
Eine Kontrollanweisung ist eine Anweisung, die Einfluss auf den Programmfluss hat. Normalerweise werden Anweisungen so ausgeführt, wie sie in der Quelldatei stehen: Von links nach rechts (falls mehrere Anweisungen in einer Zeile stehen sollten, wovon i.A. abzuraten ist) und von oben nach unten. Mit einer Kontrollanweisung kann dieser lineare Programmfluss durchbrochen werden: Die Codeausführung kann kann abhängig von einer Bedingung gemacht werden (&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;), kann wiederholt werden (Schleife) oder an einer anderen Stelle der Funktion fortgesetzt werden (&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==if-Anweisung==&lt;br /&gt;
Mit Hilfe des if-Befehls kann man Codeteile abhängig davon einer Bedingung ausführen lassen:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
oder mit else-Teil&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 if (x &amp;gt; 100)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;gt; 100 ist: Fehlerausgabe}}&lt;br /&gt;
    printf (&amp;quot;x = %d ist zu gross fuer die Berechnung!\n&amp;quot;, x);&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;lt;&amp;amp;#61; 100 ist: Berechne Summe der Zahlen 1...x}}&lt;br /&gt;
    {{comment|Die lokale Variable x2 lebt nur innerhalb dieses alse-Blocks}}&lt;br /&gt;
    int x2 = x;&lt;br /&gt;
 &lt;br /&gt;
    for (x = 0; x2 &amp;gt; 0; x2--)&lt;br /&gt;
       x += x2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Wenn die Bedingung wahr ist (&amp;lt;tt&amp;gt;x &amp;gt; 100&amp;lt;/tt&amp;gt;), dann wird eine Meldung ausgegeben; danach ist die if-Anweisung beendet. Der else-Block wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung nicht erfüllt (&amp;lt;tt&amp;gt;x &amp;amp;le; 100&amp;lt;/tt&amp;gt;), dann wird gleich zum else-Teil gesprungen, und nach dessen Ausführung der if-Befehl beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Ein häufiger Fehler ist es, statt &amp;lt;tt&amp;gt;if (a &amp;amp;#61;&amp;amp;#61; 23)&amp;lt;/tt&amp;gt; etwas wie &amp;lt;tt&amp;gt;if (a &amp;amp;#61; 23)&amp;lt;/tt&amp;gt; zu schreiben. &lt;br /&gt;
Dann wird allerdings nicht geprüft, ob die Variable&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gleich 23 ist, sondern der Variablen&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wird der Wert 23 zugewiesen. Der Ausdruck &amp;lt;tt&amp;gt;a &amp;amp;#61; 23&amp;lt;/tt&amp;gt; hat den Wert&amp;amp;nbsp;23 und ist damit immer &amp;quot;wahr&amp;quot;! Daher ist diese if-Bedingung immer erfüllt!&lt;br /&gt;
&lt;br /&gt;
Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken sondern bestenfalls eine Warnung. Damit ist dieser Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise &amp;lt;tt&amp;gt;if (23 &amp;amp;#61;&amp;amp;#61; a)&amp;lt;/tt&amp;gt;. Wenn man dort anstatt des Vergleichsoperators '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;amp;#61;&amp;lt;/tt&amp;gt;' den Zuweisungsoperator '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;lt;/tt&amp;gt;' verwendet, spuckt der Compiler sehr wohl einen Fehler aus! Ist die Zuweisung jedoch erwünscht und eine Compiler-Warnung lästig, dann wählt man eine Schreibweise wie &amp;lt;tt&amp;gt;if ((a &amp;amp;#61; b))&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;if (a &amp;amp;#61; b, a)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist zu schreiben &amp;lt;tt&amp;gt;if (Bedingung);&amp;lt;/tt&amp;gt; Richtig muss es heissen &amp;quot;&amp;lt;tt&amp;gt;if(Bedingung)&amp;lt;/tt&amp;gt;&amp;quot; Das Semikolon im ersten Fall ist eine leere Anweisung, die im if-Falle ausgeführt wird &amp;amp;ndash; sie bleibt also ohne Resultet. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt; ein auf das Semikolon folgende Anweisung die eigentlich zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören soll wird immer ausgeführt, die sie nicht mehr zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; dazu gehört.&lt;br /&gt;
}}&lt;br /&gt;
Bei verschachtelten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Konstrukten gehört ein &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zu letzten &amp;quot;freien&amp;quot; &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;. Soll in einer &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Folge das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zum ersten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören, dann ist das so zu hinzuschreiben:&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Ohne die geschweiften Klammern um das zweite &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehörte das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; dort hinzu.&lt;br /&gt;
&lt;br /&gt;
==switch-Anweisung==&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
&lt;br /&gt;
 switch ({{Ausdruck|}}) &lt;br /&gt;
 {&lt;br /&gt;
     case konstante1:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
    &lt;br /&gt;
     case konstante2:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 &lt;br /&gt;
     {{comment|weitere case-Marken}}&lt;br /&gt;
 &lt;br /&gt;
     default:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 } {{comment|Ende von switch}} &lt;br /&gt;
&lt;br /&gt;
Der Ausdruck muss ein skalarer Typ sein, er wird in die nächste ganze Zahl gewandelt und mit den Werten hinter den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Marken verglichen. Bei einer Übereinstimmung werden alle Befehle ab dem zutreffenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; ausgeführt. Stimmt der Ausdruck mit keinem der Werte überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt falls vorhanden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der nachfolgenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;- und des &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitts werden ausgeführt, wenn die Anweisungen des &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitts nicht mit dem Befehl &amp;lt;tt&amp;gt;break;&amp;lt;/tt&amp;gt; beendet werden!&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es dürfen beliebig viele &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitte angegeben werden, pro Vergleichswert jedoch nur einer.&lt;br /&gt;
Der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ist optional. Die Reihenfolge, in der &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt; angegeben werden, ist unerheblich.&lt;br /&gt;
&lt;br /&gt;
==Schleifen==&lt;br /&gt;
Um Anweisungen mehrmals hintereinander auszuführen, benötigt man Schleifen. Diese führen Anweisungen aus, bis oder solange Bedingungen erfüllt sind.&amp;lt;br&amp;gt; &lt;br /&gt;
Wichtig ist also, ob die Bedingung '''vor''' oder '''nach''' den Schleifen-Anweisungen geprüft wird. &lt;br /&gt;
&lt;br /&gt;
===while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 while ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Die while-Schleife wird solange durchlaufen, wie die Bedingung erfüllt ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Die Anweisung kann natürlich auch ein Block sein, der aus mehreren Deklarationen und Anweisungen besteht. &lt;br /&gt;
&lt;br /&gt;
 int zahl1 = 0;&lt;br /&gt;
 int zahl2 = 1;&lt;br /&gt;
 &lt;br /&gt;
 while (zahl1 &amp;lt; 3)&lt;br /&gt;
 {&lt;br /&gt;
    zahl1 = zahl1 + 1;&lt;br /&gt;
    zahl2 = zahl2 * 2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife drei mal durchlaufen. Zu Beginn des vierten Durchlaufs ist die Bedingung nicht mehr erfüllt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
&lt;br /&gt;
===do-while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
Die do-while-Schleife wird auf jeden Fall einmal durchlaufen und dann solange wiederholt, wie die Bedingung erfüllt ist.&lt;br /&gt;
 int i = 2;&lt;br /&gt;
 &lt;br /&gt;
 do &lt;br /&gt;
 {&lt;br /&gt;
     i = i*i;   {{comment|i quadrieren}}&lt;br /&gt;
     printf (&amp;quot;i = %d\n&amp;quot;, i);&lt;br /&gt;
 }&lt;br /&gt;
 while (i &amp;lt; 20);&lt;br /&gt;
&lt;br /&gt;
Die Schleife wird durchlaufen und wiederholt, solange &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; kleiner als 20 ist. Es werden also nacheinander die Werte 2, 4 und 16 ausgegeben. Nach der Schleife hat&amp;amp;nbsp;&amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; den Wert 256.&lt;br /&gt;
&lt;br /&gt;
===for-Schleife===&lt;br /&gt;
'''Syntax:''' &lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Bei den Ausdrücken wird es sich um einen Ausdrücke mit Nebeneffekt handeln wie etwa &amp;lt;tt&amp;gt;i=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;i=i+2&amp;lt;/tt&amp;gt;. Es werden folgende Aktionen ausgeführt:&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# falls die Bedingung wahr ist, dann führe &amp;lt;tt&amp;gt;Anweisung&amp;lt;/tt&amp;gt; aus.&lt;br /&gt;
# falls die Bedingung unwahr ist, dann sprinte zu 7 (Ende).&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# gehe zu 2&lt;br /&gt;
# nächste Anweisung nach der for-Schleife&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int lauf, summe;&lt;br /&gt;
 &lt;br /&gt;
 for (lauf=1, summe=0; lauf &amp;lt;= 10; lauf += 2) &lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel ist &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; ein [[#Komma-Operator|Komma-Ausdruck]], der zwei Anweisungen kombiniert und daher sogar zwei Nebeneffente hat: er setzt &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;1 und &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;0.&lt;br /&gt;
&lt;br /&gt;
Das Äquivalent als while-Schleife:&lt;br /&gt;
&lt;br /&gt;
 int lauf  = 1;                 {{comment|Anfangswerte}}&lt;br /&gt;
 int summe = 0;&lt;br /&gt;
 &lt;br /&gt;
 while (lauf &amp;lt;= 10)             {{comment|Bedingung}}&lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
    lauf  += 2;                 {{comment|Inkrement}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; in jedem Schleifendurchlauf um die Laufvariable &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; erhöht. Da &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nacheinander die ungeraden Werte von&amp;amp;nbsp;1 bis&amp;amp;nbsp;10 annimmt, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von&amp;amp;nbsp;1 bis kleinergleich 10 gespeichert, also der Wert&amp;amp;nbsp;25. &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; hat nach der Schleife den Wert&amp;amp;nbsp;11.&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf = 1&amp;lt;/tt&amp;gt; bedeutet, dass der Variablen &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; vor dem ersten Schleifendurchlauf der Wert&amp;amp;nbsp;1 zugewiesen wird. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf &amp;lt;= 10&amp;lt;/tt&amp;gt; ist die Schleifenbedingung; ist sie nicht erfüllt, wird die Schleife beendet. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf += 2&amp;lt;/tt&amp;gt; bedeutet, dass &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nach jedem Durchlauf um&amp;amp;nbsp;2 erhöht wird.&lt;br /&gt;
&lt;br /&gt;
===continue-Anweisung===&lt;br /&gt;
Innerhalb einer Schleife darf die &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die nachfolgenden Anweisungen übersprungen werden und mit dem nächsten Schleifendurchlauf fortgesetzt wird &amp;amp;ndash; vorausgesetzt die Schleifenbedingung ist noch erfüllt. Ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; etc. stehen, wenn dieses innerhalb einer Schleife steht.&lt;br /&gt;
&lt;br /&gt;
==break-Anweisung==&lt;br /&gt;
Innerhalb einer Schleife oder eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; darf die &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die Schleifen-/Switch-Anweisung sofort verlassen wird und das Programm dahinter weiter macht. Bei mehrfach geschachtelten Schleifen wird nur die innere verlassen. Ein &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; stehen, wenn dieses innerhalb einer Schleife/Switch-Anweisung steht.&lt;br /&gt;
&lt;br /&gt;
==goto-Anweisung==&lt;br /&gt;
&lt;br /&gt;
Innerhalb ein und derselben Funktion kann mit &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; an eine andere Stelle gesprungen werden. Dazu gibt man hinter dem &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einen Bezeichner an, der dadurch als Label fungiert:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 goto {{Bezeichner}};&lt;br /&gt;
Die Bezeichner selbst steht irgendwo in der Funktion und wird dadurch zur Sprungmarke (Label), daß er von einem Doppelpunkt (und mindestens einer C-Anweisung, die auch leer sein darf) gefolgt wird.&lt;br /&gt;
&lt;br /&gt;
Das Beispiel durchsucht das 2-dimensionale &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array &amp;lt;tt&amp;gt;feld&amp;lt;/tt&amp;gt; mit den &amp;lt;tt&amp;gt;SIZE_X &amp;amp;times; SIZE_Y&amp;lt;/tt&amp;gt; Werten nach dem Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;. Wird er gefunden, dann wird die 2-fach geschachtelte Suchschleife verlassen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int x, y;&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y; y++)&lt;br /&gt;
       if (feld[x][y] == 0)&lt;br /&gt;
          goto done;&lt;br /&gt;
 {{Label|done:}};&lt;br /&gt;
&lt;br /&gt;
Der folgende Code hat die gleiche Funktion, arbeitet jedoch ohne &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int x, y;&lt;br /&gt;
 int found = 0; {{comment|FALSE}}&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X &amp;amp;&amp;amp; !found; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y &amp;amp;&amp;amp; !found; y++)&lt;br /&gt;
       found = (0 == feld[x][y]);&lt;br /&gt;
Der Nachteil der &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-losen Variante ist, daß man eine Variable, die merkt, ob das Suchziel gefunden wurde, mitschleppen und in ''jedem'' Schleifendurchlauf abtesten muss. Dies bedeutet einen höheren Programmier- und Laufzeitaufwand und ist nicht so klar formuliert wie das &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-Beispiel.&lt;br /&gt;
&lt;br /&gt;
Gleichwohl sei angemerkt, daß die Verwendung von &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einem gewissen Dogmatismus unterliegt, der sich wie folgt subsummieren liesse:&lt;br /&gt;
:''goto ist böse und sollte keinesfalls verwendet werden! Wer es dennoch tut, offenbart dadurch seinen schlechten Geschmach sowie mangelhafte C-Kenntnis.'' &amp;lt;div align=&amp;quot;right&amp;quot;&amp;gt;http://www.roboternetz.de/phpBB2/images/smiles/icon_wink.gif&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Funktionen=&lt;br /&gt;
Stellen Dir vor, Du hast eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben &amp;amp;ndash; was Dich Zeit beim Erstellen des Programms und Speicherplatz im ausführbaren Programm kostet &amp;amp;ndash; kannst Du den Code-Abschnitt in eine Funktion schreiben und diese von jeder Stelle des Programms aus verwenden. Die Hauptgründe, um Funktionen zu verwenden, sind:&lt;br /&gt;
;Wiederverwendung von Code: Mehrfach verwendete Codestücke müssen nicht mehrfach implementiert werden. Oft unterscheiden sich die Codesequenzen nur in Kleinigkeiten, die man der Funktion über Parameter mitteilen kann.&lt;br /&gt;
;Übersichtlichkeit: Ein gut gegliedertes C-Programm implementiert klar umrissene Aufgaben in einer Funktion, auch wenn diese Funktion nur einmal im Code aufgerufen wird! Dadurch bleibt der Code um die Aufrufstelle besser verständlich, und man kann auf verschiedenen &amp;quot;Ebenen&amp;quot; denken. Eine Funktion wie &amp;quot;Datei öffnen&amp;quot; kann recht komplex sein. Auf höherer Ebene interessieren die Innereien nicht mehr, man möchte sich um andere Dinge kümmern und will den Code an der Stelle garnicht sehen...&lt;br /&gt;
;Rekursive Funktionen: Eine Funktion kann sich auch selbst aufrufen. In dem Falle nennt man die Funktion ''rekursiv''. Zwar lässt sich das, was eine rekursive Funktion tut, auch mit anderen Mitteln formulieren, die keine rekursiven Funktionen brauchen, aber oft ist der rekursive Weg knackiger und klarer formulierbar als eine nicht-rekursiven Ansatz, auch wenn es etwas mehr Resourcen verbraucht.&lt;br /&gt;
;Modulare Programmierung: Funktionen können anhand ihres Aufgabenbereichs auf verschiedene C-Quellen &amp;amp;ndash; sogenannte ''Module'' &amp;amp;ndash; verteilt werden. Funktionen, die etwas mit dem USB-Bus anstellen, werden in einem anderen Modul sein als mathematische Funktionen. Dies erhöht die Übersichtlichkeit und vereinfacht die Entwicklung im Team.&lt;br /&gt;
;Bibliotheken: Standard-Funktionen wie das hier oft auftauchende &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; sind in Bibliotheken gespeichert. Wenn das eigene Programm übersetzt wird, dann müssen nicht mehr alle Standard-Funktionen übersetzt werden, sondern werden nur noch aus der Bibliothek gelesen und ihr Code zum Programm dazugelinkt. Die Bibliotheks-Funktionen wurden schon zu einem früheren Zeitpunkt compiliert und liegen in dieser compilerten Form in der Bibliothek. Das spart mächtig Entwicklungszeit. Man kann auch selbst solche Bibliotheken erstellen und in diversen Projekten wiederverwenden.&lt;br /&gt;
;Generische Programmierung: In C ist es möglich, einer Funktion eine andere Funktion zu übergeben. (Damit ist nicht gemeint, ihr deren ''Rückgabewert'' zu übergeben (was auch ginge), sondern ''die Funktion selbst'' wird als Parameter übergeben und kann aufgerufen werden.) Ein typisches Beispiel dafür sind Sortieralgorithmen. Einem Sortieralgorithmus kann es egal sein, ''was'' er sortiert. Er muss lediglich wissen, ''wie'' er das Zeug zu sortieren hat: aufsteigend, absteigend, als Zahl, in lexikographischer Ordnung, nach der Quersumme, Körper nach Oberfläche, Durchmesser, Gewicht oder Volumen... Diese Vergleichsfunktion, die für zwei Objekte entscheidet, welches davon &amp;quot;kleiner&amp;quot; ist, kann man dem Sortierer übergeben. Will er zwei Werte vergleichen, dann muss er nur die Vergleichsfunktion aufrufen, ohne zu wissen, was diese tut. Damit kann der Sortieralgorithmus unanhängig von den Objekten gehalten werden, mit denen er hantieren soll.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Definition==&lt;br /&gt;
&lt;br /&gt;
In der ''Definition'' der Funktion wird gesagt, welche Werte sie liefern kann, wie sie heisst (Bezeichner) und wieviele und welche Parameter sie hat. Danach folgt ihre Implementierung:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}} ({{Parameterliste}})&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 &lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
Für Funktionen, die keinen Wert zurückliefern, gibt es den speziellen Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der besagt, daß die Funktion nichts zurückgibt. Die einfachste denkbare Funktion ist eine solch void-Funktion. Sie bekommt keine Parameter, gibt nicht zurück und ihr Body ist leer:&lt;br /&gt;
 void dummy()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==return-Anweisung==&lt;br /&gt;
An jeder Stelle des Programmflusses einer Funktion kann diese mit &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; beendet werden.&lt;br /&gt;
&lt;br /&gt;
'''bei void-Funktionen:'''&lt;br /&gt;
 return;&lt;br /&gt;
'''Funktionen mit Rückgabe-Wert:'''&lt;br /&gt;
 return {{Ausdruck|}};&lt;br /&gt;
Die zweite Variante gibt an, welcher Wert zurückgegeben wird.&lt;br /&gt;
 int main (int argc, char * argv[])&lt;br /&gt;
 {&lt;br /&gt;
    if (argc &amp;lt; 2)&lt;br /&gt;
       return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
Falls die letzte Anweisung einer void-Funktion ein &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; ist, kann es auch weggelassen werden wie oben bei der Funktion &amp;lt;tt&amp;gt;dummy&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Aufruf==&lt;br /&gt;
Um die Funktion aufzurufen gibt man ihren Namen an, gefolgt von den durch Komma getrennten Argumenten in runden Klammern wie im Beispiel unten das&lt;br /&gt;
 quadrat (5) &lt;br /&gt;
Da &amp;lt;tt&amp;gt;quadrat&amp;lt;/tt&amp;gt; einen Wert liefert, kann man damit weiter rechnen wie mit einem normalen Ausdruck:&lt;br /&gt;
 if (quadrat (a) + quadrat (b) == quadrat (c))&lt;br /&gt;
    c = quadrat (quadrat (a)); {{comment|c &amp;amp;#61; a hoch 4}}&lt;br /&gt;
&lt;br /&gt;
;Ein Hinweis am Rande: Der Name einer Funktion ohne die beiden runden Klammern ist der Pointer/Zeiger auf ihren Anfang. Damit kann ein Funktionsname überall dort verwendet werden, wo Pointer/Zeiger zulässig sind. Insbesondere kann er als Argument einer weiteren Funktion dienen. Siehe auch [[#Zeiger auf Funktionen|Zeiger auf Funktionen]].&lt;br /&gt;
&lt;br /&gt;
==Rekursive Funktionen==&lt;br /&gt;
Eine Funktion die sich selbst &amp;amp;ndash; möglicheweise auch über andere Zwischenfunktionen &amp;amp;ndash; wieder selbst aufruft, wird als ''rekursive Funktion'' bezeichnet. In der Definition ist nichts besonderes zu beachten. Ist die Verschachtelungstiefe im laufenden Programm zu tief, dann gibt das natürlich Probleme, aber das gilt bei tief verschachtelten 'normalen' Funktionen abenso...&lt;br /&gt;
&lt;br /&gt;
Das Beispiel berechnet den Größten Gemeinsamen Teiler zweier Zahlen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int ggT (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
     if (0 == a)&lt;br /&gt;
        return b;&lt;br /&gt;
 &lt;br /&gt;
    return ggT (b % a, a);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Ein komplettes kleines Programm:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int quadrat (int param1)&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  zahl = param1 * param1;&lt;br /&gt;
  return zahl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl, ergebnis;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Bitte Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = quadrat (zahl);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, zahl, ergebnis);&lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, 5, quadrat (5));&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur ausserhalb von Blöcken. Geschachtelte Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen beim Aufruf die Klammern angeben werden:&lt;br /&gt;
 dummy();&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Prototypen==&lt;br /&gt;
Wie oben erwähnt, kann ein Unterprogramm an jeder beliebigen Stelle im Programm stehen. Damit ist jedoch eine Bedingung verknüpft: Das Unterprogramm muß in der Datei oberhalb des ersten Aufrufes definiert worden sein. Wenn Sie ein Unterprogramm in Zeile 10 zum ersten mal aufrufen, müssen Sie die Deklaration davor erledigt haben. Verstanden?&lt;br /&gt;
Um dies zu erreichen, gibt es zwei Möglichkeiten: &lt;br /&gt;
&lt;br /&gt;
Entweder Sie schreiben alle Unterprogramme vor &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; in die Datei. Dies muß jedoch wiederum so geschehen, dass Funktionen zum Zeitpunkt ihres Aufrufes bereits bekannt sind! &lt;br /&gt;
Wo dies nicht möglich ist (z.B. sich gegenseitig aufrufende Unterprogramme), oder wenn Sie das stört, müssen Sie Prototypen verwenden. &lt;br /&gt;
Wie definiert man nun Prototypen? Sie kopieren einfach die erste Zeile des Unterprogrammes (z.B. &amp;quot;&amp;lt;tt&amp;gt;void ausgeben (int zahl)&amp;lt;/tt&amp;gt;&amp;quot;), fügen einen Strichpunkt&amp;amp;nbsp;&amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;an und fügen es an einer geeigneten Stelle ein (so, dass alle Aufrufe später in der Datei kommen). &lt;br /&gt;
Solche Definitionen stehen gewöhnlich am Anfang der Quelldatei oder in einer Header-Datei, die eingebunden wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl);  /* Der Prototyp */&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
   ausgeben (12);&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl)   /* Die eigentliche Prozedur */&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Ausgabe: %d\n&amp;quot;, zahl);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Parameterübergabe==&lt;br /&gt;
&lt;br /&gt;
Alle Werte, die an Prozeduren und Funktionen übergeben werden, werden grundsätzlich '''kopiert'''.&lt;br /&gt;
Das hat folgende Auswirkungen:&lt;br /&gt;
&lt;br /&gt;
# Änderungen an einem Parameter in einer Funktion erscheinen ''nicht'' beim Aufrufer!&lt;br /&gt;
# Möchte man, dass eine Funktion einen Wert trotzdem dauerhaft ändern soll, so muss die Adresse des Wertes via [[#Zeiger|Zeiger]] übergeben werden.&lt;br /&gt;
# Werden [[#Strukturen|Strukturen]] übergeben, so wird von ihnen eine Kopie erstellt, was bei großen Strukturen viel Zeit und Arbeitsspeicher kostet. Deshalb wird häufig nur die Adresse von Strukturen übergeben, da die Adresse viel schneller und platzsparender als die Struktur selbst kopiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele:'''&lt;br /&gt;
 void erhoehe (int x)&lt;br /&gt;
 {&lt;br /&gt;
    x = x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe(a);&lt;br /&gt;
    {{comment|a ist immer noch 0}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Beim Aufruf von &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; wird eine Kopie des Wertes von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; (im Beispiel also 0) erstellt und der Prozedur als Parameter &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; übergeben. Weil dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat dies keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|erhoehe den Wert an der Adresse x um eins}}&lt;br /&gt;
    *x = *x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe (&amp;amp;a);&lt;br /&gt;
    {{comment|a ist jetzt 1}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Jetzt wird im Hauptprogramm mittels [[#Adress-Operator und Dereferenzierung|Adress-Operator]] &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; die Speicheradresse von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; bestimmt. Dann wird eine ''Kopie der Adresse'' an das Unterprogramm &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; übergeben. Jetzt kennt das Unterprogramm die&lt;br /&gt;
Adresse des Originals &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und kann direkt mit dem Inhalts-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&lt;br /&gt;
'''Besonderheit bei Feldern'''&lt;br /&gt;
&lt;br /&gt;
Bei der Übergabe von [[#Felder|Feldern]] gibt es eine Besonderheit. Schreibt man nämlich den Namen eines Feldes, so ist das nichts anderes als die '''Speicheradresse des ersten Elements'''.&lt;br /&gt;
Bei der Übergabe eines Feldes wird also eine Kopie der Startadresse übergeben. Somit kann das Unterprogramm auf den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 void erhoehe (int x[])&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
   int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
   erhoehe (a);&lt;br /&gt;
   {{comment|a hat jetzt folgenden Inhalte: 11, 23, 35}}&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Dass die Übergabe einer Adresse erfolgt, sieht man an folgendem Beispiel, das von der Funktionsweise '''absolut identisch''' mit dem vorhergehenden ist:&lt;br /&gt;
&lt;br /&gt;
 {{comment|Bei Parametern gibt es keinen Unterschied zwischen Zeiger und Feld}}&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
    int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
    erhoehe (a);&lt;br /&gt;
 &lt;br /&gt;
    {{comment|a hat jetzt folgenden Inhalt: 11, 23, 35}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
Die Länge des Feldes wird nicht automatisch übergeben. Dafür ist ggf. ein zusätzlicher Parameter notwendig.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Inlining==&lt;br /&gt;
&lt;br /&gt;
In C gibt es die Möglichkeit, eine Funktion als ''inline''-Funktion zu definieren.&lt;br /&gt;
Für eine inline-Funktion wird üblicher Weise kein Code erzeugt, der beim Aufruf der Funktion angesprungen wird, sondern an der Stelle des Aufrufs wird eine Kopie der inline-Funktion eingefügt.&lt;br /&gt;
&lt;br /&gt;
Vom Effekt her ist eine inline-Funktion also ähnlich wie ein Makro. Allerdings wird das Einfügen des Codes nicht vom Präprozessor übernommen, sondern vom eigentlichen C-Compiler. Damit der Compiler in der Lage ist, eine Funktion zu inlinen, muss ihm der Code zur Verfügung stehen, da er ansonsten natürlich keinen Code einfügen kann.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort ist ''inline'':&lt;br /&gt;
 {{ccomment|Deklariere ''increment'' als inline-Funktion}}&lt;br /&gt;
 static inline int increment (int);&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Implementierung von ''increment''}}&lt;br /&gt;
 int increment (int i)&lt;br /&gt;
 {&lt;br /&gt;
    return i+1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Aufruf von ''increment'' wie eine normale Funktion}}&lt;br /&gt;
 int foo (int n)&lt;br /&gt;
 {&lt;br /&gt;
    if (n &amp;lt; MAX_INT)&lt;br /&gt;
       n = increment (n);&lt;br /&gt;
 &lt;br /&gt;
    return n;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Inline-Funktionen werden verwendet, wenn der Funktionscode recht klein ist und ein Funktionsaufruf schon so aufwändig ist wie das, was die Funktion zu erledigen hat. Im Beispiel wird der gleiche Code erzeugt, wie wenn &amp;lt;tt&amp;gt;n = n + 1&amp;lt;/tt&amp;gt; im Aufrufer stünde, was deutlich schneller ist als ein Funktionsaufruf mit Register-Sicherung, Parameterübergabe, Wertrückgabe, etc.&lt;br /&gt;
&lt;br /&gt;
==Variable Argumentanzahl==&lt;br /&gt;
&lt;br /&gt;
'''Baustelle'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdarg.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
static void uput_va (const char * fmt, va_list args /*, uint8_t pstr_p*/)&lt;br /&gt;
{&lt;br /&gt;
	while (1)&lt;br /&gt;
	{&lt;br /&gt;
		char c = (pstr_p) &lt;br /&gt;
			? pgm_read_byte (fmt++)&lt;br /&gt;
			: *fmt++;&lt;br /&gt;
		&lt;br /&gt;
		if ('\0' == c)&lt;br /&gt;
			return;&lt;br /&gt;
		&lt;br /&gt;
		if ('%' == c)&lt;br /&gt;
		{&lt;br /&gt;
			c = (pstr_p) &lt;br /&gt;
				? pgm_read_byte (fmt++)&lt;br /&gt;
				: *fmt++;&lt;br /&gt;
				&lt;br /&gt;
			if ('%' == c)	putc (c);&lt;br /&gt;
			if ('c' == c)	putc (va_arg (args, int));&lt;br /&gt;
			&lt;br /&gt;
			&lt;br /&gt;
			if ('s' == c)	{ fn = uputs   ;       ; goto _dispatch; }&lt;br /&gt;
			continue;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		if ('\n' == c)	&lt;br /&gt;
			putc ('\r');&lt;br /&gt;
		&lt;br /&gt;
		putc (c);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 void uput_PSTR (const char * fmt, ...)&lt;br /&gt;
 {&lt;br /&gt;
     va_list vlist;&lt;br /&gt;
     va_start (vlist, fmt);&lt;br /&gt;
     uput_va (fmt, vlist);&lt;br /&gt;
     va_end (vlist);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
== Funktionen indirekt aufrufen ==&lt;br /&gt;
Siehe [[#Zeiger auf Funktionen|Zeiger auf Funktionen]]&lt;br /&gt;
&lt;br /&gt;
=Zeiger II=&lt;br /&gt;
&lt;br /&gt;
Zeiger haben wir bereits weiter oben kennen gelernt. Zeiger sind ein zentrales Konzept in C und sollen hier etwas eingehender behandelt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger-Arithmetik==&lt;br /&gt;
In C kann man den Wert eines Zeigers verändern. Betrachten wir dazu die Funktion &amp;lt;tt&amp;gt;suche_0&amp;lt;/tt&amp;gt;, die einen Zeiger auf einen &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; erhält. Die Funktion soll ab der gegebenen Adresse nach dem ersten long-Wert suchen, der 0 ist, und dessen Adresse zurückgeben:&lt;br /&gt;
 long * suche_0 (long * addr)&lt;br /&gt;
 {&lt;br /&gt;
    while (*addr != 0)&lt;br /&gt;
       addr = addr + 1;&lt;br /&gt;
 &lt;br /&gt;
    return addr;&lt;br /&gt;
 }&lt;br /&gt;
In der Bedingung der while-Schleife wird der Inhalt an der Speicherstelle &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf 0 getestet. Ist der Wert 0, dann wird die Schleife beendet und die Adresse zurückgeliefert. Ist der Wert ungleich 0, dann wird &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf den nächste long gesetzt, &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; also um 4 Bytes weitergezählt. &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ist ja ein Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, und ein &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; ist 4 Bytes lang.&lt;br /&gt;
&lt;br /&gt;
Die Bedeutung von&lt;br /&gt;
 address + n&lt;br /&gt;
ist also, die Adresse um das &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;-fache der Größe des Typs, auf den &amp;lt;tt&amp;gt;address&amp;lt;/tt&amp;gt; zeigt, zu erhöhen. Dabei ist &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; eine ganze Zahl und darf auch negativ sein.&lt;br /&gt;
&lt;br /&gt;
Hier noch ein Beispiel einer Funktion, die nach einer Person mit einer bestimmten ID sucht (für die Definition von &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; siehe [[#Strukturen|Strukturen]]). Der Parameter &amp;lt;tt&amp;gt;person&amp;lt;/tt&amp;gt; ist dabei ein Array von Strukturen. Eine Person mit der gesuchten ID muss existieren, ansonsten hat die Suchfunktion kein definiertes Verhalten.&lt;br /&gt;
 {{comment|Sucht nach einer Person mit der ID person_id}}&lt;br /&gt;
 struct Person * &lt;br /&gt;
 suche_person_id (struct Person * person, int person_id)&lt;br /&gt;
 {&lt;br /&gt;
    while (person-&amp;gt;id != person_id)&lt;br /&gt;
       person++;&lt;br /&gt;
 &lt;br /&gt;
    return person;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:1em; padding:1em; border:solid 2px #FF0040;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- Vorlage:FarbigerRahmen funzt hier net --&amp;gt;&lt;br /&gt;
Beachte, daß es nicht sinnvoll ist, zwei Zeiger zu addieren oder zu multiplizieren. Ausserdem ist das &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt; der Zeiger-Arithmetik nicht kommutativ. Eine Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, der an Adresse 1 im Speicher zeigt, wird man schreiben als&lt;br /&gt;
 (long *) 1&lt;br /&gt;
Addiert man darauf eine ganze Zahl, dann haben die entstehenden Ausdrücke unterschiedliche Werte:&lt;br /&gt;
 (long *) 1 + 2    {{comment|zeigt zu Adresse 9}}&lt;br /&gt;
 (long *) 2 + 1    {{comment|zeigt zu Adresse 6}}&lt;br /&gt;
 (long *) (1 + 2)  {{comment|zeigt zu Adresse 3}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==void-Pointer==&lt;br /&gt;
Eine besondere Art von Zeiger ist der void-Pointer&lt;br /&gt;
 void * addr;&lt;br /&gt;
Ein void-Pointer ist ein &amp;quot;Zeiger auf irgendwas&amp;quot;, dementsprechend kann er nicht dereferenziert werden, Anwenden von &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf einen solchen Zeiger gibt also einen Fehler. Ausserdem ist es nicht möglich, mit einem void-Pointer Zeigerarithmetik zu machen, weil er nicht auf eine definierte Art von Objekt zeigt. Der Vorteil eines void-Pointers ist, daß er jede Art von Zeiger aufnehmen kann.&lt;br /&gt;
&lt;br /&gt;
Dazu betrachten wir die Funktion &amp;lt;tt&amp;gt;send_buf&amp;lt;/tt&amp;gt;, die eine Adresse erhält und ab dieser Adresse &amp;lt;tt&amp;gt;num&amp;lt;/tt&amp;gt; Bytes versenden soll. Wir könnten die Funktion so schreiben:&lt;br /&gt;
 void send_buf (unsigned char * buf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   ...&lt;br /&gt;
Das ist jedoch hässlich, wenn wir damit etwas anderes verschicken wollen als &amp;lt;tt&amp;gt; unsigned char&amp;lt;/tt&amp;gt;, etwa eine Struktur wie &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; (vom Typ &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;):&lt;br /&gt;
 send_buf ((unsigned char*) &amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
Ohne den Cast der Adresse von &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; zu einem Zeiger auf &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt; bekommt man eine Warnung oder gar einen Compilerfehler.&lt;br /&gt;
Dieses Zeiger gecaste ist mühsam und hässlich, es muss bei jedem Aufruf der Funktion explizit hingeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Besser ist es, den ersten Parameter der Funktion als void-Pointer zu definieren und den Cast in der Funktion zu machen:&lt;br /&gt;
 void send_buf (void * vbuf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   unsigned char *buf = (unsigned char*) vbuf;&lt;br /&gt;
   ...&lt;br /&gt;
Durch den Cast in der Funktion kann auf den Inhalt des Zeigers zugegriffen werden. Man muss nur festlegen, ''wie'' man zugreifen will, nämlich als &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Der Aufruf kann jetzt ohne Pointer-Cast erfolgen: &lt;br /&gt;
 send_buf (&amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
&lt;br /&gt;
==Null-Pointer==&lt;br /&gt;
==Zeiger als Parameter==&lt;br /&gt;
Wenn Sie ein Unterprogramm aufrufen, können Sie diesem Parameter übergeben, aber keine Werte zurückgekommen (außer den Funktionswert bei Funktionen). Dies hat einen guten Grund: beim Aufruf werden nicht die aufgerufenen Parameter benutzt, sondern es werden deren Werte in neue Variablen kopiert. Diese Variablen werden am Ende des Unterprogrammes &amp;quot;zerstört&amp;quot;, ohne ihre Werte an die aufrufenden Parameter zu übergeben. Jede Veränderung eines Parameters hat daher keine Auswirkung auf den Parameter.&lt;br /&gt;
&lt;br /&gt;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der C-Compiler legt dann immer noch Kopien an. In dieser Kopie steht aber kein Wert, sondern die Adresse einer Varaiblen. Und auf diese können Sie dann zugreifen. Denken Sie nur an &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; &amp;amp;ndash; da übergeben Sie ja auch die Adresse einer Variablen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void erhoehe (int *zeiger)&lt;br /&gt;
{&lt;br /&gt;
  *zeiger = 1 + *zeiger;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  erhoehe (&amp;amp;zahl);&lt;br /&gt;
  printf (&amp;quot;\nDie erhoehte Zahl lautet: %d\n&amp;quot;, zahl);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Zeiger auf Funktionen==&lt;br /&gt;
&lt;br /&gt;
Stell dir vor, du willst einen Sortieralgorithmus wie Bubble-Sort oder Quick-Sort oder wie sie alle heissen implementieren. Für den Sortieralgorithmus ist eigentlich egal, ''was'' er zu sortieren hat. Ihm ist es egal, ob er Zahlen aufwärts sortieren soll oder Strings in lexikographischer Reihenfolge, ob Objekte nach Größe oder Gewicht, Personen nach Alter oder Adressen nach Postleitzahl. Das einzige, was der Algorithmus wissen muss, ist ''wie'' er zwei Objekte zu vergleichen hat und wann eines davon &amp;quot;kleiner&amp;quot; (im Sinne der Ordnung, nach der sortiert werden soll) ist. &lt;br /&gt;
&lt;br /&gt;
Eine einfache Sortierfunktion, die nur zwei Zahlen sortiert, könnte man also so schreiben: &lt;br /&gt;
 {{comment|Sortiert ein Array von 2 int-Zeigern nach den Inhalten &lt;br /&gt;
  * an den Zeiger-Adressen}}&lt;br /&gt;
 void sort2_a (int * p[])&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Inhalte vergleichen...}}&lt;br /&gt;
    if (*p[0] &amp;gt; *p[1])&lt;br /&gt;
    {&lt;br /&gt;
       {{comment|... und ggf. Dreieckstausch der 2 Zeiger}}&lt;br /&gt;
       int * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Die Funktion bekommt ein Array der Länge&amp;amp;nbsp;2. In diesem Array stehen Zeiger auf die zu sortierenden Zahlen. Ein Array mit Zeigern zu verwenden und nicht ein Array von &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; scheint recht umständlich, und das ist es hier auch. Aber stell dir vor, du willst Strukturen wie &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; sortieren. Das Tauschen zweier Strukturen würde bedeuten, ihre kompletten Inhalte umzukopieren! Das wäre sehr aufwändig. Viel einfacher ist das Kopieren, wenn nur die Adressen zu kopieren sind.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; könnte dann so aussehen:&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void sortiere (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|p[] enthält 2 int-Zeiger: die Adressen von a und b}}&lt;br /&gt;
    int * p[2];&lt;br /&gt;
    p[0] = &amp;amp;a; &lt;br /&gt;
    p[1] = &amp;amp;b; &lt;br /&gt;
 &lt;br /&gt;
    {{comment|Sortiere die Zeiger}} &lt;br /&gt;
    sort2_a (p);&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Sortiert: %d, %d\n&amp;quot;, *p[0], *p[1]);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Für den nächsten Schritt überlegen wir uns, daß das Array in &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; ebensogut void-Pointer enthalten kann. Die einzige Stelle, an der wir auf die endgültigen int-Objekte zugreifen, ist der Vergleich. Diesen Vergleich lagern wir in die Funktion &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; aus:&lt;br /&gt;
 {{comment|Bekommt zwei void-Pointer und vergleicht die Inhalte.&lt;br /&gt;
  * Liefert 0 bei Gleichheit,&lt;br /&gt;
  * -1 wenn der erste Wert kleiner ist als der zweite und&lt;br /&gt;
  * 1  wenn der erste Wert größer ist als der zweite}}&lt;br /&gt;
 int compare_int (void * p0, void * p1)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Um über die Zeiger zugreifen zu können müssen wir diese&lt;br /&gt;
     * erst zu int-Zeigern casten}}&lt;br /&gt;
    int a0 = * (int*) p0;&lt;br /&gt;
    int a1 = * (int*) p1;&lt;br /&gt;
 &lt;br /&gt;
    if (a0 &amp;gt; a1)  return  1;&lt;br /&gt;
    if (a0 &amp;lt; a1)  return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void sort2_b (void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare_int (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Ein Aufruf von &amp;lt;tt&amp;gt;sort2_b&amp;lt;/tt&amp;gt; sieht dann genauso aus wie ein Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt definieren wir uns den neuen Datentyp &amp;lt;tt&amp;gt;comparator_t&amp;lt;/tt&amp;gt;. Dieser ist ein Zeiger auf eine Funktion, die zwei void-Pointer erhält und einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; zurückliefert, also analog arbeitet zu &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; von oben. &lt;br /&gt;
&lt;br /&gt;
Unsere Sortierfunktion bekommt nun neben dem zu sortierenden Zeiger-Array auch eine Vergleichsfunktion &amp;lt;tt&amp;gt;compare&amp;lt;/tt&amp;gt; mitgeliefert, die sie aufruft, wenn sie zwei Objekte vergleichen will&lt;br /&gt;
 {{comment|comparator_t sind Zeiger auf Funktionen, die 2 void-Pointer&lt;br /&gt;
  * erhalten und einen int zurückliefern}}&lt;br /&gt;
 typedef int (*comparator_t) (void*, void*);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Der Sortierer bekommt einen Funktionszeiger auf den Vergleicher.&lt;br /&gt;
  * Der Aufruf vom compare geht so als wäre es eine &amp;quot;normale&amp;quot; Funktion&lt;br /&gt;
  * (ist es im Endeffekt ja auch)}}&lt;br /&gt;
 void sort2_c (comparator_t compare, void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Bei einem Aufruf von &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; muss man dann einen Komparator mit angeben. In einem Beispiel analog zu &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; von oben ist das:&lt;br /&gt;
 sort2_c (compare_int, p);&lt;br /&gt;
Um zwei Strings lexikographisch zu sortieren nehmen wie die Standard-Funktion &amp;lt;tt&amp;gt;strcmp&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void foo()&lt;br /&gt;
 {&lt;br /&gt;
    char * worte[] = { &amp;quot;Wort1&amp;quot;, &amp;quot;Wort2&amp;quot; };&lt;br /&gt;
 &lt;br /&gt;
    sort2_c ((comparator_t) strcmp, (void**) worte);&lt;br /&gt;
 }&lt;br /&gt;
Die Casts sind hier erforderlich. Alternativ könnte man &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; mit reinen void-Pointern versorgen und diese dann dort umcasten.&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
&lt;br /&gt;
Die Syntax zur Definition/Deklaration von Funktionszeigern ist etwas verzwackt. Zur Verdeutlichung ein paar Beispiele. Dabei legt das linke &amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt; jeweils den Return-Typ fest.&lt;br /&gt;
 {{comment|definiert einen neuen Funktionszeiger-Typ}}&lt;br /&gt;
 typedef {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert eine Variable als Funktionszeiger}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert ein Array von Funktionszeigern (mit Initializer)}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}[]) ({{type}}, {{type}}, ...) = { wert1, wert2, ... };&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer}}&lt;br /&gt;
 ({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer und ruft die Funktion auf}}&lt;br /&gt;
 (({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}) (arg1, arg2, ...);&lt;br /&gt;
&lt;br /&gt;
=Standard-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==String-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===strcpy===&lt;br /&gt;
Bei vielen Compilern können sie einem String nicht direkt einen Wert (Text) zuweisen. Dazu müssen Sie dann die Prozedur strcpy() benutzen. Diese erwartet als ersten Parameter den Namen einer String-Variablen (ohne eckige Klammern) und als zweiten Parameter den eines (anderen) Strings. Letzterer kann auch ein in doppelten Hochkommas (&amp;quot;) eingeschlossener Text sein. Die Funktion fügt am Ende automatisch ein 0-Zeichen ein. Um diese Funktion nutzen zu können, müssen Sie die Datei string.h includieren! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri1[21], eingabe[21];&lt;br /&gt;
&lt;br /&gt;
  strcpy (stri1, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Der 1. String: %s\n&amp;quot;, stri1);&lt;br /&gt;
  printf (&amp;quot;Bitte geben Sie maximal 20 Zeichen ein: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%s&amp;quot;, eingabe);&lt;br /&gt;
  strcpy (stri1, eingabe);&lt;br /&gt;
  printf (&amp;quot;\n%s = %s&amp;quot;, stri1, eingabe);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis:''' &lt;br /&gt;
Da ein String, wie jedes Feld, eigentlich ein Zeiger ist, dürfen Sie kein &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; bei &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; angeben!&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
Es werden zwei gleich große Strings definiert: &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;eingabe&amp;lt;/tt&amp;gt;, mit je 20 &amp;quot;nutzbaren&amp;quot; Zeichen. &lt;br /&gt;
In &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; wird die Zeichenkette &amp;lt;tt&amp;gt;&amp;quot;hallo&amp;quot;&amp;lt;/tt&amp;gt; hineinkopiert. Das 0-Zeichen am Ende wird automatisch angefügt. &lt;br /&gt;
Der String wird ausgegeben. Als neues &amp;quot;Sonderzeichen&amp;quot; kommt &amp;lt;tt&amp;gt;%s&amp;lt;/tt&amp;gt; ins Spiel. Es hat die gleiche Aufgabe wie &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt;, nur für Strings. &lt;br /&gt;
Sie werden gebeten, eine String einzugeben. &lt;br /&gt;
Dieser String wird danach in die Variable &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; kopiert. &lt;br /&gt;
Beide Strings, die ja nun die gleiche Zeichenkette enthalten, werden ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===strlen===&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;strlen&amp;lt;/tt&amp;gt;, die als Parameter eine String-Variable erwartet, liefert die Länge diese Strings zurück. Sie werden jetzt vermutlich sagen: &amp;quot;Das ist doch klar, wie lang der String ist. Ich habe es ja bei der Deklaratin angegeben&amp;quot;. Das stimmt schon, aber denken Sie noch einmal an die null-terminierten Strings. Das 0-Zeichen steht am Ende des Strings (am Ende der gültigen Zeichenfolge), aber nicht unbedingt am Ende des reservierten Speicherplatzes. Haben Sie eine Variable &amp;quot;char Variable[21];&amp;quot;, und ihr den Wert &amp;quot;hallo&amp;quot; zugewiesen, dann steht das null-Zeichen in Variable[5]. Der &amp;quot;gültige&amp;quot; String ist also 5 Zeichen (0-4) lang. Und genau das (5) würde strlen zurück liefern. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri[21];&lt;br /&gt;
  &lt;br /&gt;
  strcpy (stri, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
  printf (&amp;quot;Der String ist %d Zeichen lang&amp;quot;, strlen (stri));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird vor allem gebraucht, wenn Sie direkt auf den String zugreifen, mittels &amp;lt;tt&amp;gt;stri[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;stri[1]&amp;lt;/tt&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
==Ein- und Ausgabe-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===Bildschirm-Ausgabe===&lt;br /&gt;
Bisher war das Tutorial trotz aller Beispiele reine Theorie. Sie konnten zwar Programme schreiben, aber die Funktion nicht testen. Hier lernen Sie nun, wie Sie etwas am Bildschirm ausgeben.&lt;br /&gt;
&lt;br /&gt;
Die dazu notwendige Funktione heisst &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (das '&amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt;' ist kein Fehler!). Diese Anweisung gibt die ihr übergebenen Parameter auf das Standard-Ausgabegerät aus, in der Regel also auf den Bildschirm. Sie kann beliebig viele Parameter übernehmen. Es müssen jedoch Standard-Datentypen (z.B. &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;...) sein! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
    int zahl1 = 12;&lt;br /&gt;
    char zeichen1 = 'A';&lt;br /&gt;
    &lt;br /&gt;
    printf (&amp;quot;Das ist Text, und er wird als solcher ausgegeben. \n&amp;quot;);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zahl1' ist: %d \n&amp;quot;, zahl1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %c \n&amp;quot;, zeichen1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %d \n&amp;quot;, zeichen1);&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt Text aus. Das Zeichen am Ende (&amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;) bedeutet &amp;quot;New Line&amp;quot;, es bewegt den Cursor an den Anfang der nächsten Zeile. &lt;br /&gt;
&lt;br /&gt;
Der zweite &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt auch Text aus, am Ende befindet sich wieder das &amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;, um einen Zeilenvorschub zu erreichen. Das &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; wird vom Compiler durch den ersten Parameter ersetzt, der nach dem Text angegeben wird. In diesem Fall wird &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; also durch den Wert der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ersetzt. Das &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; im &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; bedeutet &amp;quot;Dezimalzahl&amp;quot;, der Computer gibt also eine ganze Zahl aus. &lt;br /&gt;
&lt;br /&gt;
In der dritten Ausgabe wird ein Zeichen ausgegeben. Diesmal bedeutet &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; &amp;quot;char&amp;quot; (Zeichen). Es wird also &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; durch ein &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt; ersetzt, denn die Variable &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; wird als Character interpretiert. &lt;br /&gt;
&lt;br /&gt;
Die letzte Ausgabe interpretiert den Inhalt von &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; als Zahl, und gibt dager den ASCII-Wert von &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, also 65 aus. Das ist ein typisches Beispiel für das mögliche unterschiedliche Interpretieren einer  Variablen!&lt;br /&gt;
&lt;br /&gt;
===Tastatur-Eingabe===&lt;br /&gt;
&lt;br /&gt;
Um ein &amp;quot;gscheites&amp;quot; Programm schreiben zu können, muß man wissen, wie der Benutzer über die Tastatur Befehle eingeben kann. Die dafür notwendigen Funktionen stelle ich in diesem Kapitel vor.&lt;br /&gt;
Die wichtigste Funktion ist &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt;. Er liest Daten von der Tastatur. Die Syntax entspricht derer von &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int  zahl1;&lt;br /&gt;
char zeichen1;&lt;br /&gt;
&lt;br /&gt;
printf (&amp;quot;Bitte geben Sie eine Zahl ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl1);&lt;br /&gt;
printf (&amp;quot;Geben Sie einen Zeichen ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%c&amp;quot;, &amp;amp;zeichen1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Programm gibt eine Eingabeaufforderung aus. Dann erwartet es vom Benutzer, daß er eine Zahl eingibt, die mit [ENTER] bestätigt wird. Dieser Wert wird in &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; abgespeichert. Danach erfolgt wiederum eine Aufforderung zur Eingabe, diesmal eines einzelnen Zeichens. Dieses kann man nun eingeben und ebenfalls mit [ENTER] bestätigen.&lt;br /&gt;
&lt;br /&gt;
Macht man keine dem Datentyp der erwarteten Variable entsprechende Eingabe, dann bricht das Programm mit einer Fehlermeldung ab (wenn man z.B. &amp;quot;1_T2&amp;quot; eingibt, wenn eine Zahl erwartet wird)!&lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; vor den Parametern ist notwendig. Warum, das erfahren Sie im Kapitel &amp;quot;Unterprogramme&amp;quot;. Für die Profis eine Kurz-Erklärung: Das Unterprogramm &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; bekommt zwar einen Wert übergeben, kann aber keinen zurückliefern (&amp;quot;call by value&amp;quot;). Daher wird kein Wert, sondern ein Zeiger auf eine Variable übergeben. Mit dem &amp;amp; Zeichen bekommen Sie die Adresse einer Variablen (&amp;quot;call by reference&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=Parameter von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;=&lt;br /&gt;
Das Unterprogramm &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; kann, wie jede andere Funktion, Parameter besitzen. Doch keine selbst gewählten, sondern nur bestimmte. Doch warum braucht main Parameter? Denken Sie einmal an alle Betriebssystembefehle:&lt;br /&gt;
&amp;lt;tt&amp;gt;dir *.exe &amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;copy *.* a:&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;ls -la &amp;lt;/tt&amp;gt;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen!&lt;br /&gt;
&lt;br /&gt;
=Kurzreferenz=&lt;br /&gt;
==Syntax-Bausteine==&lt;br /&gt;
&lt;br /&gt;
Die Erklärung des Aufbaus von C-Befehlen erfolgt neben einfachen Beispielen auch durch ihren prinzipellen Aufbau. In diesen Syntax-Beschreibungen finden sich immer wieder die gleichen Bausteine, die hier näher erklärt werden sollen. Falls Dir solch ein Syntax-Baustein begegnet, kannst Du ihn anklicken und kommst dann zu seiner Erläuterung. &lt;br /&gt;
&lt;br /&gt;
In den Beispielen selbst gehören auch die spitzen Klammern zu dem Baustein (was daran zu erkennen ist, daß auch die Klammern eingefärbt sind). Die Klammern dürfen in einem konkreten C-Programm daher nicht eingetippt werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bezeichner&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Bezeichner in C dienen dazu, Variablen zu identifizieren und ihnen sprechende Namen zu geben, um die Quelle lesbarer zu machen. Man braucht Bezeichner auch, um selbstdefinierte Datentypen zu benennen und zum Benennen von Struct- und Union-Komponenten sowie als Namen für Funktionen und Sprungmarken (Labels).&lt;br /&gt;
&lt;br /&gt;
Bezeichner dürfen aus den Kleinbuchstaben &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;z&amp;lt;/tt&amp;gt;, den Großbuchstaben &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;Z&amp;lt;/tt&amp;gt;, dem Unterstrich&amp;amp;nbsp;&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt; und den Ziffern &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;9&amp;lt;/tt&amp;gt; aufgebaut werden, wobei an erster Stelle jedoch keine Ziffer stehen darf.&lt;br /&gt;
&lt;br /&gt;
Es wird zwischen Groß- und Kleinschreibung unterschieden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Ausdruck in C ist ein Konstrukt, das einen Wert hat. Ob dieser Wert eine ganze Zahl ist, eine Kommazahl oder ein Zeiger, etc. ist dabei egal. Die einfachsten Ausdrücke sind Konstanten wie&lt;br /&gt;
 2&lt;br /&gt;
oder Variablen wie&lt;br /&gt;
 ein_zahl&lt;br /&gt;
Mehrere Ausdrücke können durch [[#Liste der Operatoren|Operatoren]] zu komplexeren Ausdrücken kombiniert werden, etwa&lt;br /&gt;
 eine_zahl + andere_zahl == 2&lt;br /&gt;
oder &lt;br /&gt;
 eine_zahl = 2&lt;br /&gt;
Letzterer hat den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; und den Nebeneffekt, daß er diesen Wert an &amp;lt;tt&amp;gt;eine_zahl&amp;lt;/tt&amp;gt; zuweist.&lt;br /&gt;
&lt;br /&gt;
Auch der Aufruf einer Funktion, die einen Rückgabewert liefert, ist ein Ausdruck:&lt;br /&gt;
 sin (1.2)&lt;br /&gt;
und kann zum Aufbau komplexerer Ausdrüche verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bedingung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Bedingung ist ein Ausdruck, bei der nur interessiert, ob dieser zu&amp;amp;nbsp;0 (unwahr) auswertet oder zu ungleich&amp;amp;nbsp;0 (wahr). Solche Ausdrücke findet man in if-Anweisungen, in Schleifenbedingungen und bedingten Zuweisungen&lt;br /&gt;
 (ein_wert &amp;lt; 2) || (ein_wert &amp;gt; 40)&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Lvalue ist ein Ausdruck, dem etwas zugewiesen werden kann. Der Name ''Lvalue'' kommt aus dem Englischen. Das ''L'' steht abkürzend für left. Ein Lvalue ist damit ein Ausdruck, der auf der linken Seite eine Zuweisung in C stehen darf. Das &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; in den folgenden Beispiel-Ausdrücken muss ein Lvalue sein:&lt;br /&gt;
 x = y-1&lt;br /&gt;
&lt;br /&gt;
 x++&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Konstante&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Konstante ist ein Ausdruck, dessen Wert dem Compiler bekannt ist. Beispiele für Konstanten sind etwa&lt;br /&gt;
 7&lt;br /&gt;
 'B'&lt;br /&gt;
 -13.98e12&lt;br /&gt;
 1+(2*3)&lt;br /&gt;
und die Werte von [[#Enum|Enum]]s. &lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; aus dem folgenden Codestück definiert jedoch keine Konstante in diesem Sinne&lt;br /&gt;
 const double Pi = 3.14159256;&lt;br /&gt;
denn in einem anderen Quellmodul könnte durch die Deklaration&lt;br /&gt;
 extern const double Pi;&lt;br /&gt;
das Symbol &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; bekannt sein, ohne daß sein Wert bekannt ist!&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Adresse&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Adresse ist ein Ausdruck, der einen Speicherort (physikalisch oder virtuell) halten kann. Adressen erhält man dadurch, daß man einem Bezeichner den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt;voranstellt, Adressen durch Arithmetik berechnet oder Zahlen zu Adressen castet. Folgende Ausdrücke sind Adressen (eine sinnvolle Deklaration der auftretenden Variablen vorausgesetzt)&lt;br /&gt;
 &amp;amp; eine_zahl&lt;br /&gt;
 &amp;amp; ein_array[10]&lt;br /&gt;
 &amp;amp; ein_struct&lt;br /&gt;
 &amp;amp; ein_struct.komponente&lt;br /&gt;
 (int *) 0x1234&lt;br /&gt;
 (int *) eine_zahl&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Deklaration&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Anweisungen sind gewissermassen die Atome (oder Moleküle?), aus denen ein C-Programm besteht. Jedes C-Programm ist eine Abfolge von Deklarationen und Anweisungen. Einfache Anweisungen erhält man, in dem man einen Ausdruck nimmt und einen Strichpunkt dahinter schreibt:&lt;br /&gt;
 {{Ausdruck|}};&lt;br /&gt;
wie in&lt;br /&gt;
 x = x+1;&lt;br /&gt;
&lt;br /&gt;
Andere Anweisungen sind die unten aufgeführten Schleifen und die if- sowie die switch-Anweisung.&lt;br /&gt;
&lt;br /&gt;
Mehrere Deklarationen und Anweisungen können zu einem Block zusammengefasst werden. Dieser Block stellt dann wieder eine einzelne Anweisung dar und kann genau so gehandhabt werden!&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
In diesem Sinne ist auch z.B. die Syntax der if-Anweisung zu verstehen&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
besagt, daß der abhängig ausgeführte Code eine einzelne Anweisung sein darf oder eben ein kompletter Block oder die Verschachtelung mehrerer Blöcke etc.&lt;br /&gt;
&lt;br /&gt;
Eine Anweisung kann auch &amp;quot;leer&amp;quot; sein, also nichts tun. Diese Anweisungen sind der leere Block&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
und der Strichpunkt&lt;br /&gt;
 ;&lt;br /&gt;
die man gelegentlich in Schleifen findet:&lt;br /&gt;
 while (!timeout())&lt;br /&gt;
    {}&lt;br /&gt;
oder hinter Sprungmarken, die sonst direkt vor einer schliessenden Blockklammer stünden:&lt;br /&gt;
 {&lt;br /&gt;
    ...&lt;br /&gt;
    goto ein_label;&lt;br /&gt;
    ...&lt;br /&gt;
    {{Label|ein_label}}:;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Nicht jede Anweisung ist an jeder Stelle eines C-Programms erlaubt, so darf ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; nut innerhalb einer Schleife stehen. Gleiches gilt für &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;, das aber auch innerhalb eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; vorkommen darf.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Dies steht für einen Datentyp. Es kann ein elementarer Typ sein wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;, ein Zeiger darauf wie &amp;lt;tt&amp;gt;char*&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;void*&amp;lt;/tt&amp;gt;, und auch Qualifier enthalten wie das &amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt; im Typ &amp;lt;tt&amp;gt;unsigned long long&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Zu den Typen gehören auch zusammengesetzte Datentypen wie Strukturen und Unions, mit &amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt; selbst definierte Typen und natürlich Zeiger darauf, wie aus dem Abschnitt [[#Datentypen|Datentypen]]:&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person *&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;data32_t&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;&lt;br /&gt;
und Zeiger auf Funktionen.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Parameterliste&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
Die Parameterliste bei einer Funktionsdefinition gibt an, wieviel Übergabeparameter sie bekommt, wie diese heissen und welchen Typs diese sind. Der prinzipielle Aufbau ist&lt;br /&gt;
 {{Type}} {{Bezeichner}}, {{Type}} {{Bezeichner}}, ...&lt;br /&gt;
Falls die Funktion keine Parameter hat, dann ist die Parameterliste leer.&lt;br /&gt;
&lt;br /&gt;
Hier als Beispiel die zweiparameterige Funktion &amp;lt;tt&amp;gt;produkt&amp;lt;/tt&amp;gt;. Der erste Parameter heisst&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und ist ein &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;. Der zweite namens&amp;amp;nbsp;&amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; ist vom Typ &amp;quot;Zeiger auf double&amp;quot;, der Inhalt &amp;lt;tt&amp;gt;*b&amp;lt;/tt&amp;gt; ist also auch ein double.&lt;br /&gt;
&lt;br /&gt;
'''Definition der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b)&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
In älteren C-Quellen findet man noch eine andere Syntax für die Deklaration der Parameter, die aber heute praktisch nicht mehr verwendet wird:&lt;br /&gt;
'''alte Definition der Funktion:'''&lt;br /&gt;
 double produkt (a, b)&lt;br /&gt;
 double a, *b;&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Um die Funktion bekannt zu machen, verwendet man eine Deklaration bzw. den Prototypen, der dem Compiler nur mitteilt, welche Parameter die Funktion bekommt und was sie zurückliefert. Für den Aufruf der Funktion muss der Compiler nur diesen Prototyp kennen, ''was'' die Funktion im Endeffekt macht und wie sie implementiert wurde ist egal, sie wird als BlackBox angesehen.&lt;br /&gt;
&lt;br /&gt;
'''Prototyp der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b);&lt;br /&gt;
Hier dürfen die Bezeichner auch fehlen:&lt;br /&gt;
 double produkt (double, double*);&lt;br /&gt;
&lt;br /&gt;
==if==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==if-else==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==for==&lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Eine for-Schleife entspricht folgendem Konstrukt. Dabei sind die drei Ausdrücke optional. Fehlt die Bedingung, dann wird diese als &amp;quot;wahr&amp;quot; angenommen. Die beiden anderen Ausdrücke wird man als Ausdrücke mit Nebeneffekt wählen wie z.B. &amp;lt;tt&amp;gt;x=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;x=x-2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
 {&lt;br /&gt;
    {{Ausdruck|1}};&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_loop}}:&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
    else&lt;br /&gt;
       goto _break;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_continue}}:&lt;br /&gt;
    {{Ausdruck|2}};&lt;br /&gt;
    goto _loop;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_break}}:;&lt;br /&gt;
 }&lt;br /&gt;
Die Labels &amp;lt;tt&amp;gt;_break&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_continue&amp;lt;/tt&amp;gt; entsprechen den Sprungzielen einer &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Anweisung innerhalb von &amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==do-while==&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while  ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
==while==&lt;br /&gt;
 while  ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==switch==&lt;br /&gt;
 switch  ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    ...&lt;br /&gt;
  &lt;br /&gt;
    default:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#break-Anweisung|&amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Konstanten|&amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#continue-Anweisung|&amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#do-while-Schleife|&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Enum|&amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#for-Schleife|&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#goto-Anweisung|&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Inlining|&amp;lt;tt&amp;gt;inline&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#return-Anweisung|&amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Liste der Operatoren|sizeof]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Strukturen|&amp;lt;tt&amp;gt;struct&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Eigene Datentypen|&amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Unions|&amp;lt;tt&amp;gt;union&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#while-Schleife|&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund2}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Arithmetische Operatoren&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Dies sind die &amp;quot;normalen&amp;quot; arithmetischen Operationen, wie man sie aus der Schule kennt. Man kann damit und allen anderen Operatoren auch komplexere Ausdrücke aufbauen. Die Prioritäten sind so, wie man sie kennt, also &amp;quot;Punktrechnung vor Strichrechnung&amp;quot;. Will man dies ändern, dann mit den runden Klammern:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;1+2*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 7&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(1+2)*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 9&amp;lt;br/&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}}&amp;amp;nbsp;+&amp;amp;nbsp;{{Ausdruck|}}&amp;lt;/tt&amp;gt; || Addition&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} - {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Subtraktion&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} * {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Multiplikation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} / {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Division&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} % {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Rest der Division (modulo)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;- {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Vorzeichenumkehr, Zweier-Komplement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Logische Operatoren und Vergleiche&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die logischen und die vergleichenden Operatoren liefern als Ergebnis den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (wahr) oder einen Wert ungleich&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (falsch, um genau zu sein den Wert &amp;lt;tt&amp;gt;!0&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Man kann das Ergebnis zwar einer Variablen zuweisen, in aller Regel wird man solche Ausdrücke jedoch in Bedingungen zu &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder in Abbruch-Bedingungen von Schleifen finden.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;&amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches AND: beides wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124;&amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches OR: mind. eines ist wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;! {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches NOT (0 &amp;amp;harr; ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} == {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} != {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist nicht gleich&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bitweise Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~ {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise NOT (Einser-Komplement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise AND&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise ODER&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} ^ {{Ausdruck|}}&amp;lt;/tt&amp;gt; ||bitweise XOR&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Shift-Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;lt;&amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Bits nach links schieben&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;gt;&amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Schieben nach rechts schieben&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Typen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Ein Cast in C kann dazu verwendet werden, den Typ eines Ausdruckes zu ändern oder den Ausdruck mit einer bestimmten Genauigkeit zu berechnen. Wird z.B. eine Berechnung standardmässig in 16 Bit ausgeführt, dann kann man mit einem Cast &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(long) &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
ausdrücken, daß die Berechnung in 32 Bit erfolgen soll. Des weiteren kann man Zeiger und ganze Zahlen und Gleitkommazahlen ineinander umwandeln.&lt;br /&gt;
&lt;br /&gt;
Casts können ''nicht'' dazu verwendet werden, um z.B. eine Zahl in einen String zu konvertieren, der diese Zahl darstellt! Dafür gibt es spezielle Funktionen wie &amp;lt;tt&amp;gt;itoa&amp;lt;/tt&amp;gt;!&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Type}}) {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Cast, Typwandlung&lt;br /&gt;
|-&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;| &amp;lt;tt&amp;gt;sizeof ({{Type}})&amp;lt;/tt&amp;gt; || Eine Konstante, deren Wert die Größe (in Bytes) des Typs ist. &amp;lt;tt&amp;gt;sizeof&amp;lt;/tt&amp;gt; ist auch auf Objekte anwendbar wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, Arrays bekannter Größe, Strukturen und Unions,  Array-, Struktur- und Union-Komponenten, Pointer, etc. Beispiel:&amp;lt;br/&amp;gt;&lt;br /&gt;
 int i, sum=0, array[] = { 1, -13, 4, 0, sizeof (int*) };&lt;br /&gt;
 &lt;br /&gt;
 for (i=0; i&amp;lt; sizeof (array) / sizeof (array[0]); i++)&lt;br /&gt;
    sum += array[i];&lt;br /&gt;
Alle Elemente des Arrays werden aufaddiert, ohne daß deren Anzahl explizit in der Schleife genannt ist.&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zeiger und Adressen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;* {{Adresse}}&amp;lt;/tt&amp;gt; || der Inhalt an Adresse&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp; {{Lvalue}}&amp;lt;/tt&amp;gt; || Adresse von&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Strukturen, Unions, Arrays&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Struct&amp;gt;}}.{{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Zeiger-auf-Struct&amp;gt;}} -&amp;gt; {{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union, deren Adresse man hat&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Adresse}}&amp;amp;#91;{{Ausdruck|}}&amp;amp;#93;&amp;lt;/tt&amp;gt; || Array-Element&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bedingte Auswertung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Bedingung}}) ? {{Ausdruck|}} : {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Auswahl des Wertes abhängig von der Bedingung&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zuweisung und Operatoren mit Nebeneffekt&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die Unterschiede der post- und pre-Varianten der Increment/Decrement kommen in Konstrukten wie &amp;lt;tt&amp;gt;x = *p++&amp;lt;/tt&amp;gt; zum tragen:&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *p++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; p = p+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *++p;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; p = p+1; x = *p;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = (*p)++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; *p = (*p)+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = ++(*p);&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; *p = (*p)+1; x = *p;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} = {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Zuweisung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++ {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-- {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Decrement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ++&amp;lt;/tt&amp;gt; || Post-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} --&amp;lt;/tt&amp;gt; || Post-Decrement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Kurzschreibweisen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Für ganz Faule gibt es anstatt&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a = a @ b&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
für viele Operatoren (hier dargestellt durch ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;@&amp;lt;/tt&amp;gt;) die abkürzende Schreibweise&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a @= b&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} += {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} -= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} *= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} /= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} %= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ^= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;lt;&amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;gt;&amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Autoren=&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
=Quellen=&lt;br /&gt;
* Kernighan und Ritchie&lt;br /&gt;
* Christian Wirth, C-Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
* W. Alex, Einführung in C/C++&lt;br /&gt;
* Peter Baeumle-Courth, ANSI-C im Überblick&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://wwwuser.gwdg.de/~kboehm/ebook/inhalt.html C-Programmieren unter Linux]&lt;br /&gt;
* [http://www.gdv.uni-hannover.de/documentation.php Skripte zum Selbststudium: C, C++, Java, etc]&lt;br /&gt;
* [http://info.baeumle.com/ansic.html Einführung in ANSI-C]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Quellcode C|!]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Inrfb2</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=11058</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=11058"/>
				<updated>2007-04-09T21:36:40Z</updated>
		
		<summary type="html">&lt;p&gt;Inrfb2: /* &amp;lt;tt&amp;gt;&amp;lt;Parameterliste&amp;gt;&amp;lt;/tt&amp;gt; */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Programmiersprache C wurde 1971 als Gundlage für das Betriebssystem UNIX in den USA entwickelt (UNIX ist zu über 90% in C geschrieben). 1978 wurde von Brian Kernighan und Dennis Ritchie eine eindeutige Sprachdefinition entwickelt. Mittlerweile ist C von ANSI und ISO standardisiert.&lt;br /&gt;
&lt;br /&gt;
Heute sind C und ihr Nachfolger C++ die dominierenden Programmiersprachen. Sehr viele Anwendungen sind in C geschrieben, was inzwischen auch auf eingebettete Systeme zutrifft, die lange in Assembler programmiert werden mussten, da keine ausreichend leistungsfähigen Compiler zur Verfügung standen. &lt;br /&gt;
&lt;br /&gt;
Leider ist C nicht einfach zu lernen &amp;amp;ndash; es wurde weder von noch für Hobby-Programmierer entwickelt &amp;amp;ndash; und eignet sich daher nur bedingt für den Einsteiger. Mit etwas Übung und einem optimierenden Compiler kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
Vom Design her ist C eine Hardware-unabhängig Sprache. Das bedeutet, daß C-Programme mit vertretbarem Aufwand auf ein anderes System portiert werden können. Dazu benötigt man lediglich einen anderen Compiler, und Inline-Assembler-Anweisungen (Assembleranweisungen innerhalb eines C-Programmes) müssen der neuen Hardware (Prozessor) angepasst werden. &lt;br /&gt;
&lt;br /&gt;
==Geschichte==&lt;br /&gt;
;1971: C wird entwickelt&lt;br /&gt;
;1978: Kernighan und Ritchie definieren die Sprache.&lt;br /&gt;
;1983: ANSI und ISO standardisieren C.&lt;br /&gt;
;1992: Bjarne Stroustrup enwickelt die Nachfolgesprache C++.&lt;br /&gt;
&lt;br /&gt;
=Aufbau eines C-Programmes=&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
   C-Programme haben keinen fixen Aufbau wie z.B. Pascal. Es gibt zwar gewisse Regeln, aber sonst sind dem Programmierer alle Freiheiten überlassen. Der folgende &amp;quot;Beispiel-Aufbau&amp;quot; ist daher nicht zwingend und kann durchaus verändert werden.&lt;br /&gt;
&lt;br /&gt;
   Natürlich haben C-Programme einen fixen Aufbau! Ebenso wie Pascal-Programme auch unterliegen sie einer strikten Grammatik! &lt;br /&gt;
Auskommentiert --[[Benutzer:SprinterSB|SprinterSB]] 10:23, 17. Feb 2006 (CET)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Ein einfaches C-Programm könnte folgendermassen aussehen. Das Programm tut eigentlich nichts, aber das Beispiel zeigt den prinzipiellen Aufbau. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 int Zahl1;&lt;br /&gt;
 char Zeichen1;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int zahl2;&lt;br /&gt;
 &lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Beschreibung:'''&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndash; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
 {{comment|void-Definition von main ist nur beim Controller ueblich}}&lt;br /&gt;
 {{comment|spezielle Compilereinstellungen sind noetig, damit bei dieser Definition von main}}&lt;br /&gt;
 {{comment|kein Fehler/Warnung erzeugt wird.}}&lt;br /&gt;
 void main ()&lt;br /&gt;
 {&lt;br /&gt;
     ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
 int main (void)&lt;br /&gt;
 {  {{comment|der Block &amp;quot;main&amp;quot; beginnt}}&lt;br /&gt;
    int zahl;&lt;br /&gt;
    &lt;br /&gt;
    {   {{comment|ein Block beginnt}}&lt;br /&gt;
        {{comment|hier koennen Deklarationen und Anweisungen stehen}}&lt;br /&gt;
    }   {{comment|der Block endet}}&lt;br /&gt;
   &lt;br /&gt;
    return 0;&lt;br /&gt;
 }  {{comment|&amp;quot;main&amp;quot; endet}}&lt;br /&gt;
&lt;br /&gt;
=Datentypen=&lt;br /&gt;
==Elementare Datentypen==&lt;br /&gt;
Der Datentyp einer Variable gibt an, welche Werte eine Variable enthalten kann, welcher Art diese Daten sind und wie sie verarbeitet werden, etwa in arithmetischen Operationen wie einer Addition. So ist es zum Beispiel möglich, in eine Variable vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ganze Zahlen zwischen ca. -32000 und +32000 einzutragen. In einer char-Variable können ASCII-Zeichen gespeichert werden (alles, was Sie mit der Tastatur erzeugen können) oder ganze Zahlen von -128 bis 127.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da C plattformabhängig ist, hängt die Größe eines Datentypes zum Teil von der genutzten Hardware (z.B. 8, 16 oder 32 Bit-Controller) und dem Compiler und dessen Einstellungen ab!&lt;br /&gt;
&lt;br /&gt;
===int, char, short, long (ganze Zahlen)===&lt;br /&gt;
In Variable dieser Typen können Sie ganze Zahlen abspeichern, also z.B. 1, &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;2, 100, 12345. Jeden dieser Typen gibt es in zwei Ausprägungen: als &amp;quot;&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;quot;, also als vorzeichenbehafteten Typ, und als &amp;quot;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&amp;quot;, also ohne Vorzeichen, d.h. das Vorzeichen wird als 0 oder +1 genommen. &lt;br /&gt;
&lt;br /&gt;
Vorzeichenbehaftete Ganzzahl-Typen werden intern im &amp;lt;tt&amp;gt;n-1&amp;lt;/tt&amp;gt;-Komplement dargestellt, das Vorzeichen selbst findet sich also im höchstwertigen Bit. Werden zur Speicherung ''b'' Bits verwendet, dann reicht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;z.B. *zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==Enum==&lt;br /&gt;
&lt;br /&gt;
Über &amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt; können Aufzählungen definiert werden. Die Werte sind &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Werte und beginnen mit&amp;amp;nbsp;0. Der folgende enum hat einen um&amp;amp;nbsp;1 grösseren Wert. Mit einer Zuweisung können auch andere Werte zugeordnet werden. Klarer wird's im Beispiel:&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 enum Farben&lt;br /&gt;
 {&lt;br /&gt;
    ROT,&lt;br /&gt;
    GRUEN,&lt;br /&gt;
    BLAU,&lt;br /&gt;
    BRAUN = 5,&lt;br /&gt;
    SCHWARZ&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
Dies definiert die Konstanten &amp;lt;tt&amp;gt;ROT=0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;GRUEN=1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BLAU=2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BRAUN=5&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;SCHWARZ=6&amp;lt;/tt&amp;gt; und den Typ &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void foo (enum Farben farbe)&lt;br /&gt;
{&lt;br /&gt;
   switch (farbe)&lt;br /&gt;
   {&lt;br /&gt;
      case ROT:&lt;br /&gt;
         ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit kann man anstatt &amp;quot;magischer&amp;quot; Zahlen sprechende Namen im Code verwenden, etwa in Berechnungen und Zuweisungen, Vergleichen oder als Konstante hinter einem &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zusammengesetzte Datentypen==&lt;br /&gt;
===Arrays===&lt;br /&gt;
Oft muß man sehr viele Werte gleichzeitig abspeichern und betrachten, die alle der selben Aufgabe dienen. Man schreibt z.B. ein Programm, das 10 Zahlen einlesen und anschließend wieder ausgeben soll. Man könnte das natürlich mit 10 einzelnen Variablen bewerkstelligen, aber es ist sinnvoller, dabei Arrays &amp;amp;ndash; teilweise auch als ''Felder'' bezeichnet &amp;amp;ndash; zu verwenden.&lt;br /&gt;
&lt;br /&gt;
In einem Array werden mehrere Variablen gleichen Typs zusammengefasst und hintereinander im Speicher abgelegt. So kann man viele tausend Variablen anlegen mit nur einer Zeile Code. Doch es gibt noch größere Vorteile: Sie können das Array mit einer Schleife ganz einfach nach Werten durchsuchen. Stellen Sie sich vor, Sie müssten mit 100 verschiedenen Variablen &amp;lt;tt&amp;gt;Zahl_00&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;Zahl_99&amp;lt;/tt&amp;gt; arbeiten!&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}}&amp;amp;#91;{{Konstante}}&amp;amp;#93;;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 unsigned int werte[100];&lt;br /&gt;
&lt;br /&gt;
Der Name muß natürlich ein gültiger Bezeichner sein, als Datentyp kann jeder Typ genommen werden &amp;amp;ndash; sowohl elementare Datentypen als auch Zeiger, Strukturen, Unions oder selbst definierte Datentypen. In der eckigen Klammer wird die Anzahl der Elemente bekanntgegeben. Ein mit [3] definiertes Array hat Platz für drei Variablen. Da der Index immer bei 0 beginnt, greift man also mit &amp;lt;tt&amp;gt;[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;[1]&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;[2]&amp;lt;/tt&amp;gt; auf den jeweilige Inhalt zu. Um auf eine der im Array enthaltenen Variablen zugreifen zu können, müssen Sie den Variablennamen und in eckigen Klammern den Index (die &amp;quot;Nummer&amp;quot;) der Variablen angeben. Diese Variable verhält sich dann wie eine ganz normale Variable des jeweiligen Datentypes. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #define NZAHLEN 10&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int i;&lt;br /&gt;
    int zahlen[NZAHLEN];  {{comment|zahlen[0] ... zahlen[9]}}&lt;br /&gt;
  &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++)&lt;br /&gt;
    {&lt;br /&gt;
       printf (&amp;quot;Bitte Zahl %d eingeben: &amp;quot;, i);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; zahlen[i]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++) &lt;br /&gt;
       printf (&amp;quot;Zahl %d ist: %d\n&amp;quot;, i, zahlen[i]);&lt;br /&gt;
      &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 10 int-Variablen großes Array angelegt. &lt;br /&gt;
In dieses wird nun der Reihe nach 10 Zahlen eingelesen. &lt;br /&gt;
Anschließend werden alle 10 Zahlen ausgegeben. &lt;br /&gt;
&lt;br /&gt;
Dabei wird die Größe der Arrays und das Schleifenende über das Define &amp;quot;&amp;lt;tt&amp;gt;NZAHLEN&amp;lt;/tt&amp;gt;&amp;quot; angegeben. Dadurch muss nur ''eine Stelle'' im Code geändert werden, wenn die Größe des Arrays einmal einen anderer Wert als 10 haben soll &amp;amp;ndash; dies vermeidet Fehler die dadurch entstehen, wenn man beim Anpassen der Array-Größe eine Codestelle vergisst, zudem wird der Code lesbarer als wenn irgendwo die Zahl &amp;quot;10&amp;quot; auftaucht.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
:Wird ein ungültiger Index angeben (einer, der in der Deklaration nicht enthalten ist) können  undefinierte Dinge passieren, wenn dadurch andere Variableninhalte oder Programmcode überschrieben wird, der hinter oder vor dem Array im Speicher liegt. Schlimmstenfalls kann sogar der Computer/Controller abstürzen. Also darauf achten, daß keine ungültigen Werte als Index auftreten!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Strings (Zeichenketten)===&lt;br /&gt;
Ein String ist nichts anderes als ein Array, das aus einzelnen Zeichen (&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;) gebildet wird. Die Ausgabe auf dem Bildschirm funktioniert am einfachsten mittels Strings.&lt;br /&gt;
&lt;br /&gt;
Die Definition eines Strings erfolgt also genauso wie bei Arrays:&lt;br /&gt;
 char string[21];&lt;br /&gt;
&lt;br /&gt;
Nun haben Sie eine String, in dem Sie 21 Zeichen speichern können. Ganz richtig ist das jedoch nicht. C arbeitet mit &amp;quot;null-terminierten Strings&amp;quot;. Das beudeutet, dass die Länge des Strings nicht abgespeichert wird, sondern das Zeichen mit dem ASCII-Wert 0 das Stringende kennzeichnet. Daher auch die Bezeichnung  &amp;quot;null terminiert&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Das letzte Zeichen eines Strings muß daher immer das ASCII-Zeichen Nr. 0 sein. Ist es das nicht, hat der String kein definiertes Ende, und wenn Sie versuchen, ihn durch eine Standard-Funktion auszugeben zu lassen, könnte es eine Weile dauern, bis sich im Speicher zufällig irgendwo eine 0 befindet. Es stehen ihnen daher bei dem Beispiel nur 20 Zeichen zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
===Mehrdimensionale Arrays===&lt;br /&gt;
Manchmal benötigt man mehr als nur ein eindimensionales Array, wie Sie es bisher kennengelernt haben. Auch dies ist kein Problem. In der Deklaration geben Sie einfach mehrere eckige Klammern hintereinander an. Aber Vorsicht: der Speicherplatz ist begrenzt, ein &amp;quot;&amp;lt;tt&amp;gt;char feld[1024][1024]&amp;lt;/tt&amp;gt;&amp;quot; hat die Speicherplatzgrenzen vermutlich bereits weit überschritten, und der Compiler wird einen (bei gewissen Einstellung auch keinen) Fehler liefern.&lt;br /&gt;
Beim Zugriff auf mehrdimensionale Felder müssen auch mehrere Indizes angeben werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  int x,y;&lt;br /&gt;
  int feld[3][5];&lt;br /&gt;
 &lt;br /&gt;
  for (x=0; x&amp;lt;3; x++) &lt;br /&gt;
  {&lt;br /&gt;
     for (y=0; y&amp;lt;5; y++)&lt;br /&gt;
     {&lt;br /&gt;
       printf (&amp;quot;Feldwert x: %d,  y: %d &amp;quot;, x, y);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; feld[x][y]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  for(x=0; x&amp;lt;3; x++) &lt;br /&gt;
     for (y=0; y&amp;lt;5; y++) &lt;br /&gt;
        printf (&amp;quot;Wert: feld[%d][%d] = %d\n&amp;quot;, x, y, feld[x][y]);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 3 mal 5 &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array angelegt. &lt;br /&gt;
Dann werden die Werte eingegeben: zuerst &amp;lt;tt&amp;gt;feld[0][0]&amp;lt;/tt&amp;gt;, dann &amp;lt;tt&amp;gt;feld[0][1]&amp;lt;/tt&amp;gt;, usw. bis &amp;lt;tt&amp;gt;feld[2][4]&amp;lt;/tt&amp;gt;. &lt;br /&gt;
Zum Schluß werden alle Werte noch einmal ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===Strukturen===&lt;br /&gt;
In C können Sie sogenannte &amp;quot;Strukturen&amp;quot; definieren. Dabei handelt es sich um eine Zusammenfassung mehrerer Datentypen zu einem größeren. Im Unterschied zu Feldern können in Strukturen unterschiedliche Datentypen zusammengestellt und gespeichert werden: &lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 struct {{Bezeichner}}&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur 'Person'}}&lt;br /&gt;
 struct Person &lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;lt;tt&amp;gt;struct Person {&amp;lt;/tt&amp;gt;&amp;quot; leitet die Definition der Struktur mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;Person&amp;lt;/tt&amp;gt;&amp;quot; ein. &lt;br /&gt;
Dann werden in dieser Struktur fünf Komponenten definiert: drei Strings und zwei &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. &lt;br /&gt;
mit &amp;lt;tt&amp;gt;}&amp;lt;/tt&amp;gt; wird die Definition abgeschlossen. Sie haben damit einen Datentyp erstellt. Um eine Variable des Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach an&lt;br /&gt;
 struct Person {{Bezeichner}};&lt;br /&gt;
&lt;br /&gt;
Zum Zugriff auf eine Komponente der Struktur gibt man den Namen der Struktur-Variablen an (im folgenden Beispiel also &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;klaus&amp;lt;/tt&amp;gt;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
 {{comment|Definition zweier Struktur-Variablen}}&lt;br /&gt;
 struct Person hubert, klaus;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Zugriff auf Struktur-Komponenten}}&lt;br /&gt;
 hubert.alter = 32;&lt;br /&gt;
 klaus.alter = hubert.alter + 1;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis:'''&lt;br /&gt;
Der eventuell etwas lästige Gebrauch von &amp;lt;tt&amp;gt;struct&amp;lt;/tt&amp;gt; kann schon bei der Definition der Struktur vermieden werden.&lt;br /&gt;
Der Definition ist ein &amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt; voranzustellen. Der Definition folgt dann ein gültiger (und auch eindeutiger) C-Name.&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 typedef struct {{Bezeichner}}&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 } {{Bezeichner}} ;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur '_Mensch' bzw. 'Mensch'}}&lt;br /&gt;
 struct _Mensch&lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 } Mensch;&lt;br /&gt;
&lt;br /&gt;
Jetzt sind folgende Deklarationen identisch:&lt;br /&gt;
 struct _Mensch {{Bezeichner}};&lt;br /&gt;
 Mensch {{Bezeichner}};&lt;br /&gt;
&lt;br /&gt;
Ist der Struktuname nicht notwendig (im Beispiel oben &amp;lt;tt&amp;gt;_Mensch&amp;lt;/tt&amp;gt;), kann auch kürzer geschrieben werden:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 typedef struct &lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 } {{Bezeichner}} ;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur 'Mensch'}}&lt;br /&gt;
 struct &lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 } Mensch;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall ist lediglich die {{Deklaration}} &amp;lt;tt&amp;gt;Mensch {{Bezeichner}};&amp;lt;/tt&amp;gt; gültig.&lt;br /&gt;
&lt;br /&gt;
Der Hinweis gilt sinngemäß auch für die Definition &amp;lt;tt&amp;gt;union&amp;lt;/tt&amp;gt; im nachfolgenden Abschnitt.&lt;br /&gt;
&lt;br /&gt;
===Unions===&lt;br /&gt;
Eine Union wird ganz analog zu einer Struktur deklariert und verwendet. Sie unterscheidet sich von einer Struktur jedoch dadurch, daß ihre Elemente nicht nacheinander im Speicher abgelegt werden, sondern sich überlagern. Auf die in einer Union enthaltenen Daten gibt es also verschiedene Sichten: je nachdem, welche Sicht bzw. Interpretation der Daten man gerne hätte, wählt man den gewünschten Zugriff.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
union Daten &lt;br /&gt;
{&lt;br /&gt;
   int id;&lt;br /&gt;
&lt;br /&gt;
   struct Person u_person;&lt;br /&gt;
&lt;br /&gt;
   struct u_double&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      double wert;&lt;br /&gt;
   };&lt;br /&gt;
&lt;br /&gt;
   struct u_pointer&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      union Daten * p1;&lt;br /&gt;
      union Daten * p2;&lt;br /&gt;
   };&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
union Daten data;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies definiert eine Union mit den vier Zugriffsmöglichkeiten &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_double&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Größe der Union richtet sich dabei nach der grössten Komponente. In diesem Beispiel sind alle Komponenten so angelegt worden, daß sie an erster Stelle ein &amp;lt;tt&amp;gt;int id&amp;lt;/tt&amp;gt; enthalten. In &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; könnte man sich also merken, wie die Daten in der Union zu interpretieren sind. Würde &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; nicht dieses &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; enthalten, so würde sich &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; mit &amp;lt;tt&amp;gt;data.u_person.vname&amp;lt;/tt&amp;gt; überlagern. Ein Ändern der ersten Buchstaben von &amp;lt;tt&amp;gt;vname&amp;lt;/tt&amp;gt; hätte also ein Ändern von &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; zur Folge, und man könnte es nicht mehr als Merker verwenden. Mit diesem Feld überlagert das &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; die &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;-Felder der anderen Sichten, z.B. ist &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; der selbe Zugriff wie auf &amp;lt;tt&amp;gt;data.u_person.id&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein anderes Beispiel ist eine Union, die es ermöglicht, auf die einzelnen Bytes eines &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; zuzugreifen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef union&lt;br /&gt;
{&lt;br /&gt;
   unsigned long  as_long;&lt;br /&gt;
   unsignen short as_short[2];&lt;br /&gt;
   unsignen char  as_byte[4];&lt;br /&gt;
} data32_t;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies überlagert einen &amp;lt;tt&amp;gt;unsigned long&amp;lt;/tt&amp;gt; &amp;amp;ndash; also eine 32-Bit-Zahl &amp;amp;ndash; mit vier Bytes bzw. zwei Shorts.&lt;br /&gt;
 data32_t wert;&lt;br /&gt;
 &lt;br /&gt;
 wert.as_long = 0x12345678;&lt;br /&gt;
 wert.as_byte[0] = 0xab;&lt;br /&gt;
 {{comment|nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform)}}&lt;br /&gt;
&lt;br /&gt;
==Eigene Datentypen==&lt;br /&gt;
&lt;br /&gt;
=Variablen=&lt;br /&gt;
Eine Variable ist ein Synonym (=anderer Name) für eine Speicherstelle in einem Computer. Einfacher gesagt, eine Variable bietet Raum, um Daten wie Zahlen oder Zeichen zu speichern und wieder zu lesen.&lt;br /&gt;
&lt;br /&gt;
==Variablennamen==&lt;br /&gt;
Ein Variablenname kann zusammengesetzt werden aus den Buchstaben &amp;lt;tt&amp;gt;'''A'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''Z'''&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;'''a'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''z'''&amp;lt;/tt&amp;gt;, den Ziffern &amp;lt;tt&amp;gt;'''0'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''9'''&amp;lt;/tt&amp;gt;, sowie dem Sonderzeichen &amp;quot;Unterstrich&amp;quot; (underscore) &amp;lt;tt&amp;gt;'''_'''&amp;lt;/tt&amp;gt;. Dabei darf an erster Stelle keine Ziffer stehen. Die Bezeichner &amp;lt;tt&amp;gt;hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALLO&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALL0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;_123&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_HALLO&amp;lt;/tt&amp;gt; sind also alle gültige und unterschiedliche Variablennamen.&lt;br /&gt;
&lt;br /&gt;
==Anlegen von Variablen==&lt;br /&gt;
Um eine Variable verwenden zu können, muss sie zuerst vereinbart (&amp;quot;erzeugt&amp;quot;) werden. Dies wird auch als &amp;quot;''Definition der Variablen''&amp;quot; bezeichnet und geht so: Schreiben Sie zuerst den Datentyp, dann den Namen der Variablen. Zum Schluß kommt noch der Strichpunkt, wie nach jeder C-Anweisung oder Deklaration. Und nicht vergessen: C unterscheidet zwischen  Groß- und Kleinschreibung! &lt;br /&gt;
 int Zahl1, Zahl2;&lt;br /&gt;
 char Zeichen;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    float gleitZahl;&lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:'''&lt;br /&gt;
In einer Zeile können auch mehrere Variablen gleichen Types vereinbart werden, wenn man ein Komma dazwischen setzt. Variablen können in jedem Block vereinbart werden. Siehe [[#Gültigkeitsbereich|Gültigkeitsbereich]].&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen==&lt;br /&gt;
Man kann einer vereinbarten Variable Werte [[#Zuweisungen|zuweisen]]. Dazu schreibt man zuerst den Variablennamen, ein Gleichheitszeichen &amp;quot;&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;&amp;quot; und anschliessend den zuzuweisenden [[#Ausdrücke|Ausdruck]]. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, zahl2 = 12;&lt;br /&gt;
  char zeichen1 = 'A';&lt;br /&gt;
&lt;br /&gt;
  zahl1 = 52;&lt;br /&gt;
  zeichen1 = zeichen1 + 1; &lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Zuerst werden drei Variablen angelegt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;: wird gleich bei der Vereinbarung der Wert 12 zugewiesen. &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl1 = 52&amp;lt;/tt&amp;gt;: Hier wird der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; der Wert 52 zugewiesen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;: wird um 1 erhöht. Da in der Variablen &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; gespeichert ist, gibt sich ihr neuer Wert aus &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt;. Weil &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; dem Wert 65 entspricht, ist &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt; gleich 66, was dem Wert für &amp;lt;tt&amp;gt;'B'&amp;lt;/tt&amp;gt; entspricht.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei float==&lt;br /&gt;
Das funktioniert genau wie bei normale Zuweisungen. Nachkommastellen werden durch einen Punkt abgegrenzt: &lt;br /&gt;
 floatVariable = 3.14;&lt;br /&gt;
Zusätzlich kann eine Zehnerpotenz angegeben werden:&lt;br /&gt;
 floatVariable2 = -1.234E-6;&lt;br /&gt;
Dadurch wird der erst Wert mit 10&amp;lt;sup&amp;gt;&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;6&amp;lt;/sup&amp;gt; multipliziert, der Wert der Variablen ist also &lt;br /&gt;
:&amp;lt;math&amp;gt;-1{,}234\cdot10^{-6} = -0.000001234&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei logischen Variablen==&lt;br /&gt;
Wie bereits erwähnt, besitzt C keinen logischen Datentyp. Es müssen also &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; dafür genutzt werden. Die Zuweisung entpricht der Standard-Zuweisung. Wird der Wert 0 zugewiesen, dann ist die Variable &amp;quot;unwahr&amp;quot;, ansonsten ist sie &amp;quot;wahr&amp;quot;. &lt;br /&gt;
 intVariable = !0;   /* entspricht &amp;quot;wahr&amp;quot;   */&lt;br /&gt;
 intVariable = 0;    /* entspricht &amp;quot;unwahr&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
==Konstanten==&lt;br /&gt;
Konstanten können als Variable angesehen werden, die nicht beschrieben, sondern nur gelesen werden können. Ein typisches Beispiel dafür ist die Zahl &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; (rund 3,141592654). Niemand würde in der realen Welt versuchen, ihr einen anderen Wert zuzuweisen. Würde man &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; jedoch wie eine normale Variable anlegen, wäre dies ohne weiteres möglich. Um dies zu verhindern, gibt es das Schlüsselwort &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in C:&lt;br /&gt;
 const {{Type}} {{Bezeichner}} = {{Konstante}};  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Wichtig dabei ist, dass man Konstanten nur bei der Vereinbarung einen Wert zuweisen kann. &lt;br /&gt;
Da Konstanten gewöhnlich im gesamten Programm, zumindest einer Quelldatei genutzt werden, definiert man diese allerdings gewöhnlich außerhalb des main-Blockes entweder am Anfang eines Programmes, oder in einer sogenannten Header-Datei, die per &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; eingebunden wird.&lt;br /&gt;
 const float PI = 3.141592;  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Es sei jedoch erwähnt, daß auch einer Konstanten nachträglich ein anderer Wert zugewieden werden kann. Im obigen Beispiel könnte mit&lt;br /&gt;
 * ((float*) &amp;amp;PI) = 2;&lt;br /&gt;
der Wert von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; im Nachhinein verändert werden. Es wird die Adresse von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; genommen und diese Adresse durch den Cast in eine ganz normale &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;-Adresse umgewandelt, über welche der Wert geändert wird. Die sei der Vollständigkeit halber erwähnt.&lt;br /&gt;
&lt;br /&gt;
Je nachdem, an welcher Stelle sich das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; bei einer Pointer-Deklaration befindet, markiert es den Pointer als konstant oder das Objekt, auf das dieser Pointer zeigt. Eine häufige Parameterdeklaration in Ausgabe-Funktionen, die einen String erhalten, ist&lt;br /&gt;
 void foo (const char * str, ...);&lt;br /&gt;
Dadurch ist &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; der Zeiger auf eine Zeichenkette, die innerhalt der Funktion nicht verändert wird bzw. verändert werden darf. Eine Zuweisung wie &amp;lt;tt&amp;gt;*str = 'a'&amp;lt;/tt&amp;gt; ergibt also einen Fehler. &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; selbst kann aber sehr wohl verändert werden, etwa mit &amp;lt;tt&amp;gt;str++&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Soll ausgedrückt werden, daß &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; unveränderlich ist, dann so:&lt;br /&gt;
 void foo (char * const str, ...);&lt;br /&gt;
Jetzt wäre eine Änderung des Strings in Ordnung, etwa durch &amp;lt;tt&amp;gt;str[10] = 'a'&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Um sich zu merken, worauf das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; wirkt, trennt man die Deklaration in Gedanken beim&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf: Steht das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; links vom&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, dann gehört es zum &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, steht es rechts davon, dann gehört es zum Pointer. Natürlich ist es auch denkbar, beides &amp;amp;ndash; also den Zeiger und sein Ziel &amp;amp;ndash; als konstant zu markieren.&lt;br /&gt;
&lt;br /&gt;
==Gültigkeitsbereich==&lt;br /&gt;
In C können mehrere Variablen den gleichen Namen haben, solange eindeutig ist, welche in welchen Block gültig ist. Dabei gelten folgende Regeln: &lt;br /&gt;
&lt;br /&gt;
;Lokale Variablen: sind Variablen, die innerhalb eines Blockes definiert werden. Jede Variable ist nur in dem Block gültig, in dem sie vereinbart wurde, sowie in allen darin enthaltenen Blöcken; es sei denn, in einem Unter-Block wird eine Variable gleichen Namens definiert. Dann bezieht sich in diesem Unter-Block der Bezeichner auf die im Unter-Block angelegte Variable.&lt;br /&gt;
;Globale Variablen: werden ausserhalb jedes Blockes definiert und gelten ab der Stelle, an der sie deklariert werden, siehe auch [[#Deklaration und Definition|Deklaration und Definition]]. Wird jedoch in einem Block eine Variable gleichen Namens angelegt, gilt ab hier bis zum Ende des Blocks nicht mehr die globale Variable, sondern die im Block deklarierte. Das Spiel kann man weiterspielen: wird in einem Unter-Block wieder eine namensgleiche Variable angelegt, gilt diese in dem Unterblock.&lt;br /&gt;
&lt;br /&gt;
==Speicherklassen==&lt;br /&gt;
Jede Variable in C gehört zu einer bestimmten Speicherklasse&lt;br /&gt;
;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;: Lokale Variablen sind in aller Regal sogenannte ''automatische Variablen''. Das bedeutet, sie werden automatisch angelegt, wenn ein Block bzw. eine Funktion betreten wird und danach wieder entfernt. Das Schlüsselwort &amp;quot;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;&amp;quot; wird praktisch nie hingeschrieben, denn lokale Variablen ohne die ausdrückliche Angabe einer Speicherklasse, sind automatisch automatische Variablen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;: Eine externes Symbol ist im ganzen Programm bekannt bzw. in dem Block, in der die Deklaration steht. In unterschiedlichen Blöcken stehende Deklarationen beziehen sich auf das gleiche Symbol! Obgleich das Datum global zugreifbar ist, ist der Gültigkeitsbereich auf den deklarierenden Block begrenzt bzw. auf das deklarierende Quell-Modul, sofern das Symbol ausserhalb jedes Blocks des Moduls deklariert wird. Siehe auch [[#Deklaration und Definition|Deklaration und Definition]].&lt;br /&gt;
;&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;: Die Variable ist im Block gültig bzw. im Quell-Modul (also in der C-Datei, in der die angelegt wurde), wenn sie nicht innerhalb eines Blockes angelegt wurde. Statische Variablen werden nicht in Registern oder im Frame der Funktion angelegt, sondern im selben Speicherbereich, in dem auch die globalen Variablen liegen; Konstanten evtl. auch im Flash. Eine lokale Variable, die als &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; angelegt wird, &amp;quot;überlebt&amp;quot; also das Verlassen des Blocks und hat beim neuerlichen Betreten des Blockes ihren bisherigen Wert. In unterschiedlichen Blöcken angelegte lokale statische Variablen beziehen sich auf unterschiedliche Speicherstellen, genau wie bei lokalen Variablen auch.&lt;br /&gt;
;&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;: Durch diese Speicherklasse wird eine Variable &amp;amp;ndash; falls möglich &amp;amp;ndash; als Registervariable angelegt, also in einem Maschinenregister des Computer/Controllers gehalten. Dadurch kann auf solche Variablen besonders schnell zugegriffen werden. Dieses Schlüsselwort ist bei modernen Compilern weitgehend überflüssig, da die entsprechenden Optimierungen selbständig vorgenommen werden, wenn ausreichend Register vorhanden sind. Auch globale Variablen können als Register angelegt werden, davon ist dem Anfänger aber dringend abzuraten, weil leicht schwerauffindbare Fehler und Abstürze auftreten, wenn man nicht genau weiss, welche Implikationen in einer solchen Definition stecken!&lt;br /&gt;
;&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;: (FIXME: volatile ist ein Qualifier und keine Speicherklasse) Dies ist das genaue Gegenteil von &amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt; und bewirkt, dass die Variable auf keinen Fall in einem Register zwischengespeichert werden darf, sondern immer aus dem RAM gelesen und ins RAM geschrieben werden soll. &amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt; müssen alle ''globalen'' Variablen markiert werden, die in [[ISR | Interrupt-Handlern]] verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Ausdrücke=&lt;br /&gt;
Eine Variable oder eine Konstante in C stellen einfache Ausdrücke dar.&lt;br /&gt;
Diese elementaren Ausdrücke können durch Operatoren miteinander verknüpft werden und so zu neuen, komplexeren Ausdrücken zusammen gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Einfache Beispiele für Ausdrücke sind also z.B.:&lt;br /&gt;
 1&lt;br /&gt;
 a&lt;br /&gt;
 'a'&lt;br /&gt;
 1 + a&lt;br /&gt;
 a == 1&lt;br /&gt;
&lt;br /&gt;
Auch Funktionen können einen Wert zurückliefern und in Ausdrücken weiter benutzt werden.&lt;br /&gt;
In den folgenden Abschnitten wird gezeigt, welche Operatoren in C vorhanden sind,&lt;br /&gt;
und wei man damit neue Ausdrücke aufbauen kann.&lt;br /&gt;
&lt;br /&gt;
==Lvalues==&lt;br /&gt;
&lt;br /&gt;
Ein Lvalue in C ist ein Ausdruck, dem ein anderer Ausdruck zugewiesen werden kann, dessen Wert also durch eine Zuweisung verändert werden kann.&lt;br /&gt;
das 'L' leitet sich ab von 'left' bwz. 'links' und das 'value' bedeutet Wert: Ein Lvalue ist ein Ausdruck, der auf der linken Seite einer Zuweisung stehen darf. Ein Lvalue ist also immer auch ein gültiger Ausdruck, aber die Umkehrung gilt in alles Regel nicht.&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für einen Lvalue ist eine &amp;quot;normale&amp;quot; Variable, die nicht mit &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; als Konstante markiert ist:&lt;br /&gt;
 a = 1;&lt;br /&gt;
Hingegen ist der Ausdruck &amp;lt;tt&amp;gt;a+1&amp;lt;/tt&amp;gt; kein Lvalue, denn eine Zuweisung wie&lt;br /&gt;
 a+1 = 2;&lt;br /&gt;
die mathematisch durchaus sinnvoll ist, erzeugt einen Compilerfehler, der etwa lauten könnte &amp;quot;illegal lvalue in assignment&amp;quot;:&lt;br /&gt;
&amp;quot;ungültiger Wert in Zuweisung&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Andere Beipiele für Lvalues sind die Komponenten von (nicht-konstanten) [[#Strukturen|Strukturen]] und [[#Unions|Unions]], [[#Arrays|Array]]-Elemente und die Dereferenzierungen von Pointern: Die Konstante&amp;amp;nbsp;4 wird durch den Cast in eine Adresse umgewandelt. Über die Dereferenzierung&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; wird an die Adresse&amp;amp;nbsp;4 im Speicher eine&amp;amp;nbsp;3 geschrieben. Ob das erlaubt bzw. sinnvoll ist, ist abhängig von der jeweiligen Architektur.&lt;br /&gt;
 * ((unsigned int *) 4) = 3;&lt;br /&gt;
Hier ist der gesamte &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;-Ausdruck ein Lvalue&lt;br /&gt;
&lt;br /&gt;
==Logische (boolsche) Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp;amp;&amp;amp;amp; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr oder &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; || gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; || ungleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;= b&amp;lt;/tt&amp;gt; || kleiner oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt; b&amp;lt;/tt&amp;gt; || kleiner als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt;= b&amp;lt;/tt&amp;gt; || glösser oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt; b&amp;lt;/tt&amp;gt; || grösser als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; nicht wahr und vice versa&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine interessante Eigenschaft der Operatoren &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;amp;amp;&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; ist, dass&lt;br /&gt;
sie die Auswertung abbrechen, sobald das Ergebnis feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet. Ein oft anzutreffendes Codestück sieht so aus, dabei sei &amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
  if (p &amp;amp;&amp;amp; *p == 5)&lt;br /&gt;
  {&lt;br /&gt;
     {{comment|mach was}}&lt;br /&gt;
  }&lt;br /&gt;
Zuerst wird in der Bedinung geprüft, ob Zeiger&amp;amp;nbsp;&amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; einen Wert ungleich Null hat, also ob er überhaupt einen gültigen Wert enthält. Es ist weit verbreitete Konvention in C, daß Zeiger, die keinen gültigen Wert haben, die Adresse&amp;amp;nbsp;0 enthalten. '''Nur dann, wenn ein Zeiger nicht ein Null-Pointer ist, darf überhaupt ein Zugriff über ihn erfolgen!'''&lt;br /&gt;
&lt;br /&gt;
==Vergleich von Variablen==&lt;br /&gt;
Skalare Variablen (also ganze Zahlen, Gleitkommazahlen, Zeiger) können miteinander verglichen werden. Dazu gibt es die folgenden Operatoren in C: &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; || ist nicht gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;=&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;=&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das Ergebnis der Auswertung ist eine ganze Zahl. Ist die Bedingung erfüllt, dann ist der Wert ungleich&amp;amp;nbsp;0. Ist die Bedingung nicht erfüllt, dann ist ihr Wert gleich&amp;amp;nbsp;0.&lt;br /&gt;
Meistens wird man diese Operatoren in &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Konstrukten finden wie zum Beispiel&lt;br /&gt;
 if (x &amp;gt;= 10)&lt;br /&gt;
    x = 10;&lt;br /&gt;
oder in Abbruchbedingungen von Schleifen, wie sie weiter unten erklärt werden.&lt;br /&gt;
&lt;br /&gt;
Es ist auch möglich, das Ergebnis der Auswertung in einer &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Variablen zu speichern:&lt;br /&gt;
 int i;&lt;br /&gt;
 int z1, z2;&lt;br /&gt;
 &lt;br /&gt;
 z1 = 5;&lt;br /&gt;
 z2 = 100;&lt;br /&gt;
 i = z1 &amp;lt;= z2;  {{comment|Ein Vergleich. i wird &amp;quot;wahr&amp;quot;, da z1 kleinergleich z2 ist}}&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich&amp;amp;nbsp;0 (&amp;quot;wahr&amp;quot;), wenn &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; kleiner oder gleich &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt; ist. Ist &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; jedoch größer als &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt;, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich&amp;amp;nbsp;0 (&amp;quot;unwahr&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
==Arithmetische Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a + b&amp;lt;/tt&amp;gt; || Summe (Addition)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a - b&amp;lt;/tt&amp;gt; || Differenz (Subtraktion)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a * b&amp;lt;/tt&amp;gt; || Produkt (Multiplikation)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a / b&amp;lt;/tt&amp;gt; || Quotient (Division, evtl. mit Rest)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a % b&amp;lt;/tt&amp;gt; || Rest bei Division (Modulo)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;-a&amp;lt;/tt&amp;gt; || Vorzeichenumkehr (Zweierkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Bit-Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp; b&amp;lt;/tt&amp;gt; || bitweise und (and)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || bitweise oder (or)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a ^ b&amp;lt;/tt&amp;gt; || bitweise exclusiv-oder (xor, exor)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;~a&amp;lt;/tt&amp;gt; || jedes Bit in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; invertieren (not, Einerkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Index-Operator bei Arrays==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a[b]&amp;lt;/tt&amp;gt; || das (b+1)ste Element des Feldes a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Folgendes gilt es bei der Verwendung des Indexoperators zu beachten:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; muss ein [[C-Tutorial#Felder | Feld]] oder [[C-Tutorial#Zeiger | Zeiger]] sein&lt;br /&gt;
# &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; muss ein Integer sein oder ein Datentyp, der sich in einen int umwandeln läßt (z.B. char)&lt;br /&gt;
# Es wird nicht geprüft, ob der Index &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; im Feld &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gültig ist!&lt;br /&gt;
# Der erste Index eines Feldes ist immer 0. Daher ''(b+1)stes Element'' in der Beschreibung&lt;br /&gt;
&lt;br /&gt;
==Komponenten-Auswahl bei Structs und Unions==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a.b&amp;lt;/tt&amp;gt; || Element b der [[C-Tutorial#Strukturen | Struktur]] oder des Unions a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adress-Operator und Dereferenzierung==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&amp;amp;amp;a&amp;lt;/tt&amp;gt; || Speicheradresse der Variablen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;*a&amp;lt;/tt&amp;gt; || Wert, der an der Adresse &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a-&amp;amp;gt;b&amp;lt;/tt&amp;gt; || Wert des Elements &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; der Struktur, deren Adresse in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Adressoperator &amp;amp; kann auf Variablen angewendet werden und&lt;br /&gt;
gibt die Startadresse der Variablen im Speicher zurück.&lt;br /&gt;
&lt;br /&gt;
Handelt es sich bei einer Variable um einen [[C-Tutorial#Zeiger | Zeiger]], so enthält&lt;br /&gt;
sie eine Speicheradresse. Um an den '''Wert''' zu gelangen, der&lt;br /&gt;
an dieser Adresse steht, wird der Operator * vorangestellt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
&lt;br /&gt;
 {{comment|x ist eine Integervariable und hat den Wert 5}}&lt;br /&gt;
 int x = 5;&lt;br /&gt;
     &lt;br /&gt;
 {{comment|z ist ein Zeiger auf eine Integer-Variable und enthaelt somit}}&lt;br /&gt;
 {{comment|die Speicheradresse einer Integer-Variablen}}&lt;br /&gt;
 int *z;       &lt;br /&gt;
  &lt;br /&gt;
 {{comment|Verwendung des Adress-Operators: weist an z die Adresse von x zu}}&lt;br /&gt;
 z = &amp;amp;x;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Verwendung der Dereferenzierung}}&lt;br /&gt;
 {{comment|erhoehe den Wert, der bei Adresse z steht, um eins}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|da z auf x zeigt, hat x jetzt den Wert 6}}&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff auf Struktir- und Union-Elemente eine abkürzende Schreibweise möglich:&lt;br /&gt;
&lt;br /&gt;
Statt &lt;br /&gt;
  (*strukturZeiger).element&lt;br /&gt;
kann geschrieben werden&lt;br /&gt;
  strukturZeiger-&amp;gt;element&lt;br /&gt;
Beide Schreibweisen sind absolut gleichbedeutend, die Klammern bei der ersteren sind notwendig.&lt;br /&gt;
&lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
:Bei der Dereferenzierung durch &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; findet keine Prüfung statt, ob der Zeiger auch auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu einer Änderung '''irgendeiner''' Speicherstelle!&lt;br /&gt;
&lt;br /&gt;
 int *z; {{comment|z ist ein Zeiger auf einen int}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.}}&lt;br /&gt;
 {{comment|z enthaelt irgendeine ungueltige Adresse!!}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|&amp;quot;Erhoehe einen Integer _irgendwo_ im Speicher um 1&amp;quot; -&amp;gt; CRASH !!!}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
&lt;br /&gt;
==Cast-Operator==&lt;br /&gt;
&lt;br /&gt;
Der Cast Operator dient dazu, den Datentyp eines Wertes zu ändern. Dafür wird einfach der neue Datentyp in Klammern vor den Wert geschrieben.&lt;br /&gt;
&lt;br /&gt;
Um zum Beispiel aus einem Float ein Integer zu machen:&lt;br /&gt;
 var  = (int) 5.60;&lt;br /&gt;
Dabei wird der Wert aber auch gerundet, und es findet somit ein Informationsverlust statt.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Umwandeln einer ganzen Zahl in eine Adresse:&lt;br /&gt;
 int * addr;&lt;br /&gt;
 addr = (int*) 0x1234;&lt;br /&gt;
Damit ist &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; an Adresse 0x1234.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
Der Cast-Operator selbst führt ''keine Konvertierung'' von Darstellungen durch, etwa die Umwandlung der ganzen Zahl 123 ein den String &amp;lt;tt&amp;gt;&amp;quot;123&amp;quot;&amp;lt;/tt&amp;gt;, der diese Zahl darstellt! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
  int main(int argc, char ** argv)&lt;br /&gt;
  {&lt;br /&gt;
        char text[] = &amp;quot;5.6&amp;quot;;&lt;br /&gt;
        int zahl = (int) text;&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, zahl);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Anfangsadresse des Strings &amp;lt;tt&amp;gt;&amp;quot;5.6&amp;quot;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Komma-Operator==&lt;br /&gt;
Mit einem &amp;lt;tt&amp;gt;,&amp;lt;/tt&amp;gt; können mehrere Ausdrücke nacheinander ausgewertet werden.&lt;br /&gt;
Die Auswertung erfolgt von links nach rechts.&lt;br /&gt;
&lt;br /&gt;
Solche Konstrukte sieht man manchmal in Abfragen wie&lt;br /&gt;
 FILE  *file;&lt;br /&gt;
 if (file = fopen (&amp;quot;foo.exe&amp;quot;, &amp;quot;r&amp;quot;), file != NULL)&lt;br /&gt;
was erst an &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; einen Wert zuweist und den &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Block nur betritt,&lt;br /&gt;
wenn &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; nicht der Nullpointer ist.&lt;br /&gt;
&lt;br /&gt;
Bequem kann das auch in einer [[#for-Schleife|for-Schleife]] sein, wenn man zwei (oder mehr) Laufvariablen hat oder so:&lt;br /&gt;
 for (i=0, j=0; i &amp;lt; 10; i++, j += 2)&lt;br /&gt;
    &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Zuweisung===&lt;br /&gt;
=== ++ und -- ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; stellen einfachere Schreibweisen dar zum Addieren bzw. Subtrahieren von&amp;amp;nbsp;1.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; (Inkrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo++; &lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo + 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; 3}}&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; (Dekrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo--;&lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo - 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; -1}}&lt;br /&gt;
&lt;br /&gt;
Die beiden Operatoren können sowohl in der Präfix-Schreibweise (vor der Variablen) als auch als Postfix-Schreibweise (hinter der Variablen) notiert werden. &lt;br /&gt;
Der Unterschied liegt darin, dass beim Präfix der Wert zuerst neu berechnet wird und die Variable dann verwendet wird. Beim Postfix wird die Variable zuerst verwendet und erst nach Auswertung des Ausdrucks, in dem sie enthalten ist, neu berechnet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 int ausgabe1, ausgabe2, var1 = 10, var2 = 10;&lt;br /&gt;
 ausgabe1 = 3 * ++var1; {{comment|ausgabe1 &amp;amp;#61; 33; var1 &amp;amp;#61; 11;}}&lt;br /&gt;
 ausgabe2 = 3 * var2++; {{comment|ausgabe2 &amp;amp;#61; 30; var2 &amp;amp;#61; 11;}}&lt;br /&gt;
&lt;br /&gt;
Für Zeiger arbeiten diese Operatoren etwas anders, siehe dazu [[#Zeiger-Arithmetik|Zeiger-Arithmetik]].&lt;br /&gt;
&lt;br /&gt;
===Bedingter Ausdruck===&lt;br /&gt;
 ({{Bedingung}}) ? {{Ausdruck|1}} : {{Ausdruck|2}}&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; erfüllt ist, dann wertet dieser Ausdruck aus zu &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt;. Ist er nicht erfüllt, dann wertet er aus zu &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 x = (x &amp;gt;= 3) ? 0 : x+1;&lt;br /&gt;
Startet man &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; mit dem Wert 0, dann nimmt es bei mehrfacher Anwendung dieser Zeile (z.B. in einer Schleife) nacheinander die folgende Werte an:&lt;br /&gt;
:&amp;lt;tt&amp;gt;1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, ...&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&lt;br /&gt;
Wie auch in der Mathematik gibt es auch in C genaue Regeln über die Abarbeitungsreihenfolge (precedence)&lt;br /&gt;
der Operatoren. Dass sich alle C-Compiler genau an diesen ANSI-Vorschlag halten, ist leider nicht sicher.&lt;br /&gt;
Sicher jedoch ist, dass nicht jeder Programmierer diese Regel jederzeit im Kopf hat. &lt;br /&gt;
Daher ist es sinnvoll, Ausdrücke durch runde Klammern eindeutig zu kennzeichnen. &lt;br /&gt;
Nebenbei stören sich Compiler nicht an überflüssigen Klammerpaaren.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Priorität ||Operator||Assoziativität&lt;br /&gt;
|-&lt;br /&gt;
  &lt;br /&gt;
|&amp;lt;tt&amp;gt;15&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ( ) [ ] -&amp;gt; . &amp;lt;/tt&amp;gt;                      ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;14&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;! ~ ++ -- + - (TYP) * &amp;amp; sizeof &amp;lt;/tt&amp;gt;    ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;13&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; * / % (Rechenoperationen) &amp;lt;/tt&amp;gt;         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;12&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; + - (binär) &amp;lt;/tt&amp;gt;                       ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;11&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;&amp;lt; &amp;gt;&amp;gt; &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;10&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt; &amp;lt;= &amp;gt; &amp;gt;= &amp;lt;/tt&amp;gt;                         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 9&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; == != &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 8&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp; (bit-AND-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 7&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ^ (bit-XOR-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 6&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; (bit-OR-Operator)&amp;lt;/tt&amp;gt;   ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 5&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp;&amp;amp; &amp;lt;/tt&amp;gt;                                ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 4&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; &amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 3&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;? : &amp;lt;/tt&amp;gt;                               ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 2&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; = += -= /= *= %= &amp;gt;&amp;gt;= &amp;lt;&amp;lt;= &amp;amp;= &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;= ^= &amp;lt;/tt&amp;gt; ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 1&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; , (Sequenz-Operator) &amp;lt;/tt&amp;gt;              ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Reihenfolge der Auswertung von Funktionsargumenten ist in der ANSI-Spezifikation nicht angegeben und daher compilerabhängig. Von Konstrukten wie&lt;br /&gt;
 {&lt;br /&gt;
    int i=0;&lt;br /&gt;
    func (i++, i++);&lt;br /&gt;
 }&lt;br /&gt;
ist also dringend abzuraten!&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
Eine Kontrollanweisung ist eine Anweisung, die Einfluss auf den Programmfluss hat. Normalerweise werden Anweisungen so ausgeführt, wie sie in der Quelldatei stehen: Von links nach rechts (falls mehrere Anweisungen in einer Zeile stehen sollten, wovon i.A. abzuraten ist) und von oben nach unten. Mit einer Kontrollanweisung kann dieser lineare Programmfluss durchbrochen werden: Die Codeausführung kann kann abhängig von einer Bedingung gemacht werden (&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;), kann wiederholt werden (Schleife) oder an einer anderen Stelle der Funktion fortgesetzt werden (&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==if-Anweisung==&lt;br /&gt;
Mit Hilfe des if-Befehls kann man Codeteile abhängig davon einer Bedingung ausführen lassen:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
oder mit else-Teil&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 if (x &amp;gt; 100)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;gt; 100 ist: Fehlerausgabe}}&lt;br /&gt;
    printf (&amp;quot;x = %d ist zu gross fuer die Berechnung!\n&amp;quot;, x);&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;lt;&amp;amp;#61; 100 ist: Berechne Summe der Zahlen 1...x}}&lt;br /&gt;
    {{comment|Die lokale Variable x2 lebt nur innerhalb dieses alse-Blocks}}&lt;br /&gt;
    int x2 = x;&lt;br /&gt;
 &lt;br /&gt;
    for (x = 0; x2 &amp;gt; 0; x2--)&lt;br /&gt;
       x += x2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Wenn die Bedingung wahr ist (&amp;lt;tt&amp;gt;x &amp;gt; 100&amp;lt;/tt&amp;gt;), dann wird eine Meldung ausgegeben; danach ist die if-Anweisung beendet. Der else-Block wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung nicht erfüllt (&amp;lt;tt&amp;gt;x &amp;amp;le; 100&amp;lt;/tt&amp;gt;), dann wird gleich zum else-Teil gesprungen, und nach dessen Ausführung der if-Befehl beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Ein häufiger Fehler ist es, statt &amp;lt;tt&amp;gt;if (a &amp;amp;#61;&amp;amp;#61; 23)&amp;lt;/tt&amp;gt; etwas wie &amp;lt;tt&amp;gt;if (a &amp;amp;#61; 23)&amp;lt;/tt&amp;gt; zu schreiben. &lt;br /&gt;
Dann wird allerdings nicht geprüft, ob die Variable&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gleich 23 ist, sondern der Variablen&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wird der Wert 23 zugewiesen. Der Ausdruck &amp;lt;tt&amp;gt;a &amp;amp;#61; 23&amp;lt;/tt&amp;gt; hat den Wert&amp;amp;nbsp;23 und ist damit immer &amp;quot;wahr&amp;quot;! Daher ist diese if-Bedingung immer erfüllt!&lt;br /&gt;
&lt;br /&gt;
Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken sondern bestenfalls eine Warnung. Damit ist dieser Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise &amp;lt;tt&amp;gt;if (23 &amp;amp;#61;&amp;amp;#61; a)&amp;lt;/tt&amp;gt;. Wenn man dort anstatt des Vergleichsoperators '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;amp;#61;&amp;lt;/tt&amp;gt;' den Zuweisungsoperator '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;lt;/tt&amp;gt;' verwendet, spuckt der Compiler sehr wohl einen Fehler aus! Ist die Zuweisung jedoch erwünscht und eine Compiler-Warnung lästig, dann wählt man eine Schreibweise wie &amp;lt;tt&amp;gt;if ((a &amp;amp;#61; b))&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;if (a &amp;amp;#61; b, a)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist zu schreiben &amp;lt;tt&amp;gt;if (Bedingung);&amp;lt;/tt&amp;gt; Richtig muss es heissen &amp;quot;&amp;lt;tt&amp;gt;if(Bedingung)&amp;lt;/tt&amp;gt;&amp;quot; Das Semikolon im ersten Fall ist eine leere Anweisung, die im if-Falle ausgeführt wird &amp;amp;ndash; sie bleibt also ohne Resultet. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt; ein auf das Semikolon folgende Anweisung die eigentlich zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören soll wird immer ausgeführt, die sie nicht mehr zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; dazu gehört.&lt;br /&gt;
}}&lt;br /&gt;
Bei verschachtelten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Konstrukten gehört ein &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zu letzten &amp;quot;freien&amp;quot; &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;. Soll in einer &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Folge das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zum ersten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören, dann ist das so zu hinzuschreiben:&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Ohne die geschweiften Klammern um das zweite &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehörte das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; dort hinzu.&lt;br /&gt;
&lt;br /&gt;
==switch-Anweisung==&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
&lt;br /&gt;
 switch ({{Ausdruck|}}) &lt;br /&gt;
 {&lt;br /&gt;
     case konstante1:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
    &lt;br /&gt;
     case konstante2:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 &lt;br /&gt;
     {{comment|weitere case-Marken}}&lt;br /&gt;
 &lt;br /&gt;
     default:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 } {{comment|Ende von switch}} &lt;br /&gt;
&lt;br /&gt;
Der Ausdruck muss ein skalarer Typ sein, er wird in die nächste ganze Zahl gewandelt und mit den Werten hinter den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Marken verglichen. Bei einer Übereinstimmung werden alle Befehle ab dem zutreffenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; ausgeführt. Stimmt der Ausdruck mit keinem der Werte überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt falls vorhanden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der nachfolgenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;- und des &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitts werden ausgeführt, wenn die Anweisungen des &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitts nicht mit dem Befehl &amp;lt;tt&amp;gt;break;&amp;lt;/tt&amp;gt; beendet werden!&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es dürfen beliebig viele &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitte angegeben werden, pro Vergleichswert jedoch nur einer.&lt;br /&gt;
Der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ist optional. Die Reihenfolge, in der &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt; angegeben werden, ist unerheblich.&lt;br /&gt;
&lt;br /&gt;
==Schleifen==&lt;br /&gt;
Um Anweisungen mehrmals hintereinander auszuführen, benötigt man Schleifen. Diese führen Anweisungen aus, bis oder solange Bedingungen erfüllt sind.&amp;lt;br&amp;gt; &lt;br /&gt;
Wichtig ist also, ob die Bedingung '''vor''' oder '''nach''' den Schleifen-Anweisungen geprüft wird. &lt;br /&gt;
&lt;br /&gt;
===while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 while ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Die while-Schleife wird solange durchlaufen, wie die Bedingung erfüllt ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Die Anweisung kann natürlich auch ein Block sein, der aus mehreren Deklarationen und Anweisungen besteht. &lt;br /&gt;
&lt;br /&gt;
 int zahl1 = 0;&lt;br /&gt;
 int zahl2 = 1;&lt;br /&gt;
 &lt;br /&gt;
 while (zahl1 &amp;lt; 3)&lt;br /&gt;
 {&lt;br /&gt;
    zahl1 = zahl1 + 1;&lt;br /&gt;
    zahl2 = zahl2 * 2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife drei mal durchlaufen. Zu Beginn des vierten Durchlaufs ist die Bedingung nicht mehr erfüllt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
&lt;br /&gt;
===do-while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
Die do-while-Schleife wird auf jeden Fall einmal durchlaufen und dann solange wiederholt, wie die Bedingung erfüllt ist.&lt;br /&gt;
 int i = 2;&lt;br /&gt;
 &lt;br /&gt;
 do &lt;br /&gt;
 {&lt;br /&gt;
     i = i*i;   {{comment|i quadrieren}}&lt;br /&gt;
     printf (&amp;quot;i = %d\n&amp;quot;, i);&lt;br /&gt;
 }&lt;br /&gt;
 while (i &amp;lt; 20);&lt;br /&gt;
&lt;br /&gt;
Die Schleife wird durchlaufen und wiederholt, solange &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; kleiner als 20 ist. Es werden also nacheinander die Werte 2, 4 und 16 ausgegeben. Nach der Schleife hat&amp;amp;nbsp;&amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; den Wert 256.&lt;br /&gt;
&lt;br /&gt;
===for-Schleife===&lt;br /&gt;
'''Syntax:''' &lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Bei den Ausdrücken wird es sich um einen Ausdrücke mit Nebeneffekt handeln wie etwa &amp;lt;tt&amp;gt;i=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;i=i+2&amp;lt;/tt&amp;gt;. Es werden folgende Aktionen ausgeführt:&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# falls die Bedingung wahr ist, dann führe &amp;lt;tt&amp;gt;Anweisung&amp;lt;/tt&amp;gt; aus.&lt;br /&gt;
# falls die Bedingung unwahr ist, dann sprinte zu 7 (Ende).&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# gehe zu 2&lt;br /&gt;
# nächste Anweisung nach der for-Schleife&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int lauf, summe;&lt;br /&gt;
 &lt;br /&gt;
 for (lauf=1, summe=0; lauf &amp;lt;= 10; lauf += 2) &lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel ist &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; ein [[#Komma-Operator|Komma-Ausdruck]], der zwei Anweisungen kombiniert und daher sogar zwei Nebeneffente hat: er setzt &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;1 und &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;0.&lt;br /&gt;
&lt;br /&gt;
Das Äquivalent als while-Schleife:&lt;br /&gt;
&lt;br /&gt;
 int lauf  = 1;                 {{comment|Anfangswerte}}&lt;br /&gt;
 int summe = 0;&lt;br /&gt;
 &lt;br /&gt;
 while (lauf &amp;lt;= 10)             {{comment|Bedingung}}&lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
    lauf  += 2;                 {{comment|Inkrement}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; in jedem Schleifendurchlauf um die Laufvariable &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; erhöht. Da &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nacheinander die ungeraden Werte von&amp;amp;nbsp;1 bis&amp;amp;nbsp;10 annimmt, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von&amp;amp;nbsp;1 bis kleinergleich 10 gespeichert, also der Wert&amp;amp;nbsp;25. &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; hat nach der Schleife den Wert&amp;amp;nbsp;11.&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf = 1&amp;lt;/tt&amp;gt; bedeutet, dass der Variablen &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; vor dem ersten Schleifendurchlauf der Wert&amp;amp;nbsp;1 zugewiesen wird. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf &amp;lt;= 10&amp;lt;/tt&amp;gt; ist die Schleifenbedingung; ist sie nicht erfüllt, wird die Schleife beendet. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf += 2&amp;lt;/tt&amp;gt; bedeutet, dass &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nach jedem Durchlauf um&amp;amp;nbsp;2 erhöht wird.&lt;br /&gt;
&lt;br /&gt;
===continue-Anweisung===&lt;br /&gt;
Innerhalb einer Schleife darf die &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die nachfolgenden Anweisungen übersprungen werden und mit dem nächsten Schleifendurchlauf fortgesetzt wird &amp;amp;ndash; vorausgesetzt die Schleifenbedingung ist noch erfüllt. Ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; etc. stehen, wenn dieses innerhalb einer Schleife steht.&lt;br /&gt;
&lt;br /&gt;
==break-Anweisung==&lt;br /&gt;
Innerhalb einer Schleife oder eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; darf die &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die Schleifen-/Switch-Anweisung sofort verlassen wird und das Programm dahinter weiter macht. Bei mehrfach geschachtelten Schleifen wird nur die innere verlassen. Ein &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; stehen, wenn dieses innerhalb einer Schleife/Switch-Anweisung steht.&lt;br /&gt;
&lt;br /&gt;
==goto-Anweisung==&lt;br /&gt;
&lt;br /&gt;
Innerhalb ein und derselben Funktion kann mit &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; an eine andere Stelle gesprungen werden. Dazu gibt man hinter dem &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einen Bezeichner an, der dadurch als Label fungiert:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 goto {{Bezeichner}};&lt;br /&gt;
Die Bezeichner selbst steht irgendwo in der Funktion und wird dadurch zur Sprungmarke (Label), daß er von einem Doppelpunkt (und mindestens einer C-Anweisung, die auch leer sein darf) gefolgt wird.&lt;br /&gt;
&lt;br /&gt;
Das Beispiel durchsucht das 2-dimensionale &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array &amp;lt;tt&amp;gt;feld&amp;lt;/tt&amp;gt; mit den &amp;lt;tt&amp;gt;SIZE_X &amp;amp;times; SIZE_Y&amp;lt;/tt&amp;gt; Werten nach dem Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;. Wird er gefunden, dann wird die 2-fach geschachtelte Suchschleife verlassen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int x, y;&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y; y++)&lt;br /&gt;
       if (feld[x][y] == 0)&lt;br /&gt;
          goto done;&lt;br /&gt;
 {{Label|done:}};&lt;br /&gt;
&lt;br /&gt;
Der folgende Code hat die gleiche Funktion, arbeitet jedoch ohne &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int x, y;&lt;br /&gt;
 int found = 0; {{comment|FALSE}}&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X &amp;amp;&amp;amp; !found; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y &amp;amp;&amp;amp; !found; y++)&lt;br /&gt;
       found = (0 == feld[x][y]);&lt;br /&gt;
Der Nachteil der &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-losen Variante ist, daß man eine Variable, die merkt, ob das Suchziel gefunden wurde, mitschleppen und in ''jedem'' Schleifendurchlauf abtesten muss. Dies bedeutet einen höheren Programmier- und Laufzeitaufwand und ist nicht so klar formuliert wie das &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-Beispiel.&lt;br /&gt;
&lt;br /&gt;
Gleichwohl sei angemerkt, daß die Verwendung von &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einem gewissen Dogmatismus unterliegt, der sich wie folgt subsummieren liesse:&lt;br /&gt;
:''goto ist böse und sollte keinesfalls verwendet werden! Wer es dennoch tut, offenbart dadurch seinen schlechten Geschmach sowie mangelhafte C-Kenntnis.'' &amp;lt;div align=&amp;quot;right&amp;quot;&amp;gt;http://www.roboternetz.de/phpBB2/images/smiles/icon_wink.gif&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Funktionen=&lt;br /&gt;
Stellen Dir vor, Du hast eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben &amp;amp;ndash; was Dich Zeit beim Erstellen des Programms und Speicherplatz im ausführbaren Programm kostet &amp;amp;ndash; kannst Du den Code-Abschnitt in eine Funktion schreiben und diese von jeder Stelle des Programms aus verwenden. Die Hauptgründe, um Funktionen zu verwenden, sind:&lt;br /&gt;
;Wiederverwendung von Code: Mehrfach verwendete Codestücke müssen nicht mehrfach implementiert werden. Oft unterscheiden sich die Codesequenzen nur in Kleinigkeiten, die man der Funktion über Parameter mitteilen kann.&lt;br /&gt;
;Übersichtlichkeit: Ein gut gegliedertes C-Programm implementiert klar umrissene Aufgaben in einer Funktion, auch wenn diese Funktion nur einmal im Code aufgerufen wird! Dadurch bleibt der Code um die Aufrufstelle besser verständlich, und man kann auf verschiedenen &amp;quot;Ebenen&amp;quot; denken. Eine Funktion wie &amp;quot;Datei öffnen&amp;quot; kann recht komplex sein. Auf höherer Ebene interessieren die Innereien nicht mehr, man möchte sich um andere Dinge kümmern und will den Code an der Stelle garnicht sehen...&lt;br /&gt;
;Rekursive Funktionen: Eine Funktion kann sich auch selbst aufrufen. In dem Falle nennt man die Funktion ''rekursiv''. Zwar lässt sich das, was eine rekursive Funktion tut, auch mit anderen Mitteln formulieren, die keine rekursiven Funktionen brauchen, aber oft ist der rekursive Weg knackiger und klarer formulierbar als eine nicht-rekursiven Ansatz, auch wenn es etwas mehr Resourcen verbraucht.&lt;br /&gt;
;Modulare Programmierung: Funktionen können anhand ihres Aufgabenbereichs auf verschiedene C-Quellen &amp;amp;ndash; sogenannte ''Module'' &amp;amp;ndash; verteilt werden. Funktionen, die etwas mit dem USB-Bus anstellen, werden in einem anderen Modul sein als mathematische Funktionen. Dies erhöht die Übersichtlichkeit und vereinfacht die Entwicklung im Team.&lt;br /&gt;
;Bibliotheken: Standard-Funktionen wie das hier oft auftauchende &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; sind in Bibliotheken gespeichert. Wenn das eigene Programm übersetzt wird, dann müssen nicht mehr alle Standard-Funktionen übersetzt werden, sondern werden nur noch aus der Bibliothek gelesen und ihr Code zum Programm dazugelinkt. Die Bibliotheks-Funktionen wurden schon zu einem früheren Zeitpunkt compiliert und liegen in dieser compilerten Form in der Bibliothek. Das spart mächtig Entwicklungszeit. Man kann auch selbst solche Bibliotheken erstellen und in diversen Projekten wiederverwenden.&lt;br /&gt;
;Generische Programmierung: In C ist es möglich, einer Funktion eine andere Funktion zu übergeben. (Damit ist nicht gemeint, ihr deren ''Rückgabewert'' zu übergeben (was auch ginge), sondern ''die Funktion selbst'' wird als Parameter übergeben und kann aufgerufen werden.) Ein typisches Beispiel dafür sind Sortieralgorithmen. Einem Sortieralgorithmus kann es egal sein, ''was'' er sortiert. Er muss lediglich wissen, ''wie'' er das Zeug zu sortieren hat: aufsteigend, absteigend, als Zahl, in lexikographischer Ordnung, nach der Quersumme, Körper nach Oberfläche, Durchmesser, Gewicht oder Volumen... Diese Vergleichsfunktion, die für zwei Objekte entscheidet, welches davon &amp;quot;kleiner&amp;quot; ist, kann man dem Sortierer übergeben. Will er zwei Werte vergleichen, dann muss er nur die Vergleichsfunktion aufrufen, ohne zu wissen, was diese tut. Damit kann der Sortieralgorithmus unanhängig von den Objekten gehalten werden, mit denen er hantieren soll.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Definition==&lt;br /&gt;
&lt;br /&gt;
In der ''Definition'' der Funktion wird gesagt, welche Werte sie liefern kann, wie sie heisst (Bezeichner) und wieviele und welche Parameter sie hat. Danach folgt ihre Implementierung:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}} ({{Parameterliste}})&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 &lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
Für Funktionen, die keinen Wert zurückliefern, gibt es den speziellen Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der besagt, daß die Funktion nichts zurückgibt. Die einfachste denkbare Funktion ist eine solch void-Funktion. Sie bekommt keine Parameter, gibt nicht zurück und ihr Body ist leer:&lt;br /&gt;
 void dummy()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==return-Anweisung==&lt;br /&gt;
An jeder Stelle des Programmflusses einer Funktion kann diese mit &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; beendet werden.&lt;br /&gt;
&lt;br /&gt;
'''bei void-Funktionen:'''&lt;br /&gt;
 return;&lt;br /&gt;
'''Funktionen mit Rückgabe-Wert:'''&lt;br /&gt;
 return {{Ausdruck|}};&lt;br /&gt;
Die zweite Variante gibt an, welcher Wert zurückgegeben wird.&lt;br /&gt;
 int main (int argc, char * argv[])&lt;br /&gt;
 {&lt;br /&gt;
    if (argc &amp;lt; 2)&lt;br /&gt;
       return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
Falls die letzte Anweisung einer void-Funktion ein &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; ist, kann es auch weggelassen werden wie oben bei der Funktion &amp;lt;tt&amp;gt;dummy&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Aufruf==&lt;br /&gt;
Um die Funktion aufzurufen gibt man ihren Namen an, gefolgt von den durch Komma getrennten Argumenten in runden Klammern wie im Beispiel unten das&lt;br /&gt;
 quadrat (5) &lt;br /&gt;
Da &amp;lt;tt&amp;gt;quadrat&amp;lt;/tt&amp;gt; einen Wert liefert, kann man damit weiter rechnen wie mit einem normalen Ausdruck:&lt;br /&gt;
 if (quadrat (a) + quadrat (b) == quadrat (c))&lt;br /&gt;
    c = quadrat (quadrat (a)); {{comment|c &amp;amp;#61; a hoch 4}}&lt;br /&gt;
&lt;br /&gt;
;Ein Hinweis am Rande: Der Name einer Funktion ohne die beiden runden Klammern ist der Pointer/Zeiger auf ihren Anfang. Damit kann ein Funktionsname überall dort verwendet werden, wo Pointer/Zeiger zulässig sind. Insbesondere kann er als Argument einer weiteren Funktion dienen. Siehe auch [[#Zeiger auf Funktionen|Zeiger auf Funktionen]].&lt;br /&gt;
&lt;br /&gt;
==Rekursive Funktionen==&lt;br /&gt;
Eine Funktion die sich selbst &amp;amp;ndash; möglicheweise auch über andere Zwischenfunktionen &amp;amp;ndash; wieder selbst aufruft, wird als ''rekursive Funktion'' bezeichnet. In der Definition ist nichts besonderes zu beachten. Ist die Verschachtelungstiefe im laufenden Programm zu tief, dann gibt das natürlich Probleme, aber das gilt bei tief verschachtelten 'normalen' Funktionen abenso...&lt;br /&gt;
&lt;br /&gt;
Das Beispiel berechnet den Größten Gemeinsamen Teiler zweier Zahlen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int ggT (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
     if (0 == a)&lt;br /&gt;
        return b;&lt;br /&gt;
 &lt;br /&gt;
    return ggT (b % a, a);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Ein komplettes kleines Programm:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int quadrat (int param1)&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  zahl = param1 * param1;&lt;br /&gt;
  return zahl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl, ergebnis;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Bitte Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = quadrat (zahl);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, zahl, ergebnis);&lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, 5, quadrat (5));&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur ausserhalb von Blöcken. Geschachtelte Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen beim Aufruf die Klammern angeben werden:&lt;br /&gt;
 dummy();&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Prototypen==&lt;br /&gt;
Wie oben erwähnt, kann ein Unterprogramm an jeder beliebigen Stelle im Programm stehen. Damit ist jedoch eine Bedingung verknüpft: Das Unterprogramm muß in der Datei oberhalb des ersten Aufrufes definiert worden sein. Wenn Sie ein Unterprogramm in Zeile 10 zum ersten mal aufrufen, müssen Sie die Deklaration davor erledigt haben. Verstanden?&lt;br /&gt;
Um dies zu erreichen, gibt es zwei Möglichkeiten: &lt;br /&gt;
&lt;br /&gt;
Entweder Sie schreiben alle Unterprogramme vor &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; in die Datei. Dies muß jedoch wiederum so geschehen, dass Funktionen zum Zeitpunkt ihres Aufrufes bereits bekannt sind! &lt;br /&gt;
Wo dies nicht möglich ist (z.B. sich gegenseitig aufrufende Unterprogramme), oder wenn Sie das stört, müssen Sie Prototypen verwenden. &lt;br /&gt;
Wie definiert man nun Prototypen? Sie kopieren einfach die erste Zeile des Unterprogrammes (z.B. &amp;quot;&amp;lt;tt&amp;gt;void ausgeben (int zahl)&amp;lt;/tt&amp;gt;&amp;quot;), fügen einen Strichpunkt&amp;amp;nbsp;&amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;an und fügen es an einer geeigneten Stelle ein (so, dass alle Aufrufe später in der Datei kommen). &lt;br /&gt;
Solche Definitionen stehen gewöhnlich am Anfang der Quelldatei oder in einer Header-Datei, die eingebunden wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl);  /* Der Prototyp */&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
   ausgeben (12);&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl)   /* Die eigentliche Prozedur */&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Ausgabe: %d\n&amp;quot;, zahl);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Parameterübergabe==&lt;br /&gt;
&lt;br /&gt;
Alle Werte, die an Prozeduren und Funktionen übergeben werden, werden grundsätzlich '''kopiert'''.&lt;br /&gt;
Das hat folgende Auswirkungen:&lt;br /&gt;
&lt;br /&gt;
# Änderungen an einem Parameter in einer Funktion erscheinen ''nicht'' beim Aufrufer!&lt;br /&gt;
# Möchte man, dass eine Funktion einen Wert trotzdem dauerhaft ändern soll, so muss die Adresse des Wertes via [[#Zeiger|Zeiger]] übergeben werden.&lt;br /&gt;
# Werden [[#Strukturen|Strukturen]] übergeben, so wird von ihnen eine Kopie erstellt, was bei großen Strukturen viel Zeit und Arbeitsspeicher kostet. Deshalb wird häufig nur die Adresse von Strukturen übergeben, da die Adresse viel schneller und platzsparender als die Struktur selbst kopiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele:'''&lt;br /&gt;
 void erhoehe (int x)&lt;br /&gt;
 {&lt;br /&gt;
    x = x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe(a);&lt;br /&gt;
    {{comment|a ist immer noch 0}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Beim Aufruf von &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; wird eine Kopie des Wertes von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; (im Beispiel also 0) erstellt und der Prozedur als Parameter &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; übergeben. Weil dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat dies keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|erhoehe den Wert an der Adresse x um eins}}&lt;br /&gt;
    *x = *x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe (&amp;amp;a);&lt;br /&gt;
    {{comment|a ist jetzt 1}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Jetzt wird im Hauptprogramm mittels [[#Adress-Operator und Dereferenzierung|Adress-Operator]] &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; die Speicheradresse von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; bestimmt. Dann wird eine ''Kopie der Adresse'' an das Unterprogramm &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; übergeben. Jetzt kennt das Unterprogramm die&lt;br /&gt;
Adresse des Originals &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und kann direkt mit dem Inhalts-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&lt;br /&gt;
'''Besonderheit bei Feldern'''&lt;br /&gt;
&lt;br /&gt;
Bei der Übergabe von [[#Felder|Feldern]] gibt es eine Besonderheit. Schreibt man nämlich den Namen eines Feldes, so ist das nichts anderes als die '''Speicheradresse des ersten Elements'''.&lt;br /&gt;
Bei der Übergabe eines Feldes wird also eine Kopie der Startadresse übergeben. Somit kann das Unterprogramm auf den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 void erhoehe (int x[])&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
   int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
   erhoehe (a);&lt;br /&gt;
   {{comment|a hat jetzt folgenden Inhalte: 11, 23, 35}}&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Dass die Übergabe einer Adresse erfolgt, sieht man an folgendem Beispiel, das von der Funktionsweise '''absolut identisch''' mit dem vorhergehenden ist:&lt;br /&gt;
&lt;br /&gt;
 {{comment|Bei Parametern gibt es keinen Unterschied zwischen Zeiger und Feld}}&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
    int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
    erhoehe (a);&lt;br /&gt;
 &lt;br /&gt;
    {{comment|a hat jetzt folgenden Inhalt: 11, 23, 35}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
Die Länge des Feldes wird nicht automatisch übergeben. Dafür ist ggf. ein zusätzlicher Parameter notwendig.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Inlining==&lt;br /&gt;
&lt;br /&gt;
In C gibt es die Möglichkeit, eine Funktion als ''inline''-Funktion zu definieren.&lt;br /&gt;
Für eine inline-Funktion wird üblicher Weise kein Code erzeugt, der beim Aufruf der Funktion angesprungen wird, sondern an der Stelle des Aufrufs wird eine Kopie der inline-Funktion eingefügt.&lt;br /&gt;
&lt;br /&gt;
Vom Effekt her ist eine inline-Funktion also ähnlich wie ein Makro. Allerdings wird das Einfügen des Codes nicht vom Präprozessor übernommen, sondern vom eigentlichen C-Compiler. Damit der Compiler in der Lage ist, eine Funktion zu inlinen, muss ihm der Code zur Verfügung stehen, da er ansonsten natürlich keinen Code einfügen kann.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort ist ''inline'':&lt;br /&gt;
 {{ccomment|Deklariere ''increment'' als inline-Funktion}}&lt;br /&gt;
 static inline int increment (int);&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Implementierung von ''increment''}}&lt;br /&gt;
 int increment (int i)&lt;br /&gt;
 {&lt;br /&gt;
    return i+1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Aufruf von ''increment'' wie eine normale Funktion}}&lt;br /&gt;
 int foo (int n)&lt;br /&gt;
 {&lt;br /&gt;
    if (n &amp;lt; MAX_INT)&lt;br /&gt;
       n = increment (n);&lt;br /&gt;
 &lt;br /&gt;
    return n;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Inline-Funktionen werden verwendet, wenn der Funktionscode recht klein ist und ein Funktionsaufruf schon so aufwändig ist wie das, was die Funktion zu erledigen hat. Im Beispiel wird der gleiche Code erzeugt, wie wenn &amp;lt;tt&amp;gt;n = n + 1&amp;lt;/tt&amp;gt; im Aufrufer stünde, was deutlich schneller ist als ein Funktionsaufruf mit Register-Sicherung, Parameterübergabe, Wertrückgabe, etc.&lt;br /&gt;
&lt;br /&gt;
==Variable Argumentanzahl==&lt;br /&gt;
&lt;br /&gt;
'''Baustelle'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdarg.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
static void uput_va (const char * fmt, va_list args /*, uint8_t pstr_p*/)&lt;br /&gt;
{&lt;br /&gt;
	while (1)&lt;br /&gt;
	{&lt;br /&gt;
		char c = (pstr_p) &lt;br /&gt;
			? pgm_read_byte (fmt++)&lt;br /&gt;
			: *fmt++;&lt;br /&gt;
		&lt;br /&gt;
		if ('\0' == c)&lt;br /&gt;
			return;&lt;br /&gt;
		&lt;br /&gt;
		if ('%' == c)&lt;br /&gt;
		{&lt;br /&gt;
			c = (pstr_p) &lt;br /&gt;
				? pgm_read_byte (fmt++)&lt;br /&gt;
				: *fmt++;&lt;br /&gt;
				&lt;br /&gt;
			if ('%' == c)	putc (c);&lt;br /&gt;
			if ('c' == c)	putc (va_arg (args, int));&lt;br /&gt;
			&lt;br /&gt;
			&lt;br /&gt;
			if ('s' == c)	{ fn = uputs   ;       ; goto _dispatch; }&lt;br /&gt;
			continue;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		if ('\n' == c)	&lt;br /&gt;
			putc ('\r');&lt;br /&gt;
		&lt;br /&gt;
		putc (c);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 void uput_PSTR (const char * fmt, ...)&lt;br /&gt;
 {&lt;br /&gt;
     va_list vlist;&lt;br /&gt;
     va_start (vlist, fmt);&lt;br /&gt;
     uput_va (fmt, vlist);&lt;br /&gt;
     va_end (vlist);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
== Funktionen indirekt aufrufen ==&lt;br /&gt;
Siehe [[#Zeiger auf Funktionen|Zeiger auf Funktionen]]&lt;br /&gt;
&lt;br /&gt;
=Zeiger II=&lt;br /&gt;
&lt;br /&gt;
Zeiger haben wir bereits weiter oben kennen gelernt. Zeiger sind ein zentrales Konzept in C und sollen hier etwas eingehender behandelt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger-Arithmetik==&lt;br /&gt;
In C kann man den Wert eines Zeigers verändern. Betrachten wir dazu die Funktion &amp;lt;tt&amp;gt;suche_0&amp;lt;/tt&amp;gt;, die einen Zeiger auf einen &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; erhält. Die Funktion soll ab der gegebenen Adresse nach dem ersten long-Wert suchen, der 0 ist, und dessen Adresse zurückgeben:&lt;br /&gt;
 long * suche_0 (long * addr)&lt;br /&gt;
 {&lt;br /&gt;
    while (*addr != 0)&lt;br /&gt;
       addr = addr + 1;&lt;br /&gt;
 &lt;br /&gt;
    return addr;&lt;br /&gt;
 }&lt;br /&gt;
In der Bedingung der while-Schleife wird der Inhalt an der Speicherstelle &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf 0 getestet. Ist der Wert 0, dann wird die Schleife beendet und die Adresse zurückgeliefert. Ist der Wert ungleich 0, dann wird &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf den nächste long gesetzt, &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; also um 4 Bytes weitergezählt. &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ist ja ein Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, und ein &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; ist 4 Bytes lang.&lt;br /&gt;
&lt;br /&gt;
Die Bedeutung von&lt;br /&gt;
 address + n&lt;br /&gt;
ist also, die Adresse um das &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;-fache der Größe des Typs, auf den &amp;lt;tt&amp;gt;address&amp;lt;/tt&amp;gt; zeigt, zu erhöhen. Dabei ist &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; eine ganze Zahl und darf auch negativ sein.&lt;br /&gt;
&lt;br /&gt;
Hier noch ein Beispiel einer Funktion, die nach einer Person mit einer bestimmten ID sucht (für die Definition von &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; siehe [[#Strukturen|Strukturen]]). Der Parameter &amp;lt;tt&amp;gt;person&amp;lt;/tt&amp;gt; ist dabei ein Array von Strukturen. Eine Person mit der gesuchten ID muss existieren, ansonsten hat die Suchfunktion kein definiertes Verhalten.&lt;br /&gt;
 {{comment|Sucht nach einer Person mit der ID person_id}}&lt;br /&gt;
 struct Person * &lt;br /&gt;
 suche_person_id (struct Person * person, int person_id)&lt;br /&gt;
 {&lt;br /&gt;
    while (person-&amp;gt;id != person_id)&lt;br /&gt;
       person++;&lt;br /&gt;
 &lt;br /&gt;
    return person;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:1em; padding:1em; border:solid 2px #FF0040;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- Vorlage:FarbigerRahmen funzt hier net --&amp;gt;&lt;br /&gt;
Beachte, daß es nicht sinnvoll ist, zwei Zeiger zu addieren oder zu multiplizieren. Ausserdem ist das &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt; der Zeiger-Arithmetik nicht kommutativ. Eine Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, der an Adresse 1 im Speicher zeigt, wird man schreiben als&lt;br /&gt;
 (long *) 1&lt;br /&gt;
Addiert man darauf eine ganze Zahl, dann haben die entstehenden Ausdrücke unterschiedliche Werte:&lt;br /&gt;
 (long *) 1 + 2    {{comment|zeigt zu Adresse 9}}&lt;br /&gt;
 (long *) 2 + 1    {{comment|zeigt zu Adresse 6}}&lt;br /&gt;
 (long *) (1 + 2)  {{comment|zeigt zu Adresse 3}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==void-Pointer==&lt;br /&gt;
Eine besondere Art von Zeiger ist der void-Pointer&lt;br /&gt;
 void * addr;&lt;br /&gt;
Ein void-Pointer ist ein &amp;quot;Zeiger auf irgendwas&amp;quot;, dementsprechend kann er nicht dereferenziert werden, Anwenden von &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf einen solchen Zeiger gibt also einen Fehler. Ausserdem ist es nicht möglich, mit einem void-Pointer Zeigerarithmetik zu machen, weil er nicht auf eine definierte Art von Objekt zeigt. Der Vorteil eines void-Pointers ist, daß er jede Art von Zeiger aufnehmen kann.&lt;br /&gt;
&lt;br /&gt;
Dazu betrachten wir die Funktion &amp;lt;tt&amp;gt;send_buf&amp;lt;/tt&amp;gt;, die eine Adresse erhält und ab dieser Adresse &amp;lt;tt&amp;gt;num&amp;lt;/tt&amp;gt; Bytes versenden soll. Wir könnten die Funktion so schreiben:&lt;br /&gt;
 void send_buf (unsigned char * buf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   ...&lt;br /&gt;
Das ist jedoch hässlich, wenn wir damit etwas anderes verschicken wollen als &amp;lt;tt&amp;gt; unsigned char&amp;lt;/tt&amp;gt;, etwa eine Struktur wie &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; (vom Typ &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;):&lt;br /&gt;
 send_buf ((unsigned char*) &amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
Ohne den Cast der Adresse von &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; zu einem Zeiger auf &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt; bekommt man eine Warnung oder gar einen Compilerfehler.&lt;br /&gt;
Dieses Zeiger gecaste ist mühsam und hässlich, es muss bei jedem Aufruf der Funktion explizit hingeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Besser ist es, den ersten Parameter der Funktion als void-Pointer zu definieren und den Cast in der Funktion zu machen:&lt;br /&gt;
 void send_buf (void * vbuf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   unsigned char *buf = (unsigned char*) vbuf;&lt;br /&gt;
   ...&lt;br /&gt;
Durch den Cast in der Funktion kann auf den Inhalt des Zeigers zugegriffen werden. Man muss nur festlegen, ''wie'' man zugreifen will, nämlich als &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Der Aufruf kann jetzt ohne Pointer-Cast erfolgen: &lt;br /&gt;
 send_buf (&amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
&lt;br /&gt;
==Null-Pointer==&lt;br /&gt;
==Zeiger als Parameter==&lt;br /&gt;
Wenn Sie ein Unterprogramm aufrufen, können Sie diesem Parameter übergeben, aber keine Werte zurückgekommen (außer den Funktionswert bei Funktionen). Dies hat einen guten Grund: beim Aufruf werden nicht die aufgerufenen Parameter benutzt, sondern es werden deren Werte in neue Variablen kopiert. Diese Variablen werden am Ende des Unterprogrammes &amp;quot;zerstört&amp;quot;, ohne ihre Werte an die aufrufenden Parameter zu übergeben. Jede Veränderung eines Parameters hat daher keine Auswirkung auf den Parameter.&lt;br /&gt;
&lt;br /&gt;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der C-Compiler legt dann immer noch Kopien an. In dieser Kopie steht aber kein Wert, sondern die Adresse einer Varaiblen. Und auf diese können Sie dann zugreifen. Denken Sie nur an &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; &amp;amp;ndash; da übergeben Sie ja auch die Adresse einer Variablen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void erhoehe (int *zeiger)&lt;br /&gt;
{&lt;br /&gt;
  *zeiger = 1 + *zeiger;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  erhoehe (&amp;amp;zahl);&lt;br /&gt;
  printf (&amp;quot;\nDie erhoehte Zahl lautet: %d\n&amp;quot;, zahl);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Zeiger auf Funktionen==&lt;br /&gt;
&lt;br /&gt;
Stell dir vor, du willst einen Sortieralgorithmus wie Bubble-Sort oder Quick-Sort oder wie sie alle heissen implementieren. Für den Sortieralgorithmus ist eigentlich egal, ''was'' er zu sortieren hat. Ihm ist es egal, ob er Zahlen aufwärts sortieren soll oder Strings in lexikographischer Reihenfolge, ob Objekte nach Größe oder Gewicht, Personen nach Alter oder Adressen nach Postleitzahl. Das einzige, was der Algorithmus wissen muss, ist ''wie'' er zwei Objekte zu vergleichen hat und wann eines davon &amp;quot;kleiner&amp;quot; (im Sinne der Ordnung, nach der sortiert werden soll) ist. &lt;br /&gt;
&lt;br /&gt;
Eine einfache Sortierfunktion, die nur zwei Zahlen sortiert, könnte man also so schreiben: &lt;br /&gt;
 {{comment|Sortiert ein Array von 2 int-Zeigern nach den Inhalten &lt;br /&gt;
  * an den Zeiger-Adressen}}&lt;br /&gt;
 void sort2_a (int * p[])&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Inhalte vergleichen...}}&lt;br /&gt;
    if (*p[0] &amp;gt; *p[1])&lt;br /&gt;
    {&lt;br /&gt;
       {{comment|... und ggf. Dreieckstausch der 2 Zeiger}}&lt;br /&gt;
       int * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Die Funktion bekommt ein Array der Länge&amp;amp;nbsp;2. In diesem Array stehen Zeiger auf die zu sortierenden Zahlen. Ein Array mit Zeigern zu verwenden und nicht ein Array von &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; scheint recht umständlich, und das ist es hier auch. Aber stell dir vor, du willst Strukturen wie &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; sortieren. Das Tauschen zweier Strukturen würde bedeuten, ihre kompletten Inhalte umzukopieren! Das wäre sehr aufwändig. Viel einfacher ist das Kopieren, wenn nur die Adressen zu kopieren sind.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; könnte dann so aussehen:&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void sortiere (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|p[] enthält 2 int-Zeiger: die Adressen von a und b}}&lt;br /&gt;
    int * p[2];&lt;br /&gt;
    p[0] = &amp;amp;a; &lt;br /&gt;
    p[1] = &amp;amp;b; &lt;br /&gt;
 &lt;br /&gt;
    {{comment|Sortiere die Zeiger}} &lt;br /&gt;
    sort2_a (p);&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Sortiert: %d, %d\n&amp;quot;, *p[0], *p[1]);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Für den nächsten Schritt überlegen wir uns, daß das Array in &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; ebensogut void-Pointer enthalten kann. Die einzige Stelle, an der wir auf die endgültigen int-Objekte zugreifen, ist der Vergleich. Diesen Vergleich lagern wir in die Funktion &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; aus:&lt;br /&gt;
 {{comment|Bekommt zwei void-Pointer und vergleicht die Inhalte.&lt;br /&gt;
  * Liefert 0 bei Gleichheit,&lt;br /&gt;
  * -1 wenn der erste Wert kleiner ist als der zweite und&lt;br /&gt;
  * 1  wenn der erste Wert größer ist als der zweite}}&lt;br /&gt;
 int compare_int (void * p0, void * p1)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Um über die Zeiger zugreifen zu können müssen wir diese&lt;br /&gt;
     * erst zu int-Zeigern casten}}&lt;br /&gt;
    int a0 = * (int*) p0;&lt;br /&gt;
    int a1 = * (int*) p1;&lt;br /&gt;
 &lt;br /&gt;
    if (a0 &amp;gt; a1)  return  1;&lt;br /&gt;
    if (a0 &amp;lt; a1)  return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void sort2_b (void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare_int (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Ein Aufruf von &amp;lt;tt&amp;gt;sort2_b&amp;lt;/tt&amp;gt; sieht dann genauso aus wie ein Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt definieren wir uns den neuen Datentyp &amp;lt;tt&amp;gt;comparator_t&amp;lt;/tt&amp;gt;. Dieser ist ein Zeiger auf eine Funktion, die zwei void-Pointer erhält und einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; zurückliefert, also analog arbeitet zu &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; von oben. &lt;br /&gt;
&lt;br /&gt;
Unsere Sortierfunktion bekommt nun neben dem zu sortierenden Zeiger-Array auch eine Vergleichsfunktion &amp;lt;tt&amp;gt;compare&amp;lt;/tt&amp;gt; mitgeliefert, die sie aufruft, wenn sie zwei Objekte vergleichen will&lt;br /&gt;
 {{comment|comparator_t sind Zeiger auf Funktionen, die 2 void-Pointer&lt;br /&gt;
  * erhalten und einen int zurückliefern}}&lt;br /&gt;
 typedef int (*comparator_t) (void*, void*);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Der Sortierer bekommt einen Funktionszeiger auf den Vergleicher.&lt;br /&gt;
  * Der Aufruf vom compare geht so als wäre es eine &amp;quot;normale&amp;quot; Funktion&lt;br /&gt;
  * (ist es im Endeffekt ja auch)}}&lt;br /&gt;
 void sort2_c (comparator_t compare, void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Bei einem Aufruf von &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; muss man dann einen Komparator mit angeben. In einem Beispiel analog zu &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; von oben ist das:&lt;br /&gt;
 sort2_c (compare_int, p);&lt;br /&gt;
Um zwei Strings lexikographisch zu sortieren nehmen wie die Standard-Funktion &amp;lt;tt&amp;gt;strcmp&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void foo()&lt;br /&gt;
 {&lt;br /&gt;
    char * worte[] = { &amp;quot;Wort1&amp;quot;, &amp;quot;Wort2&amp;quot; };&lt;br /&gt;
 &lt;br /&gt;
    sort2_c ((comparator_t) strcmp, (void**) worte);&lt;br /&gt;
 }&lt;br /&gt;
Die Casts sind hier erforderlich. Alternativ könnte man &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; mit reinen void-Pointern versorgen und diese dann dort umcasten.&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
&lt;br /&gt;
Die Syntax zur Definition/Deklaration von Funktionszeigern ist etwas verzwackt. Zur Verdeutlichung ein paar Beispiele. Dabei legt das linke &amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt; jeweils den Return-Typ fest.&lt;br /&gt;
 {{comment|definiert einen neuen Funktionszeiger-Typ}}&lt;br /&gt;
 typedef {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert eine Variable als Funktionszeiger}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert ein Array von Funktionszeigern (mit Initializer)}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}[]) ({{type}}, {{type}}, ...) = { wert1, wert2, ... };&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer}}&lt;br /&gt;
 ({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer und ruft die Funktion auf}}&lt;br /&gt;
 (({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}) (arg1, arg2, ...);&lt;br /&gt;
&lt;br /&gt;
=Standard-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==String-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===strcpy===&lt;br /&gt;
Bei vielen Compilern können sie einem String nicht direkt einen Wert (Text) zuweisen. Dazu müssen Sie dann die Prozedur strcpy() benutzen. Diese erwartet als ersten Parameter den Namen einer String-Variablen (ohne eckige Klammern) und als zweiten Parameter den eines (anderen) Strings. Letzterer kann auch ein in doppelten Hochkommas (&amp;quot;) eingeschlossener Text sein. Die Funktion fügt am Ende automatisch ein 0-Zeichen ein. Um diese Funktion nutzen zu können, müssen Sie die Datei string.h includieren! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri1[21], eingabe[21];&lt;br /&gt;
&lt;br /&gt;
  strcpy (stri1, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Der 1. String: %s\n&amp;quot;, stri1);&lt;br /&gt;
  printf (&amp;quot;Bitte geben Sie maximal 20 Zeichen ein: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%s&amp;quot;, eingabe);&lt;br /&gt;
  strcpy (stri1, eingabe);&lt;br /&gt;
  printf (&amp;quot;\n%s = %s&amp;quot;, stri1, eingabe);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis:''' &lt;br /&gt;
Da ein String, wie jedes Feld, eigentlich ein Zeiger ist, dürfen Sie kein &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; bei &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; angeben!&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
Es werden zwei gleich große Strings definiert: &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;eingabe&amp;lt;/tt&amp;gt;, mit je 20 &amp;quot;nutzbaren&amp;quot; Zeichen. &lt;br /&gt;
In &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; wird die Zeichenkette &amp;lt;tt&amp;gt;&amp;quot;hallo&amp;quot;&amp;lt;/tt&amp;gt; hineinkopiert. Das 0-Zeichen am Ende wird automatisch angefügt. &lt;br /&gt;
Der String wird ausgegeben. Als neues &amp;quot;Sonderzeichen&amp;quot; kommt &amp;lt;tt&amp;gt;%s&amp;lt;/tt&amp;gt; ins Spiel. Es hat die gleiche Aufgabe wie &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt;, nur für Strings. &lt;br /&gt;
Sie werden gebeten, eine String einzugeben. &lt;br /&gt;
Dieser String wird danach in die Variable &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; kopiert. &lt;br /&gt;
Beide Strings, die ja nun die gleiche Zeichenkette enthalten, werden ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===strlen===&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;strlen&amp;lt;/tt&amp;gt;, die als Parameter eine String-Variable erwartet, liefert die Länge diese Strings zurück. Sie werden jetzt vermutlich sagen: &amp;quot;Das ist doch klar, wie lang der String ist. Ich habe es ja bei der Deklaratin angegeben&amp;quot;. Das stimmt schon, aber denken Sie noch einmal an die null-terminierten Strings. Das 0-Zeichen steht am Ende des Strings (am Ende der gültigen Zeichenfolge), aber nicht unbedingt am Ende des reservierten Speicherplatzes. Haben Sie eine Variable &amp;quot;char Variable[21];&amp;quot;, und ihr den Wert &amp;quot;hallo&amp;quot; zugewiesen, dann steht das null-Zeichen in Variable[5]. Der &amp;quot;gültige&amp;quot; String ist also 5 Zeichen (0-4) lang. Und genau das (5) würde strlen zurück liefern. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri[21];&lt;br /&gt;
  &lt;br /&gt;
  strcpy (stri, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
  printf (&amp;quot;Der String ist %d Zeichen lang&amp;quot;, strlen (stri));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird vor allem gebraucht, wenn Sie direkt auf den String zugreifen, mittels &amp;lt;tt&amp;gt;stri[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;stri[1]&amp;lt;/tt&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
==Ein- und Ausgabe-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===Bildschirm-Ausgabe===&lt;br /&gt;
Bisher war das Tutorial trotz aller Beispiele reine Theorie. Sie konnten zwar Programme schreiben, aber die Funktion nicht testen. Hier lernen Sie nun, wie Sie etwas am Bildschirm ausgeben.&lt;br /&gt;
&lt;br /&gt;
Die dazu notwendige Funktione heisst &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (das '&amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt;' ist kein Fehler!). Diese Anweisung gibt die ihr übergebenen Parameter auf das Standard-Ausgabegerät aus, in der Regel also auf den Bildschirm. Sie kann beliebig viele Parameter übernehmen. Es müssen jedoch Standard-Datentypen (z.B. &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;...) sein! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
    int zahl1 = 12;&lt;br /&gt;
    char zeichen1 = 'A';&lt;br /&gt;
    &lt;br /&gt;
    printf (&amp;quot;Das ist Text, und er wird als solcher ausgegeben. \n&amp;quot;);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zahl1' ist: %d \n&amp;quot;, zahl1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %c \n&amp;quot;, zeichen1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %d \n&amp;quot;, zeichen1);&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt Text aus. Das Zeichen am Ende (&amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;) bedeutet &amp;quot;New Line&amp;quot;, es bewegt den Cursor an den Anfang der nächsten Zeile. &lt;br /&gt;
&lt;br /&gt;
Der zweite &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt auch Text aus, am Ende befindet sich wieder das &amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;, um einen Zeilenvorschub zu erreichen. Das &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; wird vom Compiler durch den ersten Parameter ersetzt, der nach dem Text angegeben wird. In diesem Fall wird &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; also durch den Wert der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ersetzt. Das &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; im &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; bedeutet &amp;quot;Dezimalzahl&amp;quot;, der Computer gibt also eine ganze Zahl aus. &lt;br /&gt;
&lt;br /&gt;
In der dritten Ausgabe wird ein Zeichen ausgegeben. Diesmal bedeutet &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; &amp;quot;char&amp;quot; (Zeichen). Es wird also &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; durch ein &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt; ersetzt, denn die Variable &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; wird als Character interpretiert. &lt;br /&gt;
&lt;br /&gt;
Die letzte Ausgabe interpretiert den Inhalt von &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; als Zahl, und gibt dager den ASCII-Wert von &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, also 65 aus. Das ist ein typisches Beispiel für das mögliche unterschiedliche Interpretieren einer  Variablen!&lt;br /&gt;
&lt;br /&gt;
===Tastatur-Eingabe===&lt;br /&gt;
&lt;br /&gt;
Um ein &amp;quot;gscheites&amp;quot; Programm schreiben zu können, muß man wissen, wie der Benutzer über die Tastatur Befehle eingeben kann. Die dafür notwendigen Funktionen stelle ich in diesem Kapitel vor.&lt;br /&gt;
Die wichtigste Funktion ist &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt;. Er liest Daten von der Tastatur. Die Syntax entspricht derer von &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int  zahl1;&lt;br /&gt;
char zeichen1;&lt;br /&gt;
&lt;br /&gt;
printf (&amp;quot;Bitte geben Sie eine Zahl ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl1);&lt;br /&gt;
printf (&amp;quot;Geben Sie einen Zeichen ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%c&amp;quot;, &amp;amp;zeichen1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Programm gibt eine Eingabeaufforderung aus. Dann erwartet es vom Benutzer, daß er eine Zahl eingibt, die mit [ENTER] bestätigt wird. Dieser Wert wird in &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; abgespeichert. Danach erfolgt wiederum eine Aufforderung zur Eingabe, diesmal eines einzelnen Zeichens. Dieses kann man nun eingeben und ebenfalls mit [ENTER] bestätigen.&lt;br /&gt;
&lt;br /&gt;
Macht man keine dem Datentyp der erwarteten Variable entsprechende Eingabe, dann bricht das Programm mit einer Fehlermeldung ab (wenn man z.B. &amp;quot;1_T2&amp;quot; eingibt, wenn eine Zahl erwartet wird)!&lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; vor den Parametern ist notwendig. Warum, das erfahren Sie im Kapitel &amp;quot;Unterprogramme&amp;quot;. Für die Profis eine Kurz-Erklärung: Das Unterprogramm &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; bekommt zwar einen Wert übergeben, kann aber keinen zurückliefern (&amp;quot;call by value&amp;quot;). Daher wird kein Wert, sondern ein Zeiger auf eine Variable übergeben. Mit dem &amp;amp; Zeichen bekommen Sie die Adresse einer Variablen (&amp;quot;call by reference&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=Parameter von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;=&lt;br /&gt;
Das Unterprogramm &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; kann, wie jede andere Funktion, Parameter besitzen. Doch keine selbst gewählten, sondern nur bestimmte. Doch warum braucht main Parameter? Denken Sie einmal an alle Betriebssystembefehle:&lt;br /&gt;
&amp;lt;tt&amp;gt;dir *.exe &amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;copy *.* a:&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;ls -la &amp;lt;/tt&amp;gt;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen!&lt;br /&gt;
&lt;br /&gt;
=Kurzreferenz=&lt;br /&gt;
==Syntax-Bausteine==&lt;br /&gt;
&lt;br /&gt;
Die Erklärung des Aufbaus von C-Befehlen erfolgt neben einfachen Beispielen auch durch ihren prinzipellen Aufbau. In diesen Syntax-Beschreibungen finden sich immer wieder die gleichen Bausteine, die hier näher erklärt werden sollen. Falls Dir solch ein Syntax-Baustein begegnet, kannst Du ihn anklicken und kommst dann zu seiner Erläuterung. &lt;br /&gt;
&lt;br /&gt;
In den Beispielen selbst gehören auch die spitzen Klammern zu dem Baustein (was daran zu erkennen ist, daß auch die Klammern eingefärbt sind). Die Klammern dürfen in einem konkreten C-Programm daher nicht eingetippt werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bezeichner&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Bezeichner in C dienen dazu, Variablen zu identifizieren und ihnen sprechende Namen zu geben, um die Quelle lesbarer zu machen. Man braucht Bezeichner auch, um selbstdefinierte Datentypen zu benennen und zum Benennen von Struct- und Union-Komponenten sowie als Namen für Funktionen und Sprungmarken (Labels).&lt;br /&gt;
&lt;br /&gt;
Bezeichner dürfen aus den Kleinbuchstaben &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;z&amp;lt;/tt&amp;gt;, den Großbuchstaben &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;Z&amp;lt;/tt&amp;gt;, dem Unterstrich&amp;amp;nbsp;&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt; und den Ziffern &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;9&amp;lt;/tt&amp;gt; aufgebaut werden, wobei an erster Stelle jedoch keine Ziffer stehen darf.&lt;br /&gt;
&lt;br /&gt;
Es wird zwischen Groß- und Kleinschreibung unterschieden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Ausdruck in C ist ein Konstrukt, das einen Wert hat. Ob dieser Wert eine ganze Zahl ist, eine Kommazahl oder ein Zeiger, etc. ist dabei egal. Die einfachsten Ausdrücke sind Konstanten wie&lt;br /&gt;
 2&lt;br /&gt;
oder Variablen wie&lt;br /&gt;
 ein_zahl&lt;br /&gt;
Mehrere Ausdrücke können durch [[#Liste der Operatoren|Operatoren]] zu komplexeren Ausdrücken kombiniert werden, etwa&lt;br /&gt;
 eine_zahl + andere_zahl == 2&lt;br /&gt;
oder &lt;br /&gt;
 eine_zahl = 2&lt;br /&gt;
Letzterer hat den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; und den Nebeneffekt, daß er diesen Wert an &amp;lt;tt&amp;gt;eine_zahl&amp;lt;/tt&amp;gt; zuweist.&lt;br /&gt;
&lt;br /&gt;
Auch der Aufruf einer Funktion, die einen Rückgabewert liefert, ist ein Ausdruck:&lt;br /&gt;
 sin (1.2)&lt;br /&gt;
und kann zum Aufbau komplexerer Ausdrüche verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bedingung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Bedingung ist ein Ausdruck, bei der nur interessiert, ob dieser zu&amp;amp;nbsp;0 (unwahr) auswertet oder zu ungleich&amp;amp;nbsp;0 (wahr). Solche Ausdrücke findet man in if-Anweisungen, in Schleifenbedingungen und bedingten Zuweisungen&lt;br /&gt;
 (ein_wert &amp;lt; 2) || (ein_wert &amp;gt; 40)&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Lvalue ist ein Ausdruck, dem etwas zugewiesen werden kann. Der Name ''Lvalue'' kommt aus dem Englischen. Das ''L'' steht abkürzend für left. Ein Lvalue ist damit ein Ausdruck, der auf der linken Seite eine Zuweisung in C stehen darf. Das &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; in den folgenden Beispiel-Ausdrücken muss ein Lvalue sein:&lt;br /&gt;
 x = y-1&lt;br /&gt;
&lt;br /&gt;
 x++&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Konstante&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Konstante ist ein Ausdruck, dessen Wert dem Compiler bekannt ist. Beispiele für Konstanten sind etwa&lt;br /&gt;
 7&lt;br /&gt;
 'B'&lt;br /&gt;
 -13.98e12&lt;br /&gt;
 1+(2*3)&lt;br /&gt;
und die Werte von [[#Enum|Enum]]s. &lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; aus dem folgenden Codestück definiert jedoch keine Konstante in diesem Sinne&lt;br /&gt;
 const double Pi = 3.14159256;&lt;br /&gt;
denn in einem anderen Quellmodul könnte durch die Deklaration&lt;br /&gt;
 extern const double Pi;&lt;br /&gt;
das Symbol &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; bekannt sein, ohne daß sein Wert bekannt ist!&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Adresse&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Adresse ist ein Ausdruck, der einen Speicherort (physikalisch oder virtuell) halten kann. Adressen erhält man dadurch, daß man einem Bezeichner den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt;voranstellt, Adressen durch Arithmetik berechnet oder Zahlen zu Adressen castet. Folgende Ausdrücke sind Adressen (eine sinnvolle Deklaration der auftretenden Variablen vorausgesetzt)&lt;br /&gt;
 &amp;amp; eine_zahl&lt;br /&gt;
 &amp;amp; ein_array[10]&lt;br /&gt;
 &amp;amp; ein_struct&lt;br /&gt;
 &amp;amp; ein_struct.komponente&lt;br /&gt;
 (int *) 0x1234&lt;br /&gt;
 (int *) eine_zahl&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Deklaration&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Anweisungen sind gewissermassen die Atome (oder Moleküle?), aus denen ein C-Programm besteht. Jedes C-Programm ist eine Abfolge von Deklarationen und Anweisungen. Einfache Anweisungen erhält man, in dem man einen Ausdruck nimmt und einen Strichpunkt dahinter schreibt:&lt;br /&gt;
 {{Ausdruck|}};&lt;br /&gt;
wie in&lt;br /&gt;
 x = x+1;&lt;br /&gt;
&lt;br /&gt;
Andere Anweisungen sind die unten aufgeführten Schleifen und die if- sowie die switch-Anweisung.&lt;br /&gt;
&lt;br /&gt;
Mehrere Deklarationen und Anweisungen können zu einem Block zusammengefasst werden. Dieser Block stellt dann wieder eine einzelne Anweisung dar und kann genau so gehandhabt werden!&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
In diesem Sinne ist auch z.B. die Syntax der if-Anweisung zu verstehen&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
besagt, daß der abhängig ausgeführte Code eine einzelne Anweisung sein darf oder eben ein kompletter Block oder die Verschachtelung mehrerer Blöcke etc.&lt;br /&gt;
&lt;br /&gt;
Eine Anweisung kann auch &amp;quot;leer&amp;quot; sein, also nichts tun. Diese Anweisungen sind der leere Block&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
und der Strichpunkt&lt;br /&gt;
 ;&lt;br /&gt;
die man gelegentlich in Schleifen findet:&lt;br /&gt;
 while (!timeout())&lt;br /&gt;
    {}&lt;br /&gt;
oder hinter Sprungmarken, die sonst direkt vor einer schliessenden Blockklammer stünden:&lt;br /&gt;
 {&lt;br /&gt;
    ...&lt;br /&gt;
    goto ein_label;&lt;br /&gt;
    ...&lt;br /&gt;
    {{Label|ein_label}}:;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Nicht jede Anweisung ist an jeder Stelle eines C-Programms erlaubt, so darf ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; nut innerhalb einer Schleife stehen. Gleiches gilt für &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;, das aber auch innerhalb eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; vorkommen darf.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Dies steht für einen Datentyp. Es kann ein elementarer Typ sein wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;, ein Zeiger darauf wie &amp;lt;tt&amp;gt;char*&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;void*&amp;lt;/tt&amp;gt;, und auch Qualifier enthalten wie das &amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt; im Typ &amp;lt;tt&amp;gt;unsigned long long&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Zu den Typen gehören auch zusammengesetzte Datentypen wie Strukturen und Unions, mit &amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt; selbst definierte Typen und natürlich Zeiger darauf, wie aus dem Abschnitt [[#Datentypen|Datentypen]]:&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person *&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;data32_t&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;&lt;br /&gt;
und Zeiger auf Funktionen.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Parameterliste&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
Die Parameterliste bei einer Funktionsdefinition gibt an, wieviel Übergabeparameter sie bekommt, wie diese heissen und welchen Typs diese sind. Der prinzipielle Aufbau ist&lt;br /&gt;
 {{Type}} {{Bezeichner}}, {{Type}} {{Bezeichner}}, ...&lt;br /&gt;
Falls die Funktion keine Parameter hat, dann ist die Parameterliste leer.&lt;br /&gt;
&lt;br /&gt;
Hier als Beispiel die zweiparametrige Funktion &amp;lt;tt&amp;gt;produkt&amp;lt;/tt&amp;gt;. Der erste Parameter heisst&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und ist ein &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;. Der zweite namens&amp;amp;nbsp;&amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; ist vom Typ &amp;quot;Zeiger auf double&amp;quot;, der Inhalt &amp;lt;tt&amp;gt;*b&amp;lt;/tt&amp;gt; ist also auch ein double.&lt;br /&gt;
&lt;br /&gt;
'''Definition der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b)&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
In älteren C-Quellen findet man noch eine andere Syntax für die Deklaration der Parameter, die aber heute praktisch nicht mehr verwendet wird:&lt;br /&gt;
'''alte Definition der Funktion:'''&lt;br /&gt;
 double produkt (a, b)&lt;br /&gt;
 double a, *b;&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Um die Funktion bekannt zu machen, verwendet man eine Deklaration bzw. den Prototypen, der dem Compiler nur mitteilt, welche Parameter die Funktion bekommt und was sie zurückliefert. Für den Aufruf der Funktion muss der Compiler nur diesen Prototyp kennen, ''was'' die Funktion im Endeffekt macht und wie sie implementiert wurde ist egal, sie wird als BlackBox angesehen.&lt;br /&gt;
&lt;br /&gt;
'''Prototyp der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b);&lt;br /&gt;
Hier dürfen die Bezeichner auch fehlen:&lt;br /&gt;
 double produkt (double, double*);&lt;br /&gt;
&lt;br /&gt;
==if==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==if-else==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==for==&lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Eine for-Schleife entspricht folgendem Konstrukt. Dabei sind die drei Ausdrücke optional. Fehlt die Bedingung, dann wird diese als &amp;quot;wahr&amp;quot; angenommen. Die beiden anderen Ausdrücke wird man als Ausdrücke mit Nebeneffekt wählen wie z.B. &amp;lt;tt&amp;gt;x=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;x=x-2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
 {&lt;br /&gt;
    {{Ausdruck|1}};&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_loop}}:&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
    else&lt;br /&gt;
       goto _break;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_continue}}:&lt;br /&gt;
    {{Ausdruck|2}};&lt;br /&gt;
    goto _loop;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_break}}:;&lt;br /&gt;
 }&lt;br /&gt;
Die Labels &amp;lt;tt&amp;gt;_break&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_continue&amp;lt;/tt&amp;gt; entsprechen den Sprungzielen einer &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Anweisung innerhalb von &amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==do-while==&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while  ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
==while==&lt;br /&gt;
 while  ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==switch==&lt;br /&gt;
 switch  ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    ...&lt;br /&gt;
  &lt;br /&gt;
    default:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#break-Anweisung|&amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Konstanten|&amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#continue-Anweisung|&amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#do-while-Schleife|&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Enum|&amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#for-Schleife|&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#goto-Anweisung|&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Inlining|&amp;lt;tt&amp;gt;inline&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#return-Anweisung|&amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Liste der Operatoren|sizeof]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Strukturen|&amp;lt;tt&amp;gt;struct&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Eigene Datentypen|&amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Unions|&amp;lt;tt&amp;gt;union&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#while-Schleife|&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund2}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Arithmetische Operatoren&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Dies sind die &amp;quot;normalen&amp;quot; arithmetischen Operationen, wie man sie aus der Schule kennt. Man kann damit und allen anderen Operatoren auch komplexere Ausdrücke aufbauen. Die Prioritäten sind so, wie man sie kennt, also &amp;quot;Punktrechnung vor Strichrechnung&amp;quot;. Will man dies ändern, dann mit den runden Klammern:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;1+2*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 7&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(1+2)*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 9&amp;lt;br/&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}}&amp;amp;nbsp;+&amp;amp;nbsp;{{Ausdruck|}}&amp;lt;/tt&amp;gt; || Addition&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} - {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Subtraktion&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} * {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Multiplikation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} / {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Division&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} % {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Rest der Division (modulo)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;- {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Vorzeichenumkehr, Zweier-Komplement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Logische Operatoren und Vergleiche&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die logischen und die vergleichenden Operatoren liefern als Ergebnis den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (wahr) oder einen Wert ungleich&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (falsch, um genau zu sein den Wert &amp;lt;tt&amp;gt;!0&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Man kann das Ergebnis zwar einer Variablen zuweisen, in aller Regel wird man solche Ausdrücke jedoch in Bedingungen zu &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder in Abbruch-Bedingungen von Schleifen finden.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;&amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches AND: beides wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124;&amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches OR: mind. eines ist wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;! {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches NOT (0 &amp;amp;harr; ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} == {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} != {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist nicht gleich&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bitweise Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~ {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise NOT (Einser-Komplement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise AND&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise ODER&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} ^ {{Ausdruck|}}&amp;lt;/tt&amp;gt; ||bitweise XOR&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Shift-Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;lt;&amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Bits nach links schieben&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;gt;&amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Schieben nach rechts schieben&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Typen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Ein Cast in C kann dazu verwendet werden, den Typ eines Ausdruckes zu ändern oder den Ausdruck mit einer bestimmten Genauigkeit zu berechnen. Wird z.B. eine Berechnung standardmässig in 16 Bit ausgeführt, dann kann man mit einem Cast &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(long) &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
ausdrücken, daß die Berechnung in 32 Bit erfolgen soll. Des weiteren kann man Zeiger und ganze Zahlen und Gleitkommazahlen ineinander umwandeln.&lt;br /&gt;
&lt;br /&gt;
Casts können ''nicht'' dazu verwendet werden, um z.B. eine Zahl in einen String zu konvertieren, der diese Zahl darstellt! Dafür gibt es spezielle Funktionen wie &amp;lt;tt&amp;gt;itoa&amp;lt;/tt&amp;gt;!&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Type}}) {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Cast, Typwandlung&lt;br /&gt;
|-&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;| &amp;lt;tt&amp;gt;sizeof ({{Type}})&amp;lt;/tt&amp;gt; || Eine Konstante, deren Wert die Größe (in Bytes) des Typs ist. &amp;lt;tt&amp;gt;sizeof&amp;lt;/tt&amp;gt; ist auch auf Objekte anwendbar wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, Arrays bekannter Größe, Strukturen und Unions,  Array-, Struktur- und Union-Komponenten, Pointer, etc. Beispiel:&amp;lt;br/&amp;gt;&lt;br /&gt;
 int i, sum=0, array[] = { 1, -13, 4, 0, sizeof (int*) };&lt;br /&gt;
 &lt;br /&gt;
 for (i=0; i&amp;lt; sizeof (array) / sizeof (array[0]); i++)&lt;br /&gt;
    sum += array[i];&lt;br /&gt;
Alle Elemente des Arrays werden aufaddiert, ohne daß deren Anzahl explizit in der Schleife genannt ist.&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zeiger und Adressen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;* {{Adresse}}&amp;lt;/tt&amp;gt; || der Inhalt an Adresse&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp; {{Lvalue}}&amp;lt;/tt&amp;gt; || Adresse von&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Strukturen, Unions, Arrays&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Struct&amp;gt;}}.{{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Zeiger-auf-Struct&amp;gt;}} -&amp;gt; {{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union, deren Adresse man hat&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Adresse}}&amp;amp;#91;{{Ausdruck|}}&amp;amp;#93;&amp;lt;/tt&amp;gt; || Array-Element&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bedingte Auswertung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Bedingung}}) ? {{Ausdruck|}} : {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Auswahl des Wertes abhängig von der Bedingung&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zuweisung und Operatoren mit Nebeneffekt&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die Unterschiede der post- und pre-Varianten der Increment/Decrement kommen in Konstrukten wie &amp;lt;tt&amp;gt;x = *p++&amp;lt;/tt&amp;gt; zum tragen:&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *p++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; p = p+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *++p;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; p = p+1; x = *p;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = (*p)++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; *p = (*p)+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = ++(*p);&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; *p = (*p)+1; x = *p;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} = {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Zuweisung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++ {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-- {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Decrement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ++&amp;lt;/tt&amp;gt; || Post-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} --&amp;lt;/tt&amp;gt; || Post-Decrement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Kurzschreibweisen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Für ganz Faule gibt es anstatt&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a = a @ b&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
für viele Operatoren (hier dargestellt durch ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;@&amp;lt;/tt&amp;gt;) die abkürzende Schreibweise&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a @= b&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} += {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} -= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} *= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} /= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} %= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ^= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;lt;&amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;gt;&amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Autoren=&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
=Quellen=&lt;br /&gt;
* Kernighan und Ritchie&lt;br /&gt;
* Christian Wirth, C-Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
* W. Alex, Einführung in C/C++&lt;br /&gt;
* Peter Baeumle-Courth, ANSI-C im Überblick&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://wwwuser.gwdg.de/~kboehm/ebook/inhalt.html C-Programmieren unter Linux]&lt;br /&gt;
* [http://www.gdv.uni-hannover.de/documentation.php Skripte zum Selbststudium: C, C++, Java, etc]&lt;br /&gt;
* [http://info.baeumle.com/ansic.html Einführung in ANSI-C]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Quellcode C|!]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Inrfb2</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Avr-gcc&amp;diff=10433</id>
		<title>Avr-gcc</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Avr-gcc&amp;diff=10433"/>
				<updated>2007-03-20T10:58:18Z</updated>
		
		<summary type="html">&lt;p&gt;Inrfb2: /* Zugiff auf Bytes und Worte */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''avr-gcc''' ist ein freier C-[[Compiler]], mit dem man C-Programme zu ausführbaren Programmen übersetzen kann, die auf [[Microcontroller]]n der [[AVR]]-Familie lauffähig sind. &lt;br /&gt;
An Sprachen versteht avr-gcc sowohl C als auch [[#C%2b%2b|C++]]. &lt;br /&gt;
Neben Standard-C bzw. ANSI-C versteht avr-gcc auch GNU-C, das etwas mehr Möglichkeiten und kleinere Spracherweiterungen bietet.&lt;br /&gt;
&lt;br /&gt;
avr-gcc kann auch dazu verwendet werden, um C/C++ Programme nach Assembler zu übersetzen oder um Bibliotheken zu erstellen, die später in unterschiedlichen Projekten verwendet werden können.&lt;br /&gt;
&lt;br /&gt;
Wie bei allen aus der UNIX-Welt kommenden Programmen ist das Kommando-Interface von avr-gcc die Shell bzw. die Kommandozeile, über die Optionen, Parameter, Einstellungen und die Namen der zu übersetzenden Dateien angegeben werden. &lt;br /&gt;
&lt;br /&gt;
=How to Read=&lt;br /&gt;
&lt;br /&gt;
Dieser Artikel bespricht avr-gcc Version 3.x. Er ist kein C-Tutorial und kein AVR-Handbuch &amp;amp;ndash; das würde den Umfang des Artikels bei weitem sprengen. &lt;br /&gt;
&lt;br /&gt;
Der Artikel ist ein Handbuch zu avr-gcc. Er bespricht zum Beispiel, wie man avr-gcc anwendet und Besonderheiten von avr-gcc-C,&lt;br /&gt;
die nicht zum Sprachumfang von C gehören.&lt;br /&gt;
Dazu zählen die Definition von [[#Interrupts|Interrupt]] Service Routinen ([[ISR|ISRs]]) &lt;br /&gt;
oder wie man Daten ins [[EEPROM]] legt.&lt;br /&gt;
&lt;br /&gt;
Es wird also besprochen, ''wie'' eine ISR zu definieren ist, aber nicht,&lt;br /&gt;
''warum'' das  gegebenenfalls notwendig oder nicht notwendig ist. &lt;br /&gt;
''Warum'' etwas gemacht wird, ist abhängig von der gestellten Aufgabe,&lt;br /&gt;
etwa ''&amp;quot;Initialisiere den [[UART]] zur Benutzung mit 9600 Baud&amp;quot;''.&lt;br /&gt;
Dafür enthält dieser Artikel zusammen mit dem AVR-Handbuch das Rüstzeug, &lt;br /&gt;
bietet aber keine Lösungen für konkrete Aufgaben.&lt;br /&gt;
&lt;br /&gt;
Neben diesem Artikel gibt es den Unterartikel [[avr-gcc/Interna|Interna von avr-gcc]] wo Dinge wie die Registerverwendung, Attribute, Builtins und Sections von avr-gcc dargestellt werden. Zudem findet sich dort ein Überblick über die Arbeitsweise von gcc mit den Schritten&lt;br /&gt;
* Precompilieren&lt;br /&gt;
* Compilieren&lt;br /&gt;
* Assemblieren&lt;br /&gt;
* Linken&lt;br /&gt;
Ein weiterer Unterartikel widmet sich dem Thema [[Inline-Assembler in avr-gcc]].&lt;br /&gt;
&lt;br /&gt;
In den [[:Kategorie:Quellcode C|C-Codebeispielen]]&lt;br /&gt;
befindet sich das ausführlichere Beispiel &amp;quot;[[Hallo Welt für AVR (LED blinken)]]&amp;quot;,&lt;br /&gt;
das nur eine [[Diode#Lumineszenzdiode|LED]] blinkt und zeigt, &lt;br /&gt;
wie ein kleines Projekt mit avr-gcc compiliert werden kann.&lt;br /&gt;
&lt;br /&gt;
Es gibt ein [[C-Tutorial]], das jedoch noch unvollständig und teilweise feherhaft ist (Stand 02/2006). Darüber hinaus gibt es ein [http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial C-Tutorial bei www.mikrocontroller.net].&lt;br /&gt;
&lt;br /&gt;
=Benutzer-Schnittstelle=&lt;br /&gt;
&lt;br /&gt;
Die Benutzer-Schnittstelle von avr-gcc ist &amp;amp;ndash; wie für alle Programme, die aus der UNIX-Welt kommen &amp;amp;ndash; die Kommandozeile einer Shell, Console bzw. Eingabeaufforderung. &lt;br /&gt;
&lt;br /&gt;
Im einfachsten Fall sieht ein Aufruf von avr-gcc also so aus:&lt;br /&gt;
 &amp;gt; avr-gcc&lt;br /&gt;
Dabei das '&amp;lt;tt&amp;gt;&amp;gt;&amp;lt;/tt&amp;gt;' nicht mittippen, und ein ENTER am Ende der Zeile drücken.&lt;br /&gt;
Die Antwort bei korrekter Installation ist dann&lt;br /&gt;
 avr-gcc: no input files&lt;br /&gt;
Was bedeutet: das Programm avr-gcc wurde vom Betriebssystem gefunden und konnte/durfte gestartet werden. Dann gibt avr-gcc eine Fehlermeldung aus und beendet die Ausführung, weil er keine Eingabedatei(en) bekommen hat &amp;amp;#150; was ja auch stimmt. Soweit ist also alles in Butter.&lt;br /&gt;
&lt;br /&gt;
Um eine C-Datei &amp;lt;tt&amp;gt;foo.c&amp;lt;/tt&amp;gt; mir avr-gcc optimiert zu einem lauffähigen elf-Programm &amp;lt;tt&amp;gt;foo.elf&amp;lt;/tt&amp;gt; für einen [[ATmega32]] zu compileren, würde man angeben&lt;br /&gt;
 &amp;gt; avr-gcc -O2 -mmcu=atmega32 foo.c -o foo.elf&lt;br /&gt;
Hat man seine Quellen auf zwei oder mehre Dateien verteilt, geht es analog:&lt;br /&gt;
 &amp;gt; avr-gcc -O2 -mmcu=atmega32 foo.c foo2.c -o foo.elf&lt;br /&gt;
&lt;br /&gt;
Will man nur eine Objekt-Datei erstellen (nur compilieren, nicht linken), dann geht das wie folgt. Das kann günstig sein bei grösseren Projekten, wenn man das Projekt neu erzeugen will, aber nur in einer Quelldatei was geändert hat. Oder wenn das Objekt in einer Bibliothek landen soll.&lt;br /&gt;
 &amp;gt; avr-gcc -O2 -c -mmcu=atmega32 foo.c -o foo.o&lt;br /&gt;
&lt;br /&gt;
Die ausführbare Gesamtdatei &amp;lt;tt&amp;gt;foo_all.elf&amp;lt;/tt&amp;gt; erhält man dann, indem alle Objekte zusammenlinkt:&lt;br /&gt;
 &amp;gt; avr-gcc -mmcu=atmega32 foo.o foo2.o foo3.o -o foo_all.elf&lt;br /&gt;
&lt;br /&gt;
Um die ausführbare Datei in das oft verwendete Intex-HEX-Format umzuwandeln (einmal fürs Programm, einmal für ein Abbild des [[EEPROM]]s) gibt man an:&lt;br /&gt;
 &amp;gt; avr-objcopy -O ihex -j .text -j .data                         foo_all.elf  foo_all.hex&lt;br /&gt;
 &amp;gt; avr-objcopy -O ihex -j .eeprom --change-section-lma .eeprom=0 foo_all.elf  foo_all_eeprom.hex&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[GCC]] war immer Kommandozeilen-orientiert und wird es auch immer bleiben, denn das hat gute Gründe:&lt;br /&gt;
* ein Compiler ist ein Compiler ist ein Compiler (und keine grafische Bedienschnittstelle)&lt;br /&gt;
* die Plattformabhängigkeit wird auf ein Minimum reduziert&lt;br /&gt;
* es gibt die Möglichkeit, avr-gcc per Skript oder [[make]] zu starten&lt;br /&gt;
* avr-gcc kann durchaus in eine Umgebung integriert werden: in einen Editor oder in eine GUI wie neuere Versionen von AVR-Studio erfolgreich beweisen, etc. Der avr-gcc-Aufruf kann sogar von einem Server-Socket oder einer Web-Application heraus erfolgen, welche ein C-Programm empfängt, es von avr-gcc übersetzen lässt, und das Resultat zurückschickt oder sonst was damit anstellt.&lt;br /&gt;
* Lizenzgründe: eine Umgebung, die avr-gcc integriert, kann durchaus proprietär oder nicht quelloffen sein und muss nicht der [[Freie Software|GPL]] unterliegen. Wieder ist AVR-Studio ein Beispiel.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Unterstützte AVR-Derivate=&lt;br /&gt;
;Classic AVR&amp;amp;#58;: [[AT90S1200]], [[AT90S2313]], [[AT90S8515]], [[AT90S8535]], [[AT90S4433]], [[AT90S4414]], [[AT90S4434]], [[AT90S2323]], [[AT90S2333]], [[AT90S2343]], &lt;br /&gt;
&lt;br /&gt;
;tinyAVR&amp;amp;#58;: [[ATtiny10]], [[ATtiny11]], [[ATtiny12]], [[ATtiny15]], [[ATtiny28]], [[ATtiny22]], [[ATtiny26]], [[AT90C8534]], [[AT86rf401]], [[ATtiny13]], [[ATtiny2313]], [[ATtiny261]], [[ATtiny461]], [[ATtiny861]], [[ATtiny24]], [[ATtiny44]], [[ATtiny84]], [[ATtiny25]], [[ATtiny45]], [[ATtiny85]]&lt;br /&gt;
&lt;br /&gt;
;megaAVR&amp;amp;#58;: [[ATmega603]], [[ATmega103]], [[AT76C711]], [[ATmega48]], [[ATmega8]], [[ATmega83]], [[ATmega85]], [[ATmega88]], [[ATmega8515]], [[ATmega8535]], [[ATmega16]], [[ATmega161]], [[ATmega162]], [[ATmega163]], [[ATmega164p]], [[ATmega165]], [[ATmega165P]], [[ATmega168]], [[ATmega32]], [[ATmega323]], [[ATmega324P]], [[ATmega325]], [[ATmega3250]],  [[ATmega64]], [[ATmega640]], [[ATmega644]], [[ATmega644P]], [[ATmega128]], [[ATmega1280]], [[ATmega1281]], [[ATmega645]],  [[ATmega6450]], [[AT94K]]&lt;br /&gt;
&lt;br /&gt;
; [[LCD]] AVR&amp;amp;#58;: [[ATmega169]], [[ATmega169P]], [[ATmega329]], [[ATmega3290]], [[ATmega649]], [[ATmega6490]],&lt;br /&gt;
; Lightning AVR&amp;amp;#58;: [[AT90PWM2]], [[AT90PWM3]]&lt;br /&gt;
; [[CAN]] AVR&amp;amp;#58;: [[AT90CAN32]], [[AT90CAN64]], [[AT90CAN128]]&lt;br /&gt;
; Smart Battery&amp;amp;#58;: [[ATmega406]]&lt;br /&gt;
; [[USB]] AVR&amp;amp;#58;: [[AT43USB320]], [[AT43USB355]], [[AT90USB646]], [[AT90USB647]], [[AT90USB1286]], [[AT90USB1287]]&lt;br /&gt;
;&lt;br /&gt;
&lt;br /&gt;
Diese Liste kann man avr-gcc anzeigen lassen mit&lt;br /&gt;
 &amp;gt; avr-gcc --target-help&lt;br /&gt;
&lt;br /&gt;
=Kommandozeilen-Optionen=&lt;br /&gt;
Die Codegenerierung bei avr-gcc wird über Kommandozeilen-Optionen gesteuert. Diese legen fest, für welchen Controller Code zu erzeugen ist, wie stark optimiert wird, ob Debug-Informationen erzeugt werden, etc. Die Optionen teilen sich in zwei Gruppen: Optionen, die für alle GCC-Ports verfürgbar sind und maschinenspezifische Optionen, die nur für AVR verfügbar sind.&lt;br /&gt;
&lt;br /&gt;
Aus der Masse an GCC-Optionen kann hier nur ein kleiner Auszug der wichtigsten und am häufigsten verwendeten Optionen vorgestellt werden. Eine Auflistung aller GCC-Optionen mit Kurzbeschreibung umfasst knapp 1000 Zeilen &amp;amp;#150; ohne undokumentierte Optionen, versteht sich.&lt;br /&gt;
&lt;br /&gt;
==Allgemeine Optionen für GCC==&lt;br /&gt;
; &amp;lt;tt&amp;gt;--help&amp;lt;/tt&amp;gt;: Anzeige der wichtigsten Optionen&lt;br /&gt;
; &amp;lt;tt&amp;gt;--help -v&amp;lt;/tt&amp;gt;: Überschüttet einen mit Optionen&lt;br /&gt;
; &amp;lt;tt&amp;gt;--target-help&amp;lt;/tt&amp;gt;: Anzeige der wichtigsten maschinenspezifischen Optionen und der unterstützten AVR-Derivate&lt;br /&gt;
; &amp;lt;tt&amp;gt;-O0&amp;lt;/tt&amp;gt;: keine Optimierung&lt;br /&gt;
; &amp;lt;tt&amp;gt;-O1&amp;lt;/tt&amp;gt;: Optimierung&lt;br /&gt;
; &amp;lt;tt&amp;gt;-Os&amp;lt;/tt&amp;gt;: optimiert für Code-Größe&lt;br /&gt;
; &amp;lt;tt&amp;gt;-O2&amp;lt;/tt&amp;gt;: stärkere Optimierung für bessere Laufzeit&lt;br /&gt;
; &amp;lt;tt&amp;gt;-g&amp;lt;/tt&amp;gt;: erzeugt Debug-Informationen&lt;br /&gt;
; &amp;lt;tt&amp;gt;-c&amp;lt;/tt&amp;gt;: (pre)compilert und assembliert nur bis zum Objekt (&amp;lt;tt&amp;gt;*.o&amp;lt;/tt&amp;gt;), kein Link-Lauf&lt;br /&gt;
; &amp;lt;tt&amp;gt;-S&amp;lt;/tt&amp;gt;: (pre)compilert nur und erzeugt Assembler-Ausgabe (*.s)&lt;br /&gt;
; &amp;lt;tt&amp;gt;-E&amp;lt;/tt&amp;gt;: nur Precompilat (&amp;lt;tt&amp;gt;*.i&amp;lt;/tt&amp;gt;) erzeugen, kein Compilieren, kein Assemblieren, kein Linken&lt;br /&gt;
; &amp;lt;tt&amp;gt;-o &amp;lt;filename&amp;gt;&amp;lt;/tt&amp;gt;: legt den Name der Ausgabedatei fest&lt;br /&gt;
; &amp;lt;tt&amp;gt;-v&amp;lt;/tt&amp;gt;: zeigt Versionsinformationen an und ist geschwätzig (verbose): Anzeige der aufgerufenen tools&lt;br /&gt;
; &amp;lt;tt&amp;gt;-I&amp;lt;path&amp;gt;&amp;lt;/tt&amp;gt;: Angabe eines weiteren Include-Pfads, in dem Dateien mit &amp;lt;tt&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/tt&amp;gt; gesucht werden&lt;br /&gt;
; &amp;lt;tt&amp;gt;-E -dM &amp;lt;filename&amp;gt;&amp;lt;/tt&amp;gt;: Anzeige aller Defines&lt;br /&gt;
; &amp;lt;tt&amp;gt;-MM&amp;lt;/tt&amp;gt;: Für die angegebenen Eingabe-Dateien wird eine Ausgabe erzeugt, die als [[make|Makefile]]-Fragment dienen kann und die Anhängigkeiten (dependencies) der Objekte von den Quellen/Headern beschreibt.&lt;br /&gt;
; &amp;lt;tt&amp;gt;-D&amp;lt;name&amp;gt;&amp;lt;/tt&amp;gt;: Definiert Makro &amp;lt;tt&amp;gt;&amp;lt;name&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
; &amp;lt;tt&amp;gt;-D&amp;lt;name&amp;gt;=&amp;lt;wert&amp;gt;&amp;lt;/tt&amp;gt;: Definiert Makro &amp;lt;tt&amp;gt;&amp;lt;name&amp;gt;&amp;lt;/tt&amp;gt; zu &amp;lt;tt&amp;gt;&amp;lt;wert&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
; &amp;lt;tt&amp;gt;-U&amp;lt;name&amp;gt;&amp;lt;/tt&amp;gt;: Undefiniert Makro &amp;lt;tt&amp;gt;&amp;lt;name&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
; &amp;lt;tt&amp;gt;-save-temps&amp;lt;/tt&amp;gt;: Temporäre Dateien (&amp;lt;tt&amp;gt;*.i&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;*.s&amp;lt;/tt&amp;gt;) werden nicht gelöscht. Teilweise fehlerhaft zusammen mit &amp;lt;tt&amp;gt;-c&amp;lt;/tt&amp;gt;&lt;br /&gt;
; &amp;lt;tt&amp;gt;-Wa,&amp;lt;options&amp;gt;&amp;lt;/tt&amp;gt;: übergibt Komma-getrennte Liste &amp;lt;tt&amp;gt;&amp;lt;options&amp;gt;&amp;lt;/tt&amp;gt; an den Assembler (&amp;lt;tt&amp;gt;avr-as&amp;lt;/tt&amp;gt;)&lt;br /&gt;
:;&amp;lt;tt&amp;gt;-Wa,-a=&amp;lt;filename&amp;gt;&amp;lt;/tt&amp;gt;: Assembler erzeugt ein Listing mit Name &amp;lt;tt&amp;gt;&amp;lt;filename&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
; &amp;lt;tt&amp;gt;-Wp,&amp;lt;options&amp;gt;&amp;lt;/tt&amp;gt;:  übergibt Komma-getrennte Liste &amp;lt;tt&amp;gt;&amp;lt;options&amp;gt;&amp;lt;/tt&amp;gt; an den Preprozessor&lt;br /&gt;
; &amp;lt;tt&amp;gt;-Wl,&amp;lt;options&amp;gt;&amp;lt;/tt&amp;gt;:  übergibt Komma-getrennte Liste &amp;lt;tt&amp;gt;&amp;lt;options&amp;gt;&amp;lt;/tt&amp;gt; an den Linker (&amp;lt;tt&amp;gt;avr-ld&amp;lt;/tt&amp;gt;)&lt;br /&gt;
:;&amp;lt;tt&amp;gt;-Wl,-Map=&amp;lt;filename&amp;gt;&amp;lt;/tt&amp;gt;: Linker erzeugt ein Map-File mit Name &amp;lt;tt&amp;gt;&amp;lt;filename&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
:;&amp;lt;tt&amp;gt;-Wl,--oformat=&amp;lt;format&amp;gt;&amp;lt;/tt&amp;gt;: Linker erzeugt Ausgabe im Format &amp;lt;tt&amp;gt;&amp;lt;format&amp;gt;&amp;lt;/tt&amp;gt;, z.b. &amp;lt;tt&amp;gt;ihex&amp;lt;/tt&amp;gt; für Intel-HEX-File&lt;br /&gt;
:;&amp;lt;tt&amp;gt;-Wl,--section-start=&amp;lt;section&amp;gt;=&amp;lt;address&amp;gt;&amp;lt;/tt&amp;gt;: Linker legt die [[avr-gcc/Interna#Sections|Section]] &amp;lt;tt&amp;gt;&amp;lt;section&amp;gt;&amp;lt;/tt&amp;gt; ab Adresse &amp;lt;tt&amp;gt;&amp;lt;address&amp;gt;&amp;lt;/tt&amp;gt;, z.B: &amp;lt;tt&amp;gt;.eeprom=0x810001&amp;lt;/tt&amp;gt;&lt;br /&gt;
; &amp;lt;tt&amp;gt;-Wall&amp;lt;/tt&amp;gt;: gibt mehr Warnungen, aber immer noch nicht alle&lt;br /&gt;
; &amp;lt;tt&amp;gt;-pedantic&amp;lt;/tt&amp;gt;: geht besonders pedantisch mit Code um&lt;br /&gt;
; &amp;lt;tt&amp;gt;-std=c89&amp;lt;br/&amp;gt;-ansi&amp;lt;/tt&amp;gt;: bricht mit einer Fehlermeldung ab, wenn kein ANSI-C (ISO C89) verwendet wurde&lt;br /&gt;
; &amp;lt;tt&amp;gt;-std=c99&amp;lt;/tt&amp;gt;: bricht mit einer Fehlermeldung ab, wenn kein ISO C99 verwendet wurde&lt;br /&gt;
; &amp;lt;tt&amp;gt;-ffreestanding&amp;lt;/tt&amp;gt;: Das erzeugte Programm läuft nicht in einer Umgebung wie einer Shell. Der Prototyp von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; ist&lt;br /&gt;
:&amp;lt;pre&amp;gt;void main (void);&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Maschinenspezifische Optionen für avr-gcc==&lt;br /&gt;
Maschinenabhängige Optionen beginnen immer mit '''-m'''&lt;br /&gt;
;-mmcu=xxx: Festlegen des Targets (Zielsystem/Controller), für das Code generiert werden soll. Je nach Target muss avr-gcc unterschiedliche Instruktionen verwenden und andere Startup-Dateien (&amp;lt;tt&amp;gt;crtxxx.o&amp;lt;/tt&amp;gt;) einbinden. avr-gcc setzt spezielle Defines, um auch in der Quelle zwischen den Targets unterscheiden zu können, falls das notwendig sein sollte: &lt;br /&gt;
:{| border=&amp;quot;0&amp;quot; cellpadding=&amp;quot;0&amp;quot; cellspacing=&amp;quot;0&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#ifdef __AVR_AT90S2313__&lt;br /&gt;
/* Code fuer AT90S2313 */&lt;br /&gt;
#elif defined (__AVR_ATmega8__) || defined (__AVR_ATmega32__)&lt;br /&gt;
/* Code fuer Mega8 und Mega32 */ &lt;br /&gt;
#else&lt;br /&gt;
#error Das ist noch nicht implementiert für diesen Controller!&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Zwar gibt es für alle AVR-Derivate die &amp;lt;tt&amp;gt;avr/io.h&amp;lt;/tt&amp;gt;, aber die AVR-Familien unterscheiden sich in ihrer Hardware; z.B. darin, wie I/O-Register heissen oder wie Hardware zu initialisieren ist. Diese Abhängigkeit kann man in unterschiedlichen Codestücken aufteilen und wie oben gezeigt bedingt übersetzen. Dadurch hat man Funktionalitäten wie &amp;lt;tt&amp;gt;uart_init&amp;lt;/tt&amp;gt; auf unterschiedlichen Controllern und wahrt den Überblick, weil nicht für jede Controller-Familie eine extra Datei notwendig ist.&lt;br /&gt;
{| &lt;br /&gt;
|- valign=&amp;quot;top&amp;quot; &lt;br /&gt;
| &lt;br /&gt;
:{| {{Blauetabelle}}&lt;br /&gt;
|+ '''AVR classic, &amp;amp;lt;= 8 kByte'''&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|mcu || Builtin define&lt;br /&gt;
 |- &lt;br /&gt;
 |avr2 ||&amp;lt;tt&amp;gt;__AVR_ARCH__=2&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |[[AT90S2313|at90s2313]]  ||&amp;lt;tt&amp;gt;__AVR_AT90S2313__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90s2323 ||&amp;lt;tt&amp;gt;__AVR_AT90S2323__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90s2333 ||&amp;lt;tt&amp;gt;__AVR_AT90S2333__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90s2343 ||&amp;lt;tt&amp;gt;__AVR_AT90S2343__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |attiny22 ||&amp;lt;tt&amp;gt;__AVR_ATtiny22__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |attiny26 ||&amp;lt;tt&amp;gt;__AVR_ATtiny26__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90s4414 ||&amp;lt;tt&amp;gt;__AVR_AT90S4414__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90s4433 ||&amp;lt;tt&amp;gt;__AVR_AT90S4433__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90s4434 ||&amp;lt;tt&amp;gt;__AVR_AT90S4434__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90s8515 ||&amp;lt;tt&amp;gt;__AVR_AT90S8515__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90c8534 ||&amp;lt;tt&amp;gt;__AVR_AT90C8534__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90s8535 ||&amp;lt;tt&amp;gt;__AVR_AT90S8535__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at86rf401 ||&amp;lt;tt&amp;gt;__AVR_AT86RF401__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
 |  &amp;lt;!-----------------------------------------------------------&amp;gt;&lt;br /&gt;
:{| {{Blauetabelle}}&lt;br /&gt;
|+ '''AVR classic, &amp;amp;gt; 8 kByte'''&lt;br /&gt;
|- bgcolor=&amp;quot;#ccccff&amp;quot;&lt;br /&gt;
! |mcu ||Builtin define&lt;br /&gt;
 |- &lt;br /&gt;
 |avr3 ||&amp;lt;tt&amp;gt;__AVR_ARCH__=3&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |atmega103 ||&amp;lt;tt&amp;gt;__AVR_ATmega103__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |atmega603 ||&amp;lt;tt&amp;gt;__AVR_ATmega603__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at43usb320 ||&amp;lt;tt&amp;gt;__AVR_AT43USB320__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at43usb355 ||&amp;lt;tt&amp;gt;__AVR_AT43USB355__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at76c711 ||&amp;lt;tt&amp;gt;__AVR_AT76C711__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&amp;lt;!-----------------------------------------------------------&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| &lt;br /&gt;
 |- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
 |&lt;br /&gt;
:{| {{Blauetabelle}}&lt;br /&gt;
|+ '''AVR enhanced, &amp;amp;lt;= 8 kByte'''&lt;br /&gt;
|- bgcolor=&amp;quot;#ccccff&amp;quot;&lt;br /&gt;
!|mcu || Builtin define&lt;br /&gt;
 |- &lt;br /&gt;
 |avr4 ||&amp;lt;tt&amp;gt;__AVR_ARCH__=4&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |[[Atmel Controller Mega8|atmega8]] ||&amp;lt;tt&amp;gt;__AVR_ATmega8__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |atmega8515 ||&amp;lt;tt&amp;gt;__AVR_ATmega8515__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |atmega8535 ||&amp;lt;tt&amp;gt;__AVR_ATmega8535__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
 |&amp;lt;!-----------------------------------------------------------&amp;gt;&lt;br /&gt;
:{| {{Blauetabelle}}&lt;br /&gt;
|+ '''AVR enhanced, &amp;amp;gt; 8 kByte'''&lt;br /&gt;
|- bgcolor=&amp;quot;#ccccff&amp;quot;&lt;br /&gt;
!|mcu ||Builtin define&lt;br /&gt;
 |- &lt;br /&gt;
 |avr5 ||&amp;lt;tt&amp;gt;__AVR_ARCH__=5&amp;lt;/tt&amp;gt; &lt;br /&gt;
 |-&lt;br /&gt;
 |[[Atmel Controller Mega16 und Mega32|atmega16]] ||&amp;lt;tt&amp;gt;__AVR_ATmega16__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |atmega161 ||&amp;lt;tt&amp;gt;__AVR_ATmega161__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |atmega162 ||&amp;lt;tt&amp;gt;__AVR_ATmega162__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |atmega163 ||&amp;lt;tt&amp;gt;__AVR_ATmega163__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |atmega169 ||&amp;lt;tt&amp;gt;__AVR_ATmega169__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |[[Atmel Controller Mega16 und Mega32|atmega32]] ||&amp;lt;tt&amp;gt;__AVR_ATmega32__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |atmega323 ||&amp;lt;tt&amp;gt;__AVR_ATmega323__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |[[ATMega64|atmega64]] ||&amp;lt;tt&amp;gt;__AVR_ATmega64__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |[[Atmel Controller Mega128|atmega128]] ||&amp;lt;tt&amp;gt;__AVR_ATmega128__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at94k ||&amp;lt;tt&amp;gt;__AVR_AT94K__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&amp;lt;!-----------------------------------------------------------&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:{| {{Blauetabelle}}&lt;br /&gt;
|+ '''AVR, nur Assembler'''&lt;br /&gt;
|- bgcolor=&amp;quot;#ccccff&amp;quot;&lt;br /&gt;
! |mcu ||Builtin define&lt;br /&gt;
 |- &lt;br /&gt;
 |avr1 ||&amp;lt;tt&amp;gt;__AVR_ARCH__=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90s1200 ||&amp;lt;tt&amp;gt;__AVR_AT90S1200__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |attiny11 ||&amp;lt;tt&amp;gt;__AVR_ATtiny11__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |attiny12 ||&amp;lt;tt&amp;gt;__AVR_ATtiny12__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |attiny15 ||&amp;lt;tt&amp;gt;__AVR_ATtiny15__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |attiny28 ||&amp;lt;tt&amp;gt;__AVR_ATtiny28__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
; -minit-stack=xxx: Festlegen der Stack-Adresse&lt;br /&gt;
; -mint8: Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ist nur 8 Bit breit, anstatt 16 Bit. Datentypen mit 32 Bit wie  &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; sind nicht verfügbar&lt;br /&gt;
; -mno-interrupts: Ändert den Stackpointer ohne Interrupts zu deaktivieren&lt;br /&gt;
; -mcall-prologues: Funktions-Prolog und -Epilog werden als Unterroutinen umgesetzt, um die Codegröße zu verkleinern&lt;br /&gt;
; -mtiny-stack: Nur die unteren 8 Bit des Stackpointers werden verändert&lt;br /&gt;
; -mno-tablejump: Für ein &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;-Statement werden keine Sprungtabellen angelegt&lt;br /&gt;
; -mshort-calls: Verwendet &amp;lt;tt&amp;gt;rjmp&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;rcall&amp;lt;/tt&amp;gt; (begrenzte Sprungweite) auf Devices mit mehr als 8 kByte Flash&lt;br /&gt;
; -msize: Ausgabe der Instruktonslängen im asm-File&lt;br /&gt;
; -mdeb: (undokumentiert) Ausgabe von Debug-Informationen für GCC-Entwickler&lt;br /&gt;
; -morder1: (undokumentiert) andere Register-Allokierung&lt;br /&gt;
; -morder2: (undokumentiert) andere Register-Allokierung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=C++=&lt;br /&gt;
&lt;br /&gt;
:''&amp;quot;C++ is a complex language and an evolving one, and its standard definition (the ISO C++ standard) was only recently completed. As a result, your C++ compiler may occasionally surprise you, even when its behavior is correct.&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
Zudem sollte der Einsatz von C++ aus Effizienzgründen sehr kritisch betrachtet werden:&lt;br /&gt;
:''&amp;quot;When programming C++ in space- and runtime-sensitive environments like microcontrollers, extra care should be taken to avoid unwanted side effects of the C++ calling conventions like implied copy constructors that could be called upon function invocation etc. These things could easily add up into a considerable amount of time and program memory wasted. Thus, casual inspection of the generated assembler code (using the &amp;lt;tt&amp;gt;-S&amp;lt;/tt&amp;gt; compiler option) seems to be warranted.&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
Weiterhin unterliegt der Einsatz von C++ je nach Compiler/Lib-Version bestimmten Einschränkungen:&lt;br /&gt;
*Einer kompletten C++ Implementierung fehlt die Unterstützung durch die &amp;lt;tt&amp;gt;libstdc++&amp;lt;/tt&amp;gt;, dadurch fehlen Standardfunktionen, -Klassen und -Templates&lt;br /&gt;
* Die Operatoren &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;delete&amp;lt;/tt&amp;gt; sind nicht implementiert, ihre Verwendung führt zu unauflösbaren externen Referenzen (Linker-Fehler)&lt;br /&gt;
*Nicht alle Header sind C++-sicher und müssen in &amp;lt;tt&amp;gt;extern &amp;quot;C&amp;quot; {...}&amp;lt;/tt&amp;gt; eingeschlossen werden.&lt;br /&gt;
*Exceptions werden nicht unterstützt und müssen via &amp;lt;tt&amp;gt;-fno-exceptions&amp;lt;/tt&amp;gt; abgeschaltet werden, oder der Linker beschwert sich über eine unauflösbare externe Referenz zu &amp;lt;tt&amp;gt;__gxx_personality_sj0&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Als Treiber verwendet man wie immer avr-gcc. Standard-Endungen für C++ sind &amp;lt;tt&amp;gt;.c++&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;.cpp&amp;lt;/tt&amp;gt;. Bei anderen Endungen teilt man mit &amp;lt;tt&amp;gt;-x c++&amp;lt;/tt&amp;gt; mit, daß es sich um C++ Dateien handelt, oder ruft &amp;lt;tt&amp;gt;avr-c++&amp;lt;/tt&amp;gt; direkt auf.&lt;br /&gt;
&lt;br /&gt;
Interrupt-Service-Routinen (ISRs) sind C-Funktionen und werden definiert wie gehabt. Siehe auch [[#Interrupts|Interrupts]].&lt;br /&gt;
 #include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #if defined (__cplusplus)&lt;br /&gt;
 extern &amp;quot;C&amp;quot; {&lt;br /&gt;
 #endif {{comment|__cplusplus}}&lt;br /&gt;
 &lt;br /&gt;
 SIGNAL (SIG_NAME)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|machwas}}&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 INTERRUPT (SIG_NAME)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|mach was}}&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 #if defined (__cplusplus)&lt;br /&gt;
 }&lt;br /&gt;
 #endif {{comment|__cplusplus}}&lt;br /&gt;
&amp;lt;tt&amp;gt;__cplusplus&amp;lt;/tt&amp;gt; ist ein Standard [[avr-gcc/Interna#Builtin Defines|GCC-Builtin-Define]].&lt;br /&gt;
&lt;br /&gt;
Globale Konstruktoren werden in [[avr-gcc/Interna#Sections|Section]] &amp;lt;tt&amp;gt;.init6&amp;lt;/tt&amp;gt; ausgeführt, die Destruktoren in &amp;lt;tt&amp;gt;.fini6&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=Code-Beispiele=&lt;br /&gt;
Dieser Abschnitt enthält Code-Schnippsel für avr-gcc. Es werden Besonderheiten besprochen, die für avr-gcc zu beachten sind. &lt;br /&gt;
&lt;br /&gt;
Dieser Abschnitt ist ''kein'' [[C-Tutorial|Tutorial zur C-Programmierung]] und ''keine'' Einführung in die Programmiersprache C im allgemeinen. Dafür sei auf einschlägige Tutorials/Bücher verwiesen.&lt;br /&gt;
&lt;br /&gt;
==Zugriff auf Special Function Registers (SFRs)==&lt;br /&gt;
&lt;br /&gt;
===Zugiff auf Bytes und Worte===&lt;br /&gt;
Vor dem Zugriff auf die SFRs gibt es Defines über den Include&lt;br /&gt;
 #include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
Abhängig vom eingestellten Controller werden denn Defines eingebunden, über die auf SFRs wie auf normale Variablen zugegriffen werden kann. Die Namen der Defines sind i.d.R. die gleichen wie im AVR-Manual, also z.b. &amp;lt;tt&amp;gt;SREG&amp;lt;/tt&amp;gt; für das Prozessorstatus-Register SREG:&lt;br /&gt;
 #include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
   {{ccomment|SREG lesen}}&lt;br /&gt;
   uint8_t sreg = SREG;&lt;br /&gt;
   ...&lt;br /&gt;
   {{ccomment|SREG schreiben}}&lt;br /&gt;
   SREG = sreg;&lt;br /&gt;
&amp;lt;!--  &lt;br /&gt;
Auf SFRs wird generell über deren Adresse zugegriffen:&lt;br /&gt;
 {{ccomment|Liest den Inhalt von SREG an Adresse 0x5f}}&lt;br /&gt;
 unsigned char sreg = *((unsigned char volatile*) 0x5f);&lt;br /&gt;
Das bedeutet in etwa: &amp;quot;Lies ein flüchtiges (&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;) Byte (&amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt;) von Adresse &amp;lt;tt&amp;gt;0x5f&amp;lt;/tt&amp;gt;&amp;quot;. Der Speicherinhalt von SFRs ist flüchtig, denn er kann sich ändern, ohne daß avr-gcc dies mitbekommt. Daher muss bei jedem C-Zugriff auf ein SFR dieses wirklich gelesen/geschrieben werden, was der Qualifier &amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt; sicherstellt. Ansonst geht der Compiler u.U. davon aus, daß der Inhalt bekannt ist und verwendet einen alten, in einem GPR befindlichen Wert.&lt;br /&gt;
&lt;br /&gt;
Um lesbaren, weniger fehleranfälligen und unter AVRs halbwegs portierbaren Code zu erhalten, gibt es Makrodefinitionen im Controller-spezifischen Header &amp;lt;tt&amp;gt;ioxxxx.h&amp;lt;/tt&amp;gt;, der neben anderen Dingen mit &amp;lt;tt&amp;gt;avr/io.h&amp;lt;/tt&amp;gt; includet wird:&lt;br /&gt;
Die Bezeichner der SFRs sind die gleichen wie im Manual.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Für einen Überblick über die eingebundenen Defines und kann ein Blick in den Controller-spezifischen Header hilfreich sein. Dieser befindet sich in&lt;br /&gt;
:&amp;lt;tt&amp;gt; &amp;amp;lt;GCC_HOME&amp;amp;gt;/avr/include/avr/io****.h&amp;lt;/tt&amp;gt;&lt;br /&gt;
z.B. &amp;lt;tt&amp;gt;iom32.h&amp;lt;/tt&amp;gt; für einen [[ATmega32]].&lt;br /&gt;
&lt;br /&gt;
Dieser Zugriff geht auch für 16-Bit Register wie &amp;lt;tt&amp;gt;TCNT1&amp;lt;/tt&amp;gt;, für die eine bestimmte Reihenfolge für den Zugriff auf Low- und High-Teil eingehalten werden muss: avr-gcc generiert die Zugriffe in der richtigen Reihenfolge.&lt;br /&gt;
  uint16_t tcnt1 = TCNT1;&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Zu beachten ist, daß dieser Zugriff nicht atomar erfolgt. Das Lesen/Schreiben mehrbytiger Werte muss vom Compiler in mehrere Byte-Zugriffe zerlegt werden. Zwischen diesen Zugriffen kann ein [[Interrupt]] auftreten, wenn Interrupts aktiviert sind. Je nach Programm und welche Aufgaben eine [[ISR]] erledigt, kann dies zu Fehlfunktion führen. In dem Fall müssen diese Code-Stücke atomar gemacht werden, damit sie nicht durch einen [[IRQ]] unterbrochen werden können!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Zugriff auf einzelne Bits===&lt;br /&gt;
Zugriff auf Bits geht wie gewohnt mit den Bitoperationen &lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; (and),&lt;br /&gt;
&amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt; (or),&lt;br /&gt;
&amp;lt;tt&amp;gt;^&amp;lt;/tt&amp;gt; (xor) und&lt;br /&gt;
&amp;lt;tt&amp;gt;~&amp;lt;/tt&amp;gt; (not)&lt;br /&gt;
&lt;br /&gt;
Wieder gibt es Defines in den AVR-Headern, mit denen man Masken für den Zugriff erhalten kann, etwa:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* GIMSK / GICR */&lt;br /&gt;
#define INT1    7&lt;br /&gt;
#define INT0    6&lt;br /&gt;
#define IVSEL   1&lt;br /&gt;
#define IVCE    0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Masken ergeben sich durch Schieben von &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; an die richtige Position:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Ports B_0 und B_1 als Ausgang&lt;br /&gt;
DDRB |= (1&amp;amp;lt;&amp;amp;lt;PB0) | (1&amp;amp;lt;&amp;amp;lt;PB1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
erzeugt&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
87 b3           in      r24, 0x17&lt;br /&gt;
83 60           ori     r24, 0x03&lt;br /&gt;
87 bb           out     0x17, r24&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Etwas anders sieht der Code aus, wenn die Bits einzeln gesetzt werden und das Register im bitadressierbaren Bereich liegt (SRAM &amp;lt;tt&amp;gt;0x20&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;0x3f&amp;lt;/tt&amp;gt; resp. I/O &amp;lt;tt&amp;gt;0x0&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;0x1f&amp;lt;/tt&amp;gt;):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Ports B_0 und B_1 als Ausgang&lt;br /&gt;
DDRB |= (1&amp;amp;lt;&amp;amp;lt;PB0);&lt;br /&gt;
DDRB |= (1&amp;amp;lt;&amp;amp;lt;PB1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
erzeugt&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
b8 9a           sbi     0x17, 0&lt;br /&gt;
b9 9a           sbi     0x17, 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um Bits zu löschen, erzeugt man eine Maske, die an der betreffenden Stelle eine &amp;amp;nbsp;0 hat:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Ports B_2 als Eingang&lt;br /&gt;
DDRB &amp;amp;= ~(1&amp;amp;lt;&amp;amp;lt;PB2);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen| &lt;br /&gt;
Auch hier ist zu beachten, daß es Probleme geben kann, wenn nicht atomarer Code erzeugt wird, weil der AVR-Befehlssatz nicht mehr hergibt:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// toggle PORT B_0: wechseln 0 &amp;amp;lt;--&amp;amp;gt; 1 &lt;br /&gt;
PORTB ^= (1&amp;amp;lt;&amp;amp;lt;PB0);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
ergibt&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
88 b3           in      r24, 0x18&lt;br /&gt;
; Wenn hier ein Interrupt auftritt, in dessen ISR PORTB verändert wird,&lt;br /&gt;
; dann wird die Änderung durch die letzte Instruktion wieder überschrieben!&lt;br /&gt;
91 e0           ldi     r25, 0x01&lt;br /&gt;
; dito&lt;br /&gt;
89 27           eor     r24, r25&lt;br /&gt;
; dito&lt;br /&gt;
88 bb           out     0x18, r24&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
}} &amp;lt;!-- /FarbigerRahmen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auch das Lesen einzelner Port-Pins geht über das Maskieren von SFRs:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DDRB &amp;amp;= ~(1 &amp;lt;&amp;lt; PB2);    // PortB.2 als INPUT &lt;br /&gt;
&lt;br /&gt;
if (PINB &amp;amp; (1 &amp;lt;&amp;lt; PB2))&lt;br /&gt;
   // PortB.2 ist HIGH&lt;br /&gt;
else&lt;br /&gt;
   // PortB.2 ist LOW&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if (!(PINB &amp;amp; (1 &amp;lt;&amp;lt; PB2)))&lt;br /&gt;
   // PortB.2 ist LOW&lt;br /&gt;
else&lt;br /&gt;
   // PortB.2 ist HIGH&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Interrupts==&lt;br /&gt;
&lt;br /&gt;
Um zu kennzeichnen, daß es sich bei einer Funktion um eine Interrupt Sevice Routine (ISR) handelt, gibt es spezielle Attribute. Diese brauchen nicht explizit hingeschrieben zu werden, ebensowenig wie die genaue Nummer des Interrupt Requests (IRQ). Dafür gibt es Includes und die folgenden Makros.&lt;br /&gt;
&lt;br /&gt;
Bitte beachte auch die Hinweise zu den [[#Inkompatibilität|Inkompatibilität]]en von avr-gcc!&lt;br /&gt;
 #include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Eine nichtunterbrechbare Interrupt-Service-Routine}}&lt;br /&gt;
 SIGNAL (SIG_OUTPUT_COMPARE1A)&lt;br /&gt;
 {&lt;br /&gt;
    {{ccomment|ISR-Code}}&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Eine unterbrechbare Interrupt-Service-Routine}}&lt;br /&gt;
 INTERRUPT (SIG_OUTPUT_COMPARE1B)&lt;br /&gt;
 {&lt;br /&gt;
    {{ccomment|ISR-Code}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Dadurch wird die Funktion mit dem richtigen Prolog/Epilog erzeugt, und es wird ein Eintrag in die Interrupt-Vektortabelle gemacht &amp;amp;#150; bei obigem Beispiel also zwei Einträge.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Die Schreibweise des Signal-Names muss genau die sein wie im Header, das schliesst auch Leerzeichen ein! Nicht alle GCC-Versionen bringen Fehler/Warnung, wenn die Schreibweise nicht stimmt.&lt;br /&gt;
 SIGNAL (SIG_OUTPUT_COMPARE1A )  // !!! Macht NICHT das, was man will (Blank am Ende)!!!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;SIGNAL&amp;lt;/tt&amp;gt;: Mit Ausführung einer ISR deaktiviert die AVR-Hardware die Interrupts, so daß die ISR nicht durch andere Interrupt-Anforderungen unterbrochen wird. Beim Verlassen der ISR werden Interrupts wieder automatisch aktiviert. Tritt während der ISR ein IRQ auf, wird diese erst nach Beenden des ISR-Codes ausgeführt. Der Interrupt geht also nicht verloren. Zwischen zwei ISRs wird zusätzlich mindestens ein Befehl des normalen Programm-Codes abgearbeitet.&lt;br /&gt;
;&amp;lt;tt&amp;gt;INTERRUPT&amp;lt;/tt&amp;gt;: Früh im ISR-Prolog werden mit &amp;lt;tt&amp;gt;sei&amp;lt;/tt&amp;gt; die von der AVR-Hardware temporär deaktivierten Interrupts reaktiviert. Dadurch kann die ISR von einer IRQ unterbrochen werden. Das bietet die Möglichkeit, so etwas wie Interrupt-Priorisierung nachzubilden, was AVRs selbst nicht können. Weiterhin kann man schneller auf bestimmte Ereignisse reagieren. Tritt während der ISR ein anderer IRQ auf, der schnell bedient werden muss, kann sofort der dringende ISR-Code ausgeführt werden. Ansonsten (Verwendung von &amp;lt;tt&amp;gt;SIGNAL&amp;lt;/tt&amp;gt;) würde der Code erst ausgeführt werden, nachdem die aktuelle ISR beendet ist.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|Dauert die ISR zu lange und wird sie nochmals von ihrem eigenen IRQ unterbrochen, stürzt man ab.}} &lt;br /&gt;
&lt;br /&gt;
Nachschlagen kann man den Namen in&lt;br /&gt;
:&amp;lt;tt&amp;gt;&amp;amp;lt;GCC_HOME&amp;amp;gt;/avr/include/avr/ioxxxx.h&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Interrupts aktivieren===&lt;br /&gt;
&lt;br /&gt;
Damit eine ISR überhaupt zur Ausführung kommt, müssen drei Bedingungen erfüllt sein&lt;br /&gt;
* Interrupts müssen global aktiviert sein&lt;br /&gt;
* Der entsprechen IRQ muss aktiviert worden sein&lt;br /&gt;
* Das zum IRQ gehörende Ereignis muss eintreten&lt;br /&gt;
 #include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
    ...&lt;br /&gt;
    {{ccomment|enable OutputCompareA Interrupt für Timer1}}&lt;br /&gt;
    TIMSK |= (1 &amp;lt;&amp;lt; OCIE1A);&lt;br /&gt;
 &lt;br /&gt;
    {{ccomment|disable OutputCompareA Interrupt für Timer1}}&lt;br /&gt;
    TIMSK &amp;amp;= ~(1 &amp;lt;&amp;lt; OCIE1A);&lt;br /&gt;
 &lt;br /&gt;
    {{ccomment|Interrupts aktivieren}}&lt;br /&gt;
    sei();&lt;br /&gt;
 &lt;br /&gt;
    {{ccomment|Interrupts abschalten}}&lt;br /&gt;
    cli();&lt;br /&gt;
Sperrt man eine Code-Sequenz durch Einschachteln in ein &amp;lt;tt&amp;gt;cli&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;sei&amp;lt;/tt&amp;gt; Paar (man macht das Codestück &amp;quot;atomar&amp;quot;, also ununterbrechbar), gehen währenddessen keine Interrupt-Anforderungen verloren. Die entsprechenden IRQ-Flags bleiben gesetzt, und nach dem &amp;lt;tt&amp;gt;sei&amp;lt;/tt&amp;gt; werden die IRQs in der Reihenfolge ihrer Prioritäten abgearbeitet. Ausnahme ist, wenn in einem atomaren Block der selbe IRQ mehrfach auftritt. Der ISR-Code wird dann trotzdem nur einmal ausgeführt.&lt;br /&gt;
&lt;br /&gt;
===default Interrupt===&lt;br /&gt;
&lt;br /&gt;
Für nicht implementierte Interrupts macht avr-gcc in die Vektortabelle einen Eintrag,&lt;br /&gt;
der zu &amp;lt;tt&amp;gt;__bad_interrupt&amp;lt;/tt&amp;gt; (definiert im Startup-Code &amp;lt;tt&amp;gt;crt*.o&amp;lt;/tt&amp;gt;) springt&lt;br /&gt;
und von dort aus weiter zu Adresse&amp;amp;nbsp;0. &lt;br /&gt;
Dadurch läuft der AVR wieder von neuem los, wenn ein Interrupt auftritt, &lt;br /&gt;
zu dem man keine ISR definiert hat &lt;br /&gt;
&amp;amp;#150; allerdings ohne die Hardware zurückzusetzen wie bei einem echten Reset.&lt;br /&gt;
&lt;br /&gt;
Möchte man diesen Fall abfangen, dann geht das über eine globale Funktion &lt;br /&gt;
namens &amp;lt;tt&amp;gt;__vector_default&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SIGNAL (__vector_default)&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Damit wird von &amp;lt;tt&amp;gt;__bad_interrupt&amp;lt;/tt&amp;gt; aus nicht nach Adresse&amp;amp;nbsp;0 gesprungen,&lt;br /&gt;
sondern weiter zu &amp;lt;tt&amp;gt;__vector_default&amp;lt;/tt&amp;gt;, welches durch &amp;lt;tt&amp;gt;SIGNAL&amp;lt;/tt&amp;gt; oder&lt;br /&gt;
&amp;lt;tt&amp;gt;INTERRUPT&amp;lt;/tt&amp;gt; den üblichen ISR-Prolog/Epilog bekommt.&lt;br /&gt;
&lt;br /&gt;
So kann man z.B. eine Meldung ausgeben, eine Warnlampe blinken, in einer Endlosschleife landen, oder über den [[Watchdog]] einen richtigen Hardware-Reset auslösen, siehe auch Abschnitt &amp;quot;[[#Reset auslösen|Reset auslösen]]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===ISR mit eigenem Prolog/Epilog===&lt;br /&gt;
&lt;br /&gt;
Wenn man in einer ISR komplett eigenes Zeug machen will, &lt;br /&gt;
dann definiert man eine nackte Funktion.&lt;br /&gt;
Mit &amp;lt;tt&amp;gt;naked&amp;lt;/tt&amp;gt; befreit man die Routine vom Standard-Prolog/Epilog.&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Dabei ist darauf zu achten, daß die ISR mit &amp;lt;tt&amp;gt;reti&amp;lt;/tt&amp;gt; (return from interrupt) &lt;br /&gt;
zurückkehrt und evtl. verwendete Register und den Status (&amp;lt;tt&amp;gt;SREG&amp;lt;/tt&amp;gt;) sichert.&lt;br /&gt;
}}&lt;br /&gt;
 #include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void __attribute__ ((naked)) &lt;br /&gt;
 SIG_OVERFLOW0 (void)&lt;br /&gt;
 {&lt;br /&gt;
    {{ccomment|Port B.6 &amp;amp;#61; 0}}&lt;br /&gt;
    {{ccomment|Diese Instruktion verändert nicht das SREG und kein anderes Register}}&lt;br /&gt;
    {{ccomment|so daß der eigentliche Code nur 1 Befehl lang ist}}&lt;br /&gt;
    __asm__ __volatile (&lt;br /&gt;
       &amp;quot;cbi %0, %1&amp;quot; &amp;quot;\n\t&amp;quot;&lt;br /&gt;
       &amp;quot;reti&amp;quot;&lt;br /&gt;
          : &lt;br /&gt;
          : &amp;quot;M&amp;quot; (_SFR_IO_ADDR (PORTB)), &amp;quot;i&amp;quot; (6)&lt;br /&gt;
    );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Siehe auch [[Inline-Assembler in avr-gcc]].&lt;br /&gt;
Die ISR sieht dann so aus:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
__vector_9:&lt;br /&gt;
   c6 98        cbi   0x18, 6&lt;br /&gt;
   18 95        reti&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wiederum kann man als Funktionsname &amp;lt;tt&amp;gt;__vector_default&amp;lt;/tt&amp;gt; nehmen,&lt;br /&gt;
um nicht-implementierte IRQs abzufangen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void __attribute__ ((naked)) &lt;br /&gt;
__vector_default (void)&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==SRAM, Flash, EEPROM: Datenablage am Beispiel Strings==&lt;br /&gt;
Die Programmiersprache C kennt selber keine Strings; das einzige, was C bekannt ist, ist der Datentyp &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, der ein einzelnes Zeichen repräsentiert. &lt;br /&gt;
===Darstellung in C===&lt;br /&gt;
Ein String im Sinne von C ist ein Array von Charactern bzw. ein Zeiger auf den Anfang des Arrays. Die einzelnen Zeichen folgen im Speicher direkt aufeinander und werden in aufsteigenden Adressen gespeichert. Am String-Ende folgt als Abschluss der Character &amp;lt;tt&amp;gt;'\0'&amp;lt;/tt&amp;gt;, um das Ende zu kennzeichnen. Dies ist besonders bei der Berechnung des Speicherplatzes für Strings zu berücksichtigen, denn für die 0 muss auch Platz reserviert werden.&lt;br /&gt;
&lt;br /&gt;
===Bestimmen der Stringlänge===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 /* Bestimmt die Laenge des Strings ohne die abschliessende '\0' zu zaehlen */&lt;br /&gt;
 unsigned int strlength (const char *str)&lt;br /&gt;
 {&lt;br /&gt;
   unsigned int len = 0;&lt;br /&gt;
   &lt;br /&gt;
   while (*str++)&lt;br /&gt;
      len++;&lt;br /&gt;
   &lt;br /&gt;
   return len;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Stringlänge kann auch mit der Standard-Funktion &amp;lt;tt&amp;gt;strlen&amp;lt;/tt&amp;gt; bestimmt werden, deren Prototyp sich in &amp;lt;tt&amp;gt;string.h&amp;lt;/tt&amp;gt; befindet:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 size_t strlen (const char*);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===String im Flash belassen===&lt;br /&gt;
Oftmals werden Strings nur zu Ausgabezwecken verwendet und nicht verändert. Verwendet man Sequenzen der Gestalt&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 char *str1 = &amp;quot;Hallo Welt!&amp;quot;;&lt;br /&gt;
 char str2[] = &amp;quot;Hallo Welt!&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
dann werden die Strings im SRAM abgelegt. Im Startup-Code werden die Strings vom Flash ins SRAM kopiert und belegen daher sowohl Platz im SRAM als auch im Flash. Wird ein String nicht verändert, braucht er nicht ins SRAM kopiert zu werden. Das spart Platz im knapp bemessenen SRAM. Allerdings muss anders auf den String zugegriffen werden, denn wegen der Harvard-Architektur des AVR-Kerns kann avr-gcc anhand der Adresse nicht unterscheiden, ob diese ins SRAM, ins Flash oder ins EEPROM zeigt.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 const prog_char str3[] = &amp;quot;Hallo Welt!&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
 unsigned int strlen_P (const prog_char *str)&lt;br /&gt;
 {&lt;br /&gt;
    unsigned int len = 0;&lt;br /&gt;
 &lt;br /&gt;
    while (1)&lt;br /&gt;
    {&lt;br /&gt;
       char c = (char) pgm_read_byte (str);&lt;br /&gt;
       if ('\0' == c)&lt;br /&gt;
          return len;&lt;br /&gt;
       len++;&lt;br /&gt;
       str++; &lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void foo()&lt;br /&gt;
 {&lt;br /&gt;
    unsigned int len;&lt;br /&gt;
    len = strlen_P (str3);&lt;br /&gt;
    len = strlen_P (PSTR(&amp;quot;String im Flash&amp;quot;));&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===String ins EEPROM legen===&lt;br /&gt;
Dies geht nach dem gleichen Muster, nach dem Strings ins Flash gelegt werden. Der Zugriff wird vergleichsweise langsam, denn der EEPROM ist langsamer als SRAM bzw. Flash.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #include &amp;lt;avr/eeprom.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 const char str4[] __attribute__ ((section(&amp;quot;.eeprom&amp;quot;))) = &amp;quot;Hallo Welt!&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
 unsigned int strlen_EE (const char *str)&lt;br /&gt;
 {&lt;br /&gt;
    unsigned int len = 0;&lt;br /&gt;
 &lt;br /&gt;
    while (1)&lt;br /&gt;
    {&lt;br /&gt;
       char c = (char) eeprom_read_byte (str);&lt;br /&gt;
       if ('\0' == c)&lt;br /&gt;
          return len;&lt;br /&gt;
       len++;&lt;br /&gt;
       str++; &lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reset auslösen==&lt;br /&gt;
Falls ein Reset per Software ausgelöst werden soll, dann geht das am besten über den [[Watchdog]].&lt;br /&gt;
Einfach nur an den RESET-Punkt an Adresse&amp;amp;nbsp;0 zu springen mit&lt;br /&gt;
 goto *((void**) 0);&lt;br /&gt;
initialisiert zwar den Controller von neuem, aber es macht keinen wirkliches RESET mit Zurücksetzen der Hardware und allen I/O-Registern. &lt;br /&gt;
&lt;br /&gt;
Durch den Watchdog kann man ein 'richtiges' RESET-Signal erzeugen lassen, so daß die AVR-Hardware genau so initialisiert ist, wie nach einem externen RESET. So kann man z.B. via [[UART]] ein RESET-Kommando schicken. Allerdings lässt sich der Watchdog nur minimal auf 15ms einstellen:&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;avr/wdt.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
 ...   &lt;br /&gt;
    cli();                     {{ccomment|Interrupts global abschalten}}&lt;br /&gt;
    wdt_enable (WDTO_15MS);    {{ccomment|Watchdog aufziehen auf 15ms}}&lt;br /&gt;
    while (1);                 {{ccomment|warten, bis er zubeisst...}}&lt;br /&gt;
&lt;br /&gt;
Welches Ereignis einen RESET ausgelöst hat, kann man im Register '''MCUCSR''' (''MCU Control and Status Register'') erfahren. Es gibt 4 mögliche RESET-Quellen:&lt;br /&gt;
* Power-On Reset&lt;br /&gt;
* External Reset&lt;br /&gt;
* Brown-Out Reset&lt;br /&gt;
* Watchdog Reset&lt;br /&gt;
&lt;br /&gt;
Soll der Inhalt von Variablen einen Reset überleben &amp;amp;ndash; eine Variable also nicht initialisiert werden &amp;amp;ndash; dann geht das so:&lt;br /&gt;
 #include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment| status informiert z.B. darüber, ob wir selber den Watchdog ausgelöst haben }}&lt;br /&gt;
 {{ccomment| oder nicht, oder andere Informationen }}&lt;br /&gt;
 unsigned char status __attribute__ ((section (&amp;quot;.noinit&amp;quot;)));&lt;br /&gt;
 &lt;br /&gt;
 void main (void)&lt;br /&gt;
 {&lt;br /&gt;
     {{ccomment|Wert von MCUSCR merken, möglichst früh im Programm }}&lt;br /&gt;
     unsigned char mcucsr = MCUCSR;&lt;br /&gt;
 &lt;br /&gt;
     {{ccomment|MCUCSR zurücksetzen }}&lt;br /&gt;
     MCUCSR = 0;&lt;br /&gt;
 &lt;br /&gt;
     {{ccomment|Watchdog-Reset }}&lt;br /&gt;
     if (mcuscr &amp;amp; (1 &amp;lt;&amp;lt; WDRF))&lt;br /&gt;
     {&lt;br /&gt;
         {{ccomment|status auswerten }}&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     {{ccomment|Power-On Reset: status auf definierten Wert setzen }}&lt;br /&gt;
     if (mcuscr &amp;amp; (1 &amp;lt;&amp;lt; PORF))&lt;br /&gt;
     {&lt;br /&gt;
         status = 0;&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     {{ccomment|status auswerten }}&lt;br /&gt;
     ...&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Die mit&lt;br /&gt;
 #include &amp;lt;...&amp;gt;&lt;br /&gt;
angegebenen Includes werden von avr-gcc in den &lt;br /&gt;
mit der Option '&amp;lt;tt&amp;gt;-I&amp;lt;/tt&amp;gt;' anegegenen Pfaden gesucht. &lt;br /&gt;
Dem Compiler bekannt sind die Pfade &lt;br /&gt;
 &amp;lt;GCC_HOME&amp;gt;/avr/include                           Standard               (stdio.h, ...)&lt;br /&gt;
 &amp;lt;GCC_HOME&amp;gt;/avr/include/avr                       AVR-spezifisch         (avr/io.h, ...)&lt;br /&gt;
 &amp;lt;GCC_HOME&amp;gt;/lib/gcc/avr/&amp;lt;GCC_VERSION&amp;gt;/include     Standard, compilerabh. (limits.h, ...)&lt;br /&gt;
&lt;br /&gt;
Gibt man z.B. an &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
dann wird automatisch in diesem Verzeichnis nach &amp;lt;tt&amp;gt;stdio.h&amp;lt;/tt&amp;gt; gesucht.&lt;br /&gt;
In den Verzeichnissen stehen Standard-Includes, die benötigt werden, wenn man libc-Funktionen &lt;br /&gt;
oder mathematische Funktionen etc. verwendet. &lt;br /&gt;
AVR-spezifische Dinge stehen im Unterverzeichnis &amp;lt;tt&amp;gt;avr&amp;lt;/tt&amp;gt;, etwa:&lt;br /&gt;
 #include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Als Pfad-Separator wird immer ein '''&amp;lt;tt&amp;gt;/&amp;lt;/tt&amp;gt;''' verwendet, auch auf Windows-Betriebssystemen! Also kein '''&amp;lt;tt&amp;gt;\&amp;lt;/tt&amp;gt;'''&amp;amp;nbsp;!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Standard==&lt;br /&gt;
&lt;br /&gt;
 ctype.h                   Zeichen-Umwandlungs-Makros und ctype Makros&lt;br /&gt;
 errno.h                   Symbolische Namen für Fehlercodes&lt;br /&gt;
 inttypes.h                Definiert [u]intN_t wenn man genau N [un]signed Bits &lt;br /&gt;
                           braucht, ISO C99.&lt;br /&gt;
 math.h                    Mathematische Funktionen: sin, cos, log, gamma, bessel, ...&lt;br /&gt;
 setjmp.h                  libc unterstützt setjmp() und longjmp(), um direkt in eine&lt;br /&gt;
                           andere (nicht-lokale) Funktion zu springen. &lt;br /&gt;
 stdio.h                   Standard I/O-Funktionen (printf, ...).&lt;br /&gt;
 stdlib.h                  Deklariert grundlegende ISO C-Makros und -Funktionen &lt;br /&gt;
                           sowie einige AVR-spezifische Erweiterungen&lt;br /&gt;
 string.h                  Stringoperationen auf NULL-terminierten Strings. (strlen, ...)&lt;br /&gt;
 stdarg.h                  Funktionen mit variabler Argumenanzahl&lt;br /&gt;
 limits.h                  Min- und Max-Werte von Skalaren (UCHAR_MAX, LONG_MIN, ...)&lt;br /&gt;
&lt;br /&gt;
==AVR-spezifisch==&lt;br /&gt;
&lt;br /&gt;
Die AVR-spezifischen Includes finden sich wie gesagt im Unterverzeichnis &amp;lt;tt&amp;gt;avr&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Die meisten dort befindlichen Header wird man nie direkt durch Angabe im C-File erhalten,&lt;br /&gt;
sondern durch Angabe von&lt;br /&gt;
 #include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
Dadurch werden z.B. genau die I/O-Header eingebunden, die zum AVR-Modell passen, also&lt;br /&gt;
*&amp;lt;tt&amp;gt;avr/iom8.h&amp;lt;/tt&amp;gt; für [[ATmega8]], &lt;br /&gt;
*&amp;lt;tt&amp;gt;avr/iotn2313.h&amp;lt;/tt&amp;gt; für [[ATtiny2313]], &lt;br /&gt;
*&amp;lt;tt&amp;gt;avr/io2313.h&amp;lt;/tt&amp;gt; für [[AT90S2313]], etc. &lt;br /&gt;
&lt;br /&gt;
Verantwortlich dafür ist der Schalter '&amp;lt;tt&amp;gt;-mmcu=xxx&amp;lt;/tt&amp;gt;'.&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Header nicht explizit angegeben werden müssen, &lt;br /&gt;
kann ein Blick dorthin hilfreich sein, um die Namen von [[SFR|SFRs]] &lt;br /&gt;
oder Signals nachzuschlagen. &lt;br /&gt;
Diese Header werden im folgenden nicht alle einzeln aufgelistet. &lt;br /&gt;
Ihre Namen sind immer &amp;lt;tt&amp;gt;avr/io*.h&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* für ATmega: &amp;lt;tt&amp;gt;avr/iom*.h&amp;lt;/tt&amp;gt; &lt;br /&gt;
* für ATtiny: &amp;lt;tt&amp;gt;avr/iotn*.h&amp;lt;/tt&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
avr/boot.h            Bootloader Support&lt;br /&gt;
avr/crc16.h           [*] Prüfsumme CRC16&lt;br /&gt;
avr/delay.h           [*] Verzögerungsschleifen für kurze, exakte Verzögerungen&lt;br /&gt;
avr/eeprom.h          EEPROM-Routinen&lt;br /&gt;
avr/ina90.h           Kompatibilität mit IAR-AVR-Compiler&lt;br /&gt;
avr/interrupt.h       sei(), cli(), ...&lt;br /&gt;
avr/io.h              --&amp;gt; inttypes.h, io*.h&lt;br /&gt;
avr/io*.h             SFRs, SIG_****, SPM_PAGESIZE, RAMEND, XRAMEND, E2END, FLASHEND&lt;br /&gt;
avr/parity.h          [*] Parität&lt;br /&gt;
avr/pgmspace.h        Zugriff aufs Flash: Byte lesen, PROGMEM, prog_char, prog_uint8_t, ...&lt;br /&gt;
avr/portpins.h        Makros für Port-Pins&lt;br /&gt;
avr/signal.h          [**] Makros SIGNAL() und INTERRUPT(), ...&lt;br /&gt;
avr/sleep.h           Power-Safe&lt;br /&gt;
avr/twi.h             [*] I2C&lt;br /&gt;
avr/wdt.h             Watchdog&lt;br /&gt;
 &lt;br /&gt;
util/crc16.h          Prüfsumme CRC16&lt;br /&gt;
util/delay.h          Verzögerungsschleifen für kurze, exakte Verzögerungen &lt;br /&gt;
util/parity.h         Parität&lt;br /&gt;
util/twi.h            I2C&lt;br /&gt;
 &lt;br /&gt;
[*]  bei neueren avr-gcc-Versionen in util&lt;br /&gt;
[**] entfällt bei neueren avr-gcc-Versionen. Stattdessen avr/interrupt.h verwenden&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Anwendungs-spezifisch==&lt;br /&gt;
Eigene Header, die nur innerhalb eigener Projekte gebraucht werden, includet man mit&lt;br /&gt;
 #include &amp;quot;...&amp;quot;&lt;br /&gt;
Auch hier darf man Unterverzeichnisse angeben oder ins übergeordnete Verzeichnis:&lt;br /&gt;
 #include &amp;quot;../../mein-zeug.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Optimierungen, Tipps &amp;amp; Tricks=&lt;br /&gt;
&lt;br /&gt;
Beim Programmieren in C möchte man sich möglichst wenig mit der Codeerzeugung selbst auseinandersetzen. Man verwendet ja gerade deshalb einen Compiler und programmiert nicht in Assembler, weil man sich nicht um Register-Belegungen o.ä. kümmern will, sondern nur um die zu lösende Aufgabe.&lt;br /&gt;
&lt;br /&gt;
GCC erzeugt zwar recht guten Code, aber er ist nicht perfekt. Gerade auf Systemen wie AVR mit nur sehr begrenzten Resourcen muss man daher dem Compiler hilfreich zur Seite stehen, wenn man noch dichteren/schnelleren Code erhalten möchte.&lt;br /&gt;
&lt;br /&gt;
:''&amp;quot;Unlike most other C compilers, GCC allows you to use -g with -O. The shortcuts taken by optimized code may occasionally produce surprising results: some variables you declared may not exist at all; flow of control may briefly move where you did not expect it; some statements may not be executed because they compute constant results or their values were already at hand; some statements may execute in different places because they were moved out of loops.''&lt;br /&gt;
&lt;br /&gt;
:''Nevertheless it proves possible to debug optimized output. This makes it reasonable to use the optimizer for programs that might have bugs.&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
Um das Ergebnis zu beurteilen, hilft ein Blick ins Listfile. &lt;br /&gt;
Siehe dazu auch die Abschnitte &lt;br /&gt;
&amp;quot;[[Hallo Welt für AVR (LED blinken)#Listfile erstellen|Listfile erstellen]]&amp;quot; &lt;br /&gt;
und&lt;br /&gt;
&amp;quot;[[Hallo Welt für AVR (LED blinken)#Die Größe ermitteln|Die Größe ermitteln]]&amp;quot; &lt;br /&gt;
im [[Hallo Welt für AVR (LED blinken)|Hallo Welt für AVR]].&lt;br /&gt;
&lt;br /&gt;
==Optimierungsgrad==&lt;br /&gt;
Als Optimierungsgrad erweist sich &amp;lt;tt&amp;gt;-Os&amp;lt;/tt&amp;gt; (Optimize for Size) als der beste, evtl. noch &amp;lt;tt&amp;gt;-O2&amp;lt;/tt&amp;gt;. Ohne Angabe eines Optimierungsgrades wird nicht optimiert, was gleichbedeutend mit der Option &amp;lt;tt&amp;gt;-O0&amp;lt;/tt&amp;gt; ist. Abzuraten ist von der maximalen Optimierung &amp;lt;tt&amp;gt;-O3&amp;lt;/tt&amp;gt;, die wegen function inlining und loop unrolling zu sehr breitem Code führt und für AVR absolut nicht angesagt ist.&lt;br /&gt;
&lt;br /&gt;
==Vermeide printf, scanf, malloc==&lt;br /&gt;
Funktionen von diesem Kaliber sind die absoluten Platz- und Zeitfresser. &lt;br /&gt;
&lt;br /&gt;
Alternativen findet man reichlich in der &amp;lt;tt&amp;gt;avr-libc&amp;lt;/tt&amp;gt; wie &amp;lt;tt&amp;gt;itoa&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;atoi&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Und für &amp;lt;tt&amp;gt;malloc&amp;lt;/tt&amp;gt; und Konsorten sind dynamische Arrays und das Compiler-Builtin &amp;lt;tt&amp;gt;__builtin_alloca&amp;lt;/tt&amp;gt; effizientere Alternativen, siehe auch im Abschnitt &amp;quot;[[avr-gcc#Dynamische Speicherallokierung|Dynamische Speicherallokierung]]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Konstante Strings ins Flash== &lt;br /&gt;
Konstante Strings, wie sie zu Ausgabezwecken Verwendung finden, werden im Programm oft nicht verändert und brauchen nicht SRAM zu belegen (und damit auch Flash, von wo aus sie vom Startup-Code ins SRAM kopiert werden), sondern gehören ins Flash! &lt;br /&gt;
&lt;br /&gt;
Entsprechende Routinen, um auf Strings im Flash zuzugreifen, tragen die Suffix &amp;lt;tt&amp;gt;_P&amp;lt;/tt&amp;gt;, wie z.B. &amp;lt;tt&amp;gt;strcmp_P&amp;lt;/tt&amp;gt; mit dem Prototyp&lt;br /&gt;
 extern int *strcmp_P (char *, const prog_char *)&lt;br /&gt;
Die Implementierungen befinden sich in der &amp;lt;tt&amp;gt;avr-libc&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Anwendung:'''&lt;br /&gt;
 #include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 const prog_char str_p[]     = &amp;quot;Ein String im Flash&amp;quot;;&lt;br /&gt;
 const char str2_p[] PROGMEM = &amp;quot;Noch ein String im Flash&amp;quot;;&lt;br /&gt;
 ...&lt;br /&gt;
   {{ccomment|String im SRAM mit String im Flash vergleichen}}&lt;br /&gt;
   if (!strcmp_P (str_sram, str_p))&lt;br /&gt;
   {&lt;br /&gt;
       {{ccomment|mach was bei Gleichheit}}&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
   {{ccomment|&amp;quot;foo&amp;quot; wird im RAM angelegt. Ineffizient für konstante Strings!}}  &lt;br /&gt;
   {{ccomment|Beachte, daß damit strcmp (nicht strcmp_P) benutzt werden muss.}}  &lt;br /&gt;
   if (!strcmp (str_sram, &amp;quot;foo&amp;quot;))&lt;br /&gt;
   {&lt;br /&gt;
       {{ccomment|mach was bei Gleichheit}}&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
   {{ccomment|PSTR bewirkt, daß die String-Konstante &amp;quot;foo&amp;quot;}}&lt;br /&gt;
   {{ccomment|im Flash angelegt wird}}&lt;br /&gt;
   if (!strcmp_P (str_sram, PSTR (&amp;quot;foo&amp;quot;))&lt;br /&gt;
   {&lt;br /&gt;
       {{ccomment|mach was bei Gleichheit}}&lt;br /&gt;
   }&lt;br /&gt;
 ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Sprungtabelle===&lt;br /&gt;
Genauso macht man auch eine Sprungtabelle, um anhand von Kommando-Strings dazugehörige Funktionen ausführen zu lassen:&lt;br /&gt;
 #include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 int func1 (int arg)&lt;br /&gt;
 {&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 #define TEXT_LEN 15&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Die Kommandostruktur}}&lt;br /&gt;
 typedef struct &lt;br /&gt;
 {&lt;br /&gt;
    int (*func)(int);      {{ccomment|Zeiger auf die auszuführende Funktion}}&lt;br /&gt;
    int arg;               {{ccomment|das Argument, das mitübergeben wird}}&lt;br /&gt;
    char text[1+TEXT_LEN]; {{ccomment|Text, maximal TEXT_LEN Zeichen lang}}&lt;br /&gt;
 } command_t;&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Das Array mit den Kommandos.}}&lt;br /&gt;
 {{ccomment|Die funcx sind vom Prototyp (z.B. func1 oben)}}&lt;br /&gt;
 {{ccomment|int funcx (int arg);}}&lt;br /&gt;
 const command_t commands[] PROGMEM =&lt;br /&gt;
 {&lt;br /&gt;
    { func1, 0, &amp;quot;Befehl 1&amp;quot; },&lt;br /&gt;
    { func2, 3, &amp;quot;Befehl für func2&amp;quot; }&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Sucht in commands[] nach text und führt gegebenenfalls}}&lt;br /&gt;
 {{ccomment|die dazugehörige Funktion funcx mit Argument arg aus.}}&lt;br /&gt;
 {{ccomment|Liefert den Rückgabewert von funcx}}&lt;br /&gt;
 {{ccomment|oder -1, falls text nicht gefunden wurde.}}&lt;br /&gt;
 int execute (const char *text)&lt;br /&gt;
 {&lt;br /&gt;
    {{ccomment|Schleifenvariable}}&lt;br /&gt;
    unsigned char i;&lt;br /&gt;
 &lt;br /&gt;
    {{ccomment|Wandert durch das Array mit Kommando-Strukturen}}&lt;br /&gt;
    const command_t * cmd = commands;&lt;br /&gt;
 &lt;br /&gt;
    {{ccomment|sizeof wird von gcc ausgewertet und ist wie eine Konstante,}}&lt;br /&gt;
    {{ccomment|denn beide sizeofs sind zur Compilezeit bekannt}}&lt;br /&gt;
    for (i=0; i &amp;lt; sizeof(commands) / sizeof(command_t); i++)&lt;br /&gt;
    {&lt;br /&gt;
       {{ccomment|Ist das der gesuchte String?}} &lt;br /&gt;
       if (strcmp_P (text, cmd-&amp;gt;text))&lt;br /&gt;
       {&lt;br /&gt;
         {{ccomment|Nein, dann weitersuchen}}&lt;br /&gt;
         cmd++;&lt;br /&gt;
         continue;&lt;br /&gt;
       }&lt;br /&gt;
 &lt;br /&gt;
       {{ccomment|Ja}}&lt;br /&gt;
       int (*func)(int), arg;&lt;br /&gt;
 &lt;br /&gt;
       {{ccomment|Dann Funktionszeiger und Argument besorgen,}}&lt;br /&gt;
       func = (int(*)(int)) pgm_read_word (&amp;amp; cmd-&amp;gt;func);&lt;br /&gt;
       arg  = (int)         pgm_read_word (&amp;amp; cmd-&amp;gt;arg);&lt;br /&gt;
 &lt;br /&gt;
       {{ccomment|Funktion ausführen und deren Wert zurückliefern}} &lt;br /&gt;
       return func (arg);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    {{ccomment|text ist nicht in commands}}&lt;br /&gt;
    return -1;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Nachteil dabei ist, daß jeder String den maximalen Platz von &amp;lt;tt&amp;gt;TEXT_LEN+1&amp;lt;/tt&amp;gt; Zeichen belegt.&lt;br /&gt;
Falls man da noch weiter sparen will, dann kann man die Strings wieder ins Flash legen und ihre Adresse in der Struktur merken. Dadurch belegt ein String nur noch Länge+3 Zeichen (+3 wegen 1 Endezeichen und 2 Bytes für seine in der Struktur gemerkte Adresse). Die Definition der Tabelle wird aber umständlicher, weil jeder String einzeln angegeben werden muss:&lt;br /&gt;
 #include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Die Kommandostruktur}}&lt;br /&gt;
 typedef struct &lt;br /&gt;
 {&lt;br /&gt;
    ...&lt;br /&gt;
    char * text;  {{ccomment|Zeiger auf Text}}&lt;br /&gt;
 } command_t;&lt;br /&gt;
 &lt;br /&gt;
 const prog_char str_1[] = &amp;quot;Befehl 1&amp;quot;;&lt;br /&gt;
 const prog_char str_2[] = &amp;quot;Befehl für func2&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
 const command_t commands[] PROGMEM =&lt;br /&gt;
 {&lt;br /&gt;
    { func1, 0, str_1 },&lt;br /&gt;
    { func2, 3, str_2 }&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Sucht in commands[] nach text und führt gegebenenfalls}}&lt;br /&gt;
 {{ccomment|die dazugehörige Funktion funcx mit Argument arg aus.}}&lt;br /&gt;
 {{ccomment|Liefert den Rückgabewert von funcx}}&lt;br /&gt;
 {{ccomment|oder -1, falls text nicht gefunden wurde.}}&lt;br /&gt;
 int execute (const char *text)&lt;br /&gt;
 {&lt;br /&gt;
    {{ccomment|Schleifenvariable}}&lt;br /&gt;
    unsigned char i;&lt;br /&gt;
 &lt;br /&gt;
    {{ccomment|Wandert durch das Array mit Kommando-Strukturen}}&lt;br /&gt;
    const command_t * cmd = commands;&lt;br /&gt;
 &lt;br /&gt;
    {{ccomment|sizeof wird von gcc ausgewertet und ist wie eine Konstante,}}&lt;br /&gt;
    {{ccomment|denn beide sizeofs sind zur Compilezeit bekannt}}&lt;br /&gt;
    for (i=0; i &amp;lt; sizeof(commands) / sizeof (command_t); i++)&lt;br /&gt;
    {&lt;br /&gt;
       const prog_char * text_P;&lt;br /&gt;
 &lt;br /&gt;
       {{ccomment|Liest die Startadresse von str_x}}&lt;br /&gt;
       text_P = (const prog_char *) pgm_read_word (&amp;amp; cmd-&amp;gt;text);&lt;br /&gt;
 &lt;br /&gt;
       {{ccomment|Ist das der gesuchte String?}}        &lt;br /&gt;
       if (strcmp_P (text, text_P))&lt;br /&gt;
       {&lt;br /&gt;
          ...&lt;br /&gt;
&lt;br /&gt;
==Lokale Variablen verwenden==&lt;br /&gt;
&lt;br /&gt;
Beim Manipulieren globaler Variablen kann es günstig sein, diese in eine lokale Variable zu kopieren, dort zu verändern, und sie danach wieder zu schreiben &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
char var;&lt;br /&gt;
&lt;br /&gt;
void foo1()&lt;br /&gt;
{&lt;br /&gt;
   var++;&lt;br /&gt;
   if (var &amp;gt; 10)&lt;br /&gt;
      var = 1;&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dadurch wird einmal unnötig gespeichert (der dritte Befehl kann vermieden werden).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
foo1:&lt;br /&gt;
  lds r24,var        ; *movqi/4 [length = 2]&lt;br /&gt;
  subi r24,lo8(-(1)) ; addqi3/2 [length = 1]&lt;br /&gt;
  sts var,r24        ; *movqi/3 [length = 2]&lt;br /&gt;
  cpi r24,lo8(11)    ; cmpqi/2  [length = 1]&lt;br /&gt;
  brlt .L3           ; branch   [length = 1]&lt;br /&gt;
  ldi r24,lo8(1)     ; *movqi/2 [length = 1]&lt;br /&gt;
  sts var,r24        ; *movqi/3 [length = 2]&lt;br /&gt;
.L3:&lt;br /&gt;
  ret   &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Indem man eine lokale Variable (&amp;lt;tt&amp;gt;var2&amp;lt;/tt&amp;gt;) verwendet für die Änderung von &amp;lt;tt&amp;gt;var&amp;lt;/tt&amp;gt; vermeidet man dies:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
char var;&lt;br /&gt;
&lt;br /&gt;
void foo2()&lt;br /&gt;
{&lt;br /&gt;
   char var2 = var;&lt;br /&gt;
   &lt;br /&gt;
   var2++;&lt;br /&gt;
   if (var2 &amp;gt; 10)&lt;br /&gt;
      var2 = 1;&lt;br /&gt;
      &lt;br /&gt;
   var = var2;&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dadurch wird erst am Ende gespeichert. &amp;lt;tt&amp;gt;var2&amp;lt;/tt&amp;gt; lebt in Register &amp;lt;tt&amp;gt;r24&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
foo2:&lt;br /&gt;
  lds r24, var       ; *movqi/4   [length = 2]&lt;br /&gt;
  subi r24,lo8(-(1)) ; addqi3/2   [length = 1]&lt;br /&gt;
  cpi r24,lo8(11)    ; cmpqi/2    [length = 1]&lt;br /&gt;
  brlt .L2           ; branch     [length = 1]&lt;br /&gt;
  ldi r24,lo8(1)     ; *movqi/2   [length = 1]&lt;br /&gt;
.L2:&lt;br /&gt;
  sts var, r24       ; *movqi/3   [length = 2]&lt;br /&gt;
  ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei diesem einfachen Beispiel spart man lediglich eine Instruktion. Bei komplexeren Rechnungen oder längeren Datentypen kann es aber durchaus lohnender sein, in lokale Register zu kopieren.&lt;br /&gt;
&lt;br /&gt;
==Arithmetik==&lt;br /&gt;
&lt;br /&gt;
=== Daten zerlegen/zusammensetzen ===&lt;br /&gt;
&lt;br /&gt;
In systemnahen Programmen hat man oft was Problem, auf die einzelnen Bytes oder Bitfelder einer grösseren Datenstruktur zuzugreifen. Indem man sich ein Komposit baut, das die gewünschten Strukturen überlagert, kann man effizient z.B. auf Bytes zugreifen. Ausnahme sind Bitfelder, deren Verwendung etwas breiten Code ergibt. Bitfelder &amp;quot;von Hand&amp;quot; zu manipulieren, ist da manchmal effizienter, führt jedoch zu schlecht lesbarem Code.&lt;br /&gt;
&lt;br /&gt;
Oft benötigt wird der Zugriff auf die einzelnen Bytes eines &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, also der Zugriff auf die Bytes eines 16-Bit-Wertes:&lt;br /&gt;
&lt;br /&gt;
 typedef union&lt;br /&gt;
 {&lt;br /&gt;
    unsigned char  asByte[2];&lt;br /&gt;
    unsigned short asWord;&lt;br /&gt;
    int            asInt;&lt;br /&gt;
 } data16_t;&lt;br /&gt;
 &lt;br /&gt;
 data16_t data;&lt;br /&gt;
 ...&lt;br /&gt;
    int foo;&lt;br /&gt;
    uint8_t wert;&lt;br /&gt;
 &lt;br /&gt;
    data.asInt = foo;&lt;br /&gt;
    wert = data.asByte[1]; {{ccomment|die oberen 8 Bits von foo}}&lt;br /&gt;
&lt;br /&gt;
Ein komplexeres Beispiel, das noch mehr Datentypen überlagert:&lt;br /&gt;
 typedef ... foo_t;&lt;br /&gt;
 &lt;br /&gt;
 typedef union&lt;br /&gt;
 {&lt;br /&gt;
     unsigned char byte[4];      {{ccomment| Zugriff als Bytes (8 Bit) }}&lt;br /&gt;
     unsigned short word[2];     {{ccomment| Zugriff als Words (16 Bit) }}&lt;br /&gt;
     signed long slong;          {{ccomment| Zugriff als signed long (32 Bit) }}&lt;br /&gt;
 &lt;br /&gt;
     struct {{ccomment| Zugriff auf einzelne Bitgruppen }}&lt;br /&gt;
     {&lt;br /&gt;
         unsigned bit_0_3 : 4;   {{ccomment| 4 Bits (0..3) }}&lt;br /&gt;
         unsigned bit_4_8 : 5;   {{ccomment| 5 Bits (4..8) }}&lt;br /&gt;
         unsigned bit_9_21 : 13; {{ccomment| 13 Bits (9..21) }}&lt;br /&gt;
         unsigned bit_22_31: 10; {{ccomment| 10 Bits (22..31) }}&lt;br /&gt;
     };&lt;br /&gt;
 &lt;br /&gt;
     foo_t foo; {{ccomment| Zugriff als foo-Struktur }}&lt;br /&gt;
 } data_t;&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 {&lt;br /&gt;
     data_t data;&lt;br /&gt;
 &lt;br /&gt;
     data.byte[2] = 12;          {{ccomment| setzt byte 2 auf 12 }}&lt;br /&gt;
     data.bit_4_8 = 0x1f;        {{ccomment| setzt bits 4..8 (5 Stück) alle auf 1 }}&lt;br /&gt;
 &lt;br /&gt;
     int anInt = data.foo.anInt; {{ccomment| liest ein Feld von foo (hier ein int) }}&lt;br /&gt;
     ...&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
===libgcc2 verwenden===&lt;br /&gt;
&lt;br /&gt;
In der libgcc2 sind einige Arithmetik-Routinen in Assembler implementiert. Dazu gehören ein paar Algorithmen zu Division (mit Rest) und Multiplikation. &lt;br /&gt;
&lt;br /&gt;
Von diesen Algorithmen werden durch die avr-libc jedoch nur zwei Strukturen und Funktionen veröffentlicht: &amp;lt;tt&amp;gt;div_t&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;ldiv_t&amp;lt;/tt&amp;gt; resp. die Funktionen &amp;lt;tt&amp;gt;div()&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;ldiv()&amp;lt;/tt&amp;gt;. Siehe dazu deine Dokumentation zur avr-libc. Damit kann man Quotient und zusätzlich den Rest bei einer Division 16/16 bzw. 32/32 berechnen lassen; den Rest bekommt man quasi kostenlos als Nebenprodukt. Das ist praktisch, wenn man z.b. eine Zahl in Dezimaldarstellung umwandeln möchte oder von/nach [[BCD]].&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den via avr-libc veröffentlichten Funktionen gibt es aber noch Routinen, die z.B. auf 8-Bit-Werten operieren oder mit &amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt; Typen und dementsprechend effizienter sind.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel: Umwandeln nach Dezimalstring'''&lt;br /&gt;
&lt;br /&gt;
Hier ein Beispiel, das Division mit Rest für &amp;lt;tt&amp;gt;unsigned short&amp;lt;/tt&amp;gt; verwendet, um eine 16-Bit-Zahl in Dezimaldarstellung zu wandeln:&lt;br /&gt;
&lt;br /&gt;
 {{ccomment| Struktur definieren und Funktion bekannt machen }}&lt;br /&gt;
 typedef struct&lt;br /&gt;
 {&lt;br /&gt;
     unsigned short quot;&lt;br /&gt;
     unsigned short rem;&lt;br /&gt;
 } udiv_t;&lt;br /&gt;
 &lt;br /&gt;
 extern udiv_t udiv (unsigned short, unsigned short) __asm__(&amp;quot;__udivmodhi4&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment| 5 Ziffern (0...65535) und evtl. noch eine führende 0 }}&lt;br /&gt;
 #define DIGITS 6&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment| +1 wegen String-Ende (wird im Startup auf 0 gesetzt) }}&lt;br /&gt;
 char string[DIGITS+1];&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment| Wandelt zahl in Dezimaldarstellung um. }}&lt;br /&gt;
 {{ccomment| Der return-Wert zeigt irgendwo ins string[]-Array. }}&lt;br /&gt;
 {{ccomment| string[] wird verändert. }}&lt;br /&gt;
 char* toString (unsigned short zahl)&lt;br /&gt;
 {&lt;br /&gt;
     {{ccomment| s zeigt auf das Ende von string }}&lt;br /&gt;
     {{ccomment| string wird von hinten nach vorne gefüllt }}&lt;br /&gt;
     char *s = string + DIGITS;&lt;br /&gt;
  &lt;br /&gt;
     {{ccomment| qrem enthält Quotient (quot) und Rest (rem) der Divisionen }}&lt;br /&gt;
     udiv_t qrem = {.quot = zahl}; &lt;br /&gt;
 &lt;br /&gt;
     do&lt;br /&gt;
     {&lt;br /&gt;
         {{ccomment| Division mit Rest durch 10 }}&lt;br /&gt;
         {{ccomment| quot: Ergebnis für den nächsten Durchlauf }}&lt;br /&gt;
         {{ccomment| rem: Rest ist die Ziffer im 10er-System }}&lt;br /&gt;
         qrem = udiv (qrem.quot, 10);&lt;br /&gt;
  &lt;br /&gt;
         {{ccomment| Ziffer in Zeichen wandeln und speichern }}&lt;br /&gt;
         *(--s) = '0' + qrem.rem;&lt;br /&gt;
     } &lt;br /&gt;
     while (0 != qrem.quot);&lt;br /&gt;
  &lt;br /&gt;
     {{ccomment| Falls eine führende '0' gespeichert wurde: weg damit }}&lt;br /&gt;
     {{ccomment| ausser zahl war selbst schon 0 }}&lt;br /&gt;
     if (*s == '0' &amp;amp;&amp;amp; *(s+1) != '\0')&lt;br /&gt;
         s++;&lt;br /&gt;
 &lt;br /&gt;
     return s;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Falls man eine Division und/oder Rest für 8-Bit braucht, dann geht für &amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt; analog. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel: BCD-Umrechnung'''&lt;br /&gt;
&lt;br /&gt;
Wandeln einer 8-Bit-Zahl &amp;lt;tt&amp;gt;0 &amp;amp;lt;= num &amp;amp;lt; 100&amp;lt;/tt&amp;gt; nach [[BCD]]&lt;br /&gt;
&lt;br /&gt;
 typedef struct&lt;br /&gt;
 {&lt;br /&gt;
     unsigned char quot; {{ccomment| Quotient }}&lt;br /&gt;
     unsigned char rem;  {{ccomment| Rest (remainder) }}&lt;br /&gt;
 } udiv8_t;&lt;br /&gt;
 &lt;br /&gt;
 extern udiv8_t udiv8 (unsigned char, unsigned char) __asm__ (&amp;quot;__udivmodqi4&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment| Wandelt num nach BCD um, 0 &amp;lt;&amp;amp;#61; num &amp;lt;&amp;amp;#61; 99 }}&lt;br /&gt;
 {{ccomment| return-Wert ist dann 0x0 &amp;lt;&amp;amp;#61; return &amp;lt;&amp;amp;#61; 0x99 }}&lt;br /&gt;
 unsigned char to_bcd (unsigned char num)&lt;br /&gt;
 {&lt;br /&gt;
     udiv8_t qrem = udiv8 (num, 10);&lt;br /&gt;
 &lt;br /&gt;
     return (unsigned char) (qrem.quot &amp;lt;&amp;lt; 4) | qrem.rem;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Division durch Multiplikation===&lt;br /&gt;
===Vermeiden von float und double===&lt;br /&gt;
&lt;br /&gt;
=Inkompatibilität=&lt;br /&gt;
&lt;br /&gt;
[[GCC]] &amp;amp;ndash; und somit auch avr-gcc &amp;amp;ndash; werden ständig weiter entwickelt. Dies betrifft das Beheben von Fehlern, die Unterstützung neuer Architekturen/Sprachen/Betriebssysteme, Implementierung neuer Optimierungsalgorithmen, Vereinheitlichungen, etc.&lt;br /&gt;
&lt;br /&gt;
Leider führt dies auch zu Inkompatibilitäten verschiedener avr-gcc-Versionen untereinander, und eine C-Quelle, die mit einer Version von avr-gcc fehler- und warnungsfrei übersetzt werden kann, ist mit einer anderen Version möglicherweise nicht compilierbar.&lt;br /&gt;
&lt;br /&gt;
Die avr-gcc Version kann man anzeigen lassen, indem man in einer Shell/Eingabeaufforderung eintippt&lt;br /&gt;
 avr-gcc -v&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;#include &amp;lt;avr/signal.h&amp;gt;&amp;lt;/tt&amp;gt;: In Versionen bis 3.4.4 werden in dieser Header-Datei u.a. die Makros &amp;lt;tt&amp;gt;SIGNAL()&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;INTERRUPT()&amp;lt;/tt&amp;gt; definiert, die man braucht, wenn man eine C-Funktion als Interrupt-Routine ([[ISR]]) kennzeichnen will. In neueren Versionen ab 3.4.5 sind diese Definitionen in den Header &amp;lt;tt&amp;gt;avr/interrupt.h&amp;lt;/tt&amp;gt; gewandert, wo auch Makros wie &amp;lt;tt&amp;gt;sei()&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;cli()&amp;lt;/tt&amp;gt; definiert werden. Die Inkludierung von &amp;lt;tt&amp;gt;avr/signal.h&amp;lt;/tt&amp;gt; in den neueren avg-gcc Versionen führt zu einer Warnung, irgendwann vielleicht sogar zu einem Fehler, weil die Datei nicht mehr bei avr-gcc dabei ist und daher nicht mehr gefunden wird.&lt;br /&gt;
: '''Verwendet man bei einer älteren avr-gcc-Version &amp;lt;tt&amp;gt;SIGNAL&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;INTERRUPT&amp;lt;/tt&amp;gt; ohne &amp;lt;tt&amp;gt;avr/signal.h&amp;lt;/tt&amp;gt; zu includen, wird u.U. stillschweigend falscher Code erzeugt.'''&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;#include &amp;lt;util/...h&amp;gt;&amp;lt;/tt&amp;gt;: In &amp;lt;tt&amp;gt;util&amp;lt;/tt&amp;gt; stehen jetzt Header wie &amp;lt;tt&amp;gt;util/parity.h&amp;lt;/tt&amp;gt; oder das vielverwendete &amp;lt;tt&amp;gt;util/delay.h&amp;lt;/tt&amp;gt;, die vormals im Include-Unterverzeichnis &amp;lt;tt&amp;gt;avr&amp;lt;/tt&amp;gt; zu finden waren.&lt;br /&gt;
&lt;br /&gt;
;Interrupt Service Routinen: Auch die API zur Definition von [[ISR]]s hat sich von avr-gcc Version 3.x zur Version 4.x geändert:&lt;br /&gt;
:'''avr-gcc 3.x'''&lt;br /&gt;
::{|&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SIGNAL (SIG_INTERRUPT0)&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt Code */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
INTERRUPT (SIG_OVERFLOW0)&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt Code */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
:'''avr-gcc 4.x'''&lt;br /&gt;
::{|&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ISR (INT0_vect)&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt Code */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void TIMER0_OVF_vect (void) __attribute__((interrupt));&lt;br /&gt;
void TIMER0_OVF_vect (void)&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt Code */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Bugs=&lt;br /&gt;
&lt;br /&gt;
==== Bit 7 bei SFR-Zugriff ====&lt;br /&gt;
&lt;br /&gt;
Bei Sequenzen wie&lt;br /&gt;
 PORTB &amp;amp;= ~ (1 &amp;lt;&amp;lt; 7);&lt;br /&gt;
 PORTD &amp;amp;= ~ (1 &amp;lt;&amp;lt; 7);&lt;br /&gt;
&lt;br /&gt;
macht avr-gcc eine CSE-Optimierung (common subexpression elimination). Er legt die Konstante 127 (&amp;lt;tt&amp;gt;~(1 &amp;lt;&amp;lt; 7)&amp;lt;/tt&amp;gt;) in ein Register und verwendet den Registerinhalt, anstatt die Konstante direkt zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Das führt dazu, daß statt der gewünschten Befehlsfolge&lt;br /&gt;
 ; Sequenz 1&lt;br /&gt;
 cbi 37-0x20, 7	&lt;br /&gt;
 cbi 43-0x20, 7&lt;br /&gt;
Sequenzen folgender Gestalt erzeugt werden:&lt;br /&gt;
 ; Sequenz 2&lt;br /&gt;
 ldi r18,     lo8(127)   ; 127 nach R18&lt;br /&gt;
 &lt;br /&gt;
 in  r19,     37-0x20    ; PORTB nach R19 lesen&lt;br /&gt;
 ; Wird hier eine ISR ausgeführt, die PORTB verändert, dann wird die&lt;br /&gt;
 ; Änderung mit dem folgenden OUT überschrieben&lt;br /&gt;
 and r19,     r18	; oberstes Bit löschen&lt;br /&gt;
 ; dito&lt;br /&gt;
 out 37-0x20, r19	; PORTB schreiben&lt;br /&gt;
 &lt;br /&gt;
 in r19,      43-0x20	; analog&lt;br /&gt;
 and r19,     r18	&lt;br /&gt;
 out 43-0x20, r19	&lt;br /&gt;
&lt;br /&gt;
Abgesehen davon, daß Sequenz&amp;amp;nbsp;2 deutlich mehr Programmspeicher und Laufzeit benötigt als Sequenz&amp;amp;nbsp;1, kann es zu folgendem Fehler kommen:&lt;br /&gt;
&lt;br /&gt;
Bei der zweiten Codesequenz erfolgt der Zugriff auf die SFRs nicht atomar. Wird der C-Code in einem Programm ausgeführt, das in einer [[ISR]] zB Port B3 verändert und wird diese ISR zwischen dem IN und dem OUT Befehl ausgeführt, dann überschreibt der OUT-Befehl den Wert von PORTB und die Aktion für Port B3 in der ISR wird wieder rückgängig gemacht. Das ist dann ein Programmfehler.&lt;br /&gt;
&lt;br /&gt;
Damit das Problem zum Tragen kommt, müssen mehrere Bedingungen erfüllt sein:&lt;br /&gt;
* Bei mindestens zwei C-Befehlen wird der Wert 127 als 8-Bit-Wert benötigt. Das ist zB auch der Fall, wenn dieser Wert nur gespeichert wird oder modulo 0x80 gerechnet wird.&lt;br /&gt;
* Mindestens einer dieser Befehle löscht Bit 7 eines SFR aus dem bitadressierbaren I/O-Bereich. (Ausser PORTx oder DDRx sind in diesem Bereich noch weitere SFR untergebracht.)&lt;br /&gt;
* Im Programm wird auf unterschiedlichen [[Interrupt]]-Ebenen auf dieses SFR zugegriffen und die oben gezeigt Stelle kann von der ISR unterbrochen werden.&lt;br /&gt;
* Die beiden C-Befehle müssen nicht unmittelbar aufeinander folgen. Es können auch andere C-Befehle dazwischen stehen. &lt;br /&gt;
&lt;br /&gt;
Bei den meisten Programmen wird das angesprochene Problem nicht zu einem Fehler führen. Falls doch, kann man dem begegnen mit folgenden &lt;br /&gt;
&lt;br /&gt;
;Workarounds:&lt;br /&gt;
* Die C-Stelle wird in CLI/SEI eingeschlossen und kann damit nicht mehr von einer ISR unterbrochen werden.&lt;br /&gt;
* Alternativ schreibt man vor und nach jedem problematischen SFR-Zugriff folgendes Kommando:&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 __asm volatile (&amp;quot;&amp;quot;::);&lt;br /&gt;
|}&lt;br /&gt;
:Dieses Kommando erzeugt keine Assembler-Instruktionen, vermeidet aber die unerwünschte &amp;quot;Optimierung&amp;quot; im gcc, und es entsteht Code gemäß Sequenz&amp;amp;nbsp;1.&lt;br /&gt;
* Alternativ definiert man sich ein Makro, mit dem man die Portzugriffe tätigt:&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 #define CBI(A,B)    __asm volatile (&amp;quot;cbi\t%0, %1&amp;quot; :: &amp;quot;M&amp;quot; (_SFR_IO_ADDR(A)), &amp;quot;M&amp;quot; (B))&lt;br /&gt;
|}&lt;br /&gt;
:Und löscht das Bit mit&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 CBI (PORTB, 7);&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;tt&amp;gt;__builtin_return_address(0)&amp;lt;/tt&amp;gt; ====&lt;br /&gt;
ist entgegen der Spezifikation nicht implementiert und liefert in der Regel ein falsches Ergebnis.&lt;br /&gt;
&lt;br /&gt;
;Workaround:&lt;br /&gt;
&lt;br /&gt;
(hier für eine ISR):&lt;br /&gt;
 #include &amp;lt;stdarg.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|The return address}}&lt;br /&gt;
 unsigned short volatile return_addr;&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Define our special SIGNAL (INTERRUPT analoguous)}}&lt;br /&gt;
 #define SIGNAL_BRA(signame,var)                                         \&lt;br /&gt;
      void signame (unsigned short var, ...) __attribute__ ((signal));   \&lt;br /&gt;
      void signame (unsigned short var, ...)&lt;br /&gt;
 &lt;br /&gt;
 #define SWAP_BYTES(x) (((x) &amp;gt;&amp;gt; 8) | ((x) &amp;lt;&amp;lt; 8))&lt;br /&gt;
 &lt;br /&gt;
 SIGNAL_BRA (SIG_OUTPUT_COMPARE1A, dummy)&lt;br /&gt;
 {&lt;br /&gt;
    {&lt;br /&gt;
       va_list vlist;&lt;br /&gt;
       va_start (vlist, dummy);&lt;br /&gt;
  &lt;br /&gt;
       {{ccomment|Get the return address from the stack}}&lt;br /&gt;
       dummy = va_arg (vlist, unsigned short);&lt;br /&gt;
 &lt;br /&gt;
       {{ccomment|Convert stack address to code location}}&lt;br /&gt;
       addr = SWAP_BYTES(dummy) &amp;lt;&amp;lt; 1;&lt;br /&gt;
       va_end (vlist);&lt;br /&gt;
    }&lt;br /&gt;
    {{ccomment|ISR Code}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== gcc 4.x ==== &lt;br /&gt;
&lt;br /&gt;
In der 4er-Version gab es tiefgreifende interne Änderungen im Compiler; er ist noch instabil und kann momentan nicht für den Produktiv-Einsatz empfohlen werden (Stand 02/2006). &lt;br /&gt;
&lt;br /&gt;
Die Auswirkungen der Optimierungen auf das Zielsystem &amp;lt;tt&amp;gt;avr&amp;lt;/tt&amp;gt; bleibt abzuwarten, dürfte aber nicht wesentlich sein. Die neue 4-er Version wurde u.a. deshalb aufgelegt, um mit dem Intel-Compiler gleichzuziehen &amp;amp;ndash; also im Hinblick auf das Zielsystem &amp;lt;tt&amp;gt;i386&amp;lt;/tt&amp;gt;) gemacht. &lt;br /&gt;
&lt;br /&gt;
Auch nach dem Release der 4-er Version wird die 3-er Version weiterentwickelt, da erst nach 1-2 Jahren nach Release einer neuer Major-Version ein Umstieg anzuraten ist und auch erst dann getätigt wird (zumindest im professionellen Bereich).&lt;br /&gt;
&lt;br /&gt;
=Abkürzungen und Bezeichnungen=&lt;br /&gt;
; [[GCC]]: GNU Compiler Collection&lt;br /&gt;
; gcc: GNU C-Compiler&lt;br /&gt;
; GPR: '''G'''eneral '''P'''urpose '''R'''egister&lt;br /&gt;
; [[ISR]]: [[Interrupt|'''I'''nterrupt]] '''S'''ervice '''R'''outine&lt;br /&gt;
; [[IRQ]]: '''I'''nterrupt '''R'''e'''q'''uest&lt;br /&gt;
; Prolog/Epilog: Code am Anfang/Ende jeder Funktionen/ISR, der dazu dient, verwendete Register zu sichern, den Stack-Frame für lokale [[Variable|Variablen]] anzulegen (falls benötigt), Stackpointer zu setzen, zurück zu springen (&amp;lt;tt&amp;gt;ret&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;reti&amp;lt;/tt&amp;gt;), etc.&lt;br /&gt;
; SFR: '''S'''pecial '''F'''unction '''R'''egister&lt;br /&gt;
; Target: Zielsystem, in unserem Falle avr&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[C-Tutorial]]&lt;br /&gt;
'''Code-Beispiele'''&lt;br /&gt;
* [[Hallo Welt für AVR (LED blinken)]] - ein erstes Beispiel für avr-gcc&lt;br /&gt;
*[[:Kategorie:Quellcode_C|C-Codebeispiele]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
'''Details'''&lt;br /&gt;
* [[Inline-Assembler in avr-gcc|Inline-Assembler]]&lt;br /&gt;
* [[avr-gcc/Interna|Interna von avr-gcc]]&lt;br /&gt;
&lt;br /&gt;
'''Installation (Linux)'''&lt;br /&gt;
* [[Linuxdistribution_Avr-live-cd]]&lt;br /&gt;
* [[avr-gcc und avrdude installieren]]&lt;br /&gt;
'''Sonstiges'''&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Speicherverbrauch bestimmen mit avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[Dev-Cpp IDE]]&lt;br /&gt;
* [[AVR]]&lt;br /&gt;
----&lt;br /&gt;
* [[Sourcevergleich]]&lt;br /&gt;
* [[Codevergleich AVR-Compiler]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
==Dokumentation==&lt;br /&gt;
* [http://gcc.gnu.org/onlinedocs/ GCC online documentation (en)] Offline findest du die Doku für gcc, cpp (Präprozessor) und avr-libc bei [[WinAVR]] in&lt;br /&gt;
:&amp;lt;pre&amp;gt;&amp;lt;GCC_HOME&amp;gt;/doc/gcc/&amp;lt;/pre&amp;gt;&lt;br /&gt;
: bzw.&lt;br /&gt;
:&amp;lt;pre&amp;gt;&amp;lt;GCC_HOME&amp;gt;/doc/avr-libc/&amp;lt;/pre&amp;gt;&lt;br /&gt;
:Online finden sich die Dokumente in&lt;br /&gt;
* [http://gcc.gnu.org/onlinedocs/gcc.pdf gcc.pdf (1900 kByte)] - Dokumentation des C/C++/Java-Compilers GCC (en)&lt;br /&gt;
* [http://gcc.gnu.org/onlinedocs/cpp.pdf cpp.pdf (470 kByte)] - Dokumentation des C-Präprozessors (en)&lt;br /&gt;
* [http://www.nongnu.org/avr-libc/user-manual/modules.html http://www.nongnu.org/avr-libc/user-manual] - Dokumentation zur avr-libc.&lt;br /&gt;
&lt;br /&gt;
== Downloads==&lt;br /&gt;
* [http://sourceforge.net/projects/winavr/ WinAVR-Projekt bei sourceforge.net (en)]&lt;br /&gt;
* [http://cdk4avr.sourceforge.net/ avr-gcc und toolchain als Linux-Paket bei sourceforge.net (en)]&lt;br /&gt;
* [[Linuxdistribution_Avr-live-cd]]&lt;br /&gt;
== Tipps, Installation ==&lt;br /&gt;
*[http://www.nongnu.org/avr-libc/user-manual/install_tools.html ''&amp;quot;Installing the GNU Tool Chain&amp;quot;''] Hilfe zum Build und Installation von GCC, binutils, etc unter Linux&lt;br /&gt;
* Im GCC-Handbuch, siehe [[#Dokumentation|Dokumentation]].&lt;br /&gt;
* [http://www.linuxfocus.org/Deutsch/November2004/article352.shtml www.linuxfocus.org (Artikel)] - Tipps zu Build und Installation von avr-gcc, binutils und avr-libc unter Linux&lt;br /&gt;
* [http://users.rcn.com/rneswold/avr/ Rich Neswold: ''A GNU Development Environment for the AVR Microcontroller'']&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/24166 www.mikrocontroller.net (Foren-Beitrag)] - Installation von GCC und Toolchain unter Mac OS X&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=125603#125603 www.roboternetz.de (Foren-Beitrag)] ''avrgcc + avrdude installieren''&lt;br /&gt;
&lt;br /&gt;
== Sonstiges ==&lt;br /&gt;
* [http://gcc.gnu.org/ Offizielle Homepage von GCC (en)]&lt;br /&gt;
* [http://de.wikipedia.org/wiki/GNU_Compiler_Collection GCC in der deutschen Wikipedia]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial avr-gcc-Tutorial auf mikrocontroller.net]&lt;br /&gt;
* [http://www.avrfreaks.net/AVRGCC/ avr-gcc bei avrfreaks.net (en)]&lt;br /&gt;
* [http://savannah.nongnu.org/projects/avr-libc/ Nützliche GCC Runtime-Libary]&lt;br /&gt;
&lt;br /&gt;
=Autor=&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:SprinterSB|SprinterSB]] 11:27, 7. Dez 2005 (CET)&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Quellcode C|!]]&lt;br /&gt;
[[Kategorie:Software]]&lt;/div&gt;</summary>
		<author><name>Inrfb2</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Avr-gcc&amp;diff=10432</id>
		<title>Avr-gcc</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Avr-gcc&amp;diff=10432"/>
				<updated>2007-03-20T10:09:32Z</updated>
		
		<summary type="html">&lt;p&gt;Inrfb2: /* Interrupts */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''avr-gcc''' ist ein freier C-[[Compiler]], mit dem man C-Programme zu ausführbaren Programmen übersetzen kann, die auf [[Microcontroller]]n der [[AVR]]-Familie lauffähig sind. &lt;br /&gt;
An Sprachen versteht avr-gcc sowohl C als auch [[#C%2b%2b|C++]]. &lt;br /&gt;
Neben Standard-C bzw. ANSI-C versteht avr-gcc auch GNU-C, das etwas mehr Möglichkeiten und kleinere Spracherweiterungen bietet.&lt;br /&gt;
&lt;br /&gt;
avr-gcc kann auch dazu verwendet werden, um C/C++ Programme nach Assembler zu übersetzen oder um Bibliotheken zu erstellen, die später in unterschiedlichen Projekten verwendet werden können.&lt;br /&gt;
&lt;br /&gt;
Wie bei allen aus der UNIX-Welt kommenden Programmen ist das Kommando-Interface von avr-gcc die Shell bzw. die Kommandozeile, über die Optionen, Parameter, Einstellungen und die Namen der zu übersetzenden Dateien angegeben werden. &lt;br /&gt;
&lt;br /&gt;
=How to Read=&lt;br /&gt;
&lt;br /&gt;
Dieser Artikel bespricht avr-gcc Version 3.x. Er ist kein C-Tutorial und kein AVR-Handbuch &amp;amp;ndash; das würde den Umfang des Artikels bei weitem sprengen. &lt;br /&gt;
&lt;br /&gt;
Der Artikel ist ein Handbuch zu avr-gcc. Er bespricht zum Beispiel, wie man avr-gcc anwendet und Besonderheiten von avr-gcc-C,&lt;br /&gt;
die nicht zum Sprachumfang von C gehören.&lt;br /&gt;
Dazu zählen die Definition von [[#Interrupts|Interrupt]] Service Routinen ([[ISR|ISRs]]) &lt;br /&gt;
oder wie man Daten ins [[EEPROM]] legt.&lt;br /&gt;
&lt;br /&gt;
Es wird also besprochen, ''wie'' eine ISR zu definieren ist, aber nicht,&lt;br /&gt;
''warum'' das  gegebenenfalls notwendig oder nicht notwendig ist. &lt;br /&gt;
''Warum'' etwas gemacht wird, ist abhängig von der gestellten Aufgabe,&lt;br /&gt;
etwa ''&amp;quot;Initialisiere den [[UART]] zur Benutzung mit 9600 Baud&amp;quot;''.&lt;br /&gt;
Dafür enthält dieser Artikel zusammen mit dem AVR-Handbuch das Rüstzeug, &lt;br /&gt;
bietet aber keine Lösungen für konkrete Aufgaben.&lt;br /&gt;
&lt;br /&gt;
Neben diesem Artikel gibt es den Unterartikel [[avr-gcc/Interna|Interna von avr-gcc]] wo Dinge wie die Registerverwendung, Attribute, Builtins und Sections von avr-gcc dargestellt werden. Zudem findet sich dort ein Überblick über die Arbeitsweise von gcc mit den Schritten&lt;br /&gt;
* Precompilieren&lt;br /&gt;
* Compilieren&lt;br /&gt;
* Assemblieren&lt;br /&gt;
* Linken&lt;br /&gt;
Ein weiterer Unterartikel widmet sich dem Thema [[Inline-Assembler in avr-gcc]].&lt;br /&gt;
&lt;br /&gt;
In den [[:Kategorie:Quellcode C|C-Codebeispielen]]&lt;br /&gt;
befindet sich das ausführlichere Beispiel &amp;quot;[[Hallo Welt für AVR (LED blinken)]]&amp;quot;,&lt;br /&gt;
das nur eine [[Diode#Lumineszenzdiode|LED]] blinkt und zeigt, &lt;br /&gt;
wie ein kleines Projekt mit avr-gcc compiliert werden kann.&lt;br /&gt;
&lt;br /&gt;
Es gibt ein [[C-Tutorial]], das jedoch noch unvollständig und teilweise feherhaft ist (Stand 02/2006). Darüber hinaus gibt es ein [http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial C-Tutorial bei www.mikrocontroller.net].&lt;br /&gt;
&lt;br /&gt;
=Benutzer-Schnittstelle=&lt;br /&gt;
&lt;br /&gt;
Die Benutzer-Schnittstelle von avr-gcc ist &amp;amp;ndash; wie für alle Programme, die aus der UNIX-Welt kommen &amp;amp;ndash; die Kommandozeile einer Shell, Console bzw. Eingabeaufforderung. &lt;br /&gt;
&lt;br /&gt;
Im einfachsten Fall sieht ein Aufruf von avr-gcc also so aus:&lt;br /&gt;
 &amp;gt; avr-gcc&lt;br /&gt;
Dabei das '&amp;lt;tt&amp;gt;&amp;gt;&amp;lt;/tt&amp;gt;' nicht mittippen, und ein ENTER am Ende der Zeile drücken.&lt;br /&gt;
Die Antwort bei korrekter Installation ist dann&lt;br /&gt;
 avr-gcc: no input files&lt;br /&gt;
Was bedeutet: das Programm avr-gcc wurde vom Betriebssystem gefunden und konnte/durfte gestartet werden. Dann gibt avr-gcc eine Fehlermeldung aus und beendet die Ausführung, weil er keine Eingabedatei(en) bekommen hat &amp;amp;#150; was ja auch stimmt. Soweit ist also alles in Butter.&lt;br /&gt;
&lt;br /&gt;
Um eine C-Datei &amp;lt;tt&amp;gt;foo.c&amp;lt;/tt&amp;gt; mir avr-gcc optimiert zu einem lauffähigen elf-Programm &amp;lt;tt&amp;gt;foo.elf&amp;lt;/tt&amp;gt; für einen [[ATmega32]] zu compileren, würde man angeben&lt;br /&gt;
 &amp;gt; avr-gcc -O2 -mmcu=atmega32 foo.c -o foo.elf&lt;br /&gt;
Hat man seine Quellen auf zwei oder mehre Dateien verteilt, geht es analog:&lt;br /&gt;
 &amp;gt; avr-gcc -O2 -mmcu=atmega32 foo.c foo2.c -o foo.elf&lt;br /&gt;
&lt;br /&gt;
Will man nur eine Objekt-Datei erstellen (nur compilieren, nicht linken), dann geht das wie folgt. Das kann günstig sein bei grösseren Projekten, wenn man das Projekt neu erzeugen will, aber nur in einer Quelldatei was geändert hat. Oder wenn das Objekt in einer Bibliothek landen soll.&lt;br /&gt;
 &amp;gt; avr-gcc -O2 -c -mmcu=atmega32 foo.c -o foo.o&lt;br /&gt;
&lt;br /&gt;
Die ausführbare Gesamtdatei &amp;lt;tt&amp;gt;foo_all.elf&amp;lt;/tt&amp;gt; erhält man dann, indem alle Objekte zusammenlinkt:&lt;br /&gt;
 &amp;gt; avr-gcc -mmcu=atmega32 foo.o foo2.o foo3.o -o foo_all.elf&lt;br /&gt;
&lt;br /&gt;
Um die ausführbare Datei in das oft verwendete Intex-HEX-Format umzuwandeln (einmal fürs Programm, einmal für ein Abbild des [[EEPROM]]s) gibt man an:&lt;br /&gt;
 &amp;gt; avr-objcopy -O ihex -j .text -j .data                         foo_all.elf  foo_all.hex&lt;br /&gt;
 &amp;gt; avr-objcopy -O ihex -j .eeprom --change-section-lma .eeprom=0 foo_all.elf  foo_all_eeprom.hex&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[GCC]] war immer Kommandozeilen-orientiert und wird es auch immer bleiben, denn das hat gute Gründe:&lt;br /&gt;
* ein Compiler ist ein Compiler ist ein Compiler (und keine grafische Bedienschnittstelle)&lt;br /&gt;
* die Plattformabhängigkeit wird auf ein Minimum reduziert&lt;br /&gt;
* es gibt die Möglichkeit, avr-gcc per Skript oder [[make]] zu starten&lt;br /&gt;
* avr-gcc kann durchaus in eine Umgebung integriert werden: in einen Editor oder in eine GUI wie neuere Versionen von AVR-Studio erfolgreich beweisen, etc. Der avr-gcc-Aufruf kann sogar von einem Server-Socket oder einer Web-Application heraus erfolgen, welche ein C-Programm empfängt, es von avr-gcc übersetzen lässt, und das Resultat zurückschickt oder sonst was damit anstellt.&lt;br /&gt;
* Lizenzgründe: eine Umgebung, die avr-gcc integriert, kann durchaus proprietär oder nicht quelloffen sein und muss nicht der [[Freie Software|GPL]] unterliegen. Wieder ist AVR-Studio ein Beispiel.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Unterstützte AVR-Derivate=&lt;br /&gt;
;Classic AVR&amp;amp;#58;: [[AT90S1200]], [[AT90S2313]], [[AT90S8515]], [[AT90S8535]], [[AT90S4433]], [[AT90S4414]], [[AT90S4434]], [[AT90S2323]], [[AT90S2333]], [[AT90S2343]], &lt;br /&gt;
&lt;br /&gt;
;tinyAVR&amp;amp;#58;: [[ATtiny10]], [[ATtiny11]], [[ATtiny12]], [[ATtiny15]], [[ATtiny28]], [[ATtiny22]], [[ATtiny26]], [[AT90C8534]], [[AT86rf401]], [[ATtiny13]], [[ATtiny2313]], [[ATtiny261]], [[ATtiny461]], [[ATtiny861]], [[ATtiny24]], [[ATtiny44]], [[ATtiny84]], [[ATtiny25]], [[ATtiny45]], [[ATtiny85]]&lt;br /&gt;
&lt;br /&gt;
;megaAVR&amp;amp;#58;: [[ATmega603]], [[ATmega103]], [[AT76C711]], [[ATmega48]], [[ATmega8]], [[ATmega83]], [[ATmega85]], [[ATmega88]], [[ATmega8515]], [[ATmega8535]], [[ATmega16]], [[ATmega161]], [[ATmega162]], [[ATmega163]], [[ATmega164p]], [[ATmega165]], [[ATmega165P]], [[ATmega168]], [[ATmega32]], [[ATmega323]], [[ATmega324P]], [[ATmega325]], [[ATmega3250]],  [[ATmega64]], [[ATmega640]], [[ATmega644]], [[ATmega644P]], [[ATmega128]], [[ATmega1280]], [[ATmega1281]], [[ATmega645]],  [[ATmega6450]], [[AT94K]]&lt;br /&gt;
&lt;br /&gt;
; [[LCD]] AVR&amp;amp;#58;: [[ATmega169]], [[ATmega169P]], [[ATmega329]], [[ATmega3290]], [[ATmega649]], [[ATmega6490]],&lt;br /&gt;
; Lightning AVR&amp;amp;#58;: [[AT90PWM2]], [[AT90PWM3]]&lt;br /&gt;
; [[CAN]] AVR&amp;amp;#58;: [[AT90CAN32]], [[AT90CAN64]], [[AT90CAN128]]&lt;br /&gt;
; Smart Battery&amp;amp;#58;: [[ATmega406]]&lt;br /&gt;
; [[USB]] AVR&amp;amp;#58;: [[AT43USB320]], [[AT43USB355]], [[AT90USB646]], [[AT90USB647]], [[AT90USB1286]], [[AT90USB1287]]&lt;br /&gt;
;&lt;br /&gt;
&lt;br /&gt;
Diese Liste kann man avr-gcc anzeigen lassen mit&lt;br /&gt;
 &amp;gt; avr-gcc --target-help&lt;br /&gt;
&lt;br /&gt;
=Kommandozeilen-Optionen=&lt;br /&gt;
Die Codegenerierung bei avr-gcc wird über Kommandozeilen-Optionen gesteuert. Diese legen fest, für welchen Controller Code zu erzeugen ist, wie stark optimiert wird, ob Debug-Informationen erzeugt werden, etc. Die Optionen teilen sich in zwei Gruppen: Optionen, die für alle GCC-Ports verfürgbar sind und maschinenspezifische Optionen, die nur für AVR verfügbar sind.&lt;br /&gt;
&lt;br /&gt;
Aus der Masse an GCC-Optionen kann hier nur ein kleiner Auszug der wichtigsten und am häufigsten verwendeten Optionen vorgestellt werden. Eine Auflistung aller GCC-Optionen mit Kurzbeschreibung umfasst knapp 1000 Zeilen &amp;amp;#150; ohne undokumentierte Optionen, versteht sich.&lt;br /&gt;
&lt;br /&gt;
==Allgemeine Optionen für GCC==&lt;br /&gt;
; &amp;lt;tt&amp;gt;--help&amp;lt;/tt&amp;gt;: Anzeige der wichtigsten Optionen&lt;br /&gt;
; &amp;lt;tt&amp;gt;--help -v&amp;lt;/tt&amp;gt;: Überschüttet einen mit Optionen&lt;br /&gt;
; &amp;lt;tt&amp;gt;--target-help&amp;lt;/tt&amp;gt;: Anzeige der wichtigsten maschinenspezifischen Optionen und der unterstützten AVR-Derivate&lt;br /&gt;
; &amp;lt;tt&amp;gt;-O0&amp;lt;/tt&amp;gt;: keine Optimierung&lt;br /&gt;
; &amp;lt;tt&amp;gt;-O1&amp;lt;/tt&amp;gt;: Optimierung&lt;br /&gt;
; &amp;lt;tt&amp;gt;-Os&amp;lt;/tt&amp;gt;: optimiert für Code-Größe&lt;br /&gt;
; &amp;lt;tt&amp;gt;-O2&amp;lt;/tt&amp;gt;: stärkere Optimierung für bessere Laufzeit&lt;br /&gt;
; &amp;lt;tt&amp;gt;-g&amp;lt;/tt&amp;gt;: erzeugt Debug-Informationen&lt;br /&gt;
; &amp;lt;tt&amp;gt;-c&amp;lt;/tt&amp;gt;: (pre)compilert und assembliert nur bis zum Objekt (&amp;lt;tt&amp;gt;*.o&amp;lt;/tt&amp;gt;), kein Link-Lauf&lt;br /&gt;
; &amp;lt;tt&amp;gt;-S&amp;lt;/tt&amp;gt;: (pre)compilert nur und erzeugt Assembler-Ausgabe (*.s)&lt;br /&gt;
; &amp;lt;tt&amp;gt;-E&amp;lt;/tt&amp;gt;: nur Precompilat (&amp;lt;tt&amp;gt;*.i&amp;lt;/tt&amp;gt;) erzeugen, kein Compilieren, kein Assemblieren, kein Linken&lt;br /&gt;
; &amp;lt;tt&amp;gt;-o &amp;lt;filename&amp;gt;&amp;lt;/tt&amp;gt;: legt den Name der Ausgabedatei fest&lt;br /&gt;
; &amp;lt;tt&amp;gt;-v&amp;lt;/tt&amp;gt;: zeigt Versionsinformationen an und ist geschwätzig (verbose): Anzeige der aufgerufenen tools&lt;br /&gt;
; &amp;lt;tt&amp;gt;-I&amp;lt;path&amp;gt;&amp;lt;/tt&amp;gt;: Angabe eines weiteren Include-Pfads, in dem Dateien mit &amp;lt;tt&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/tt&amp;gt; gesucht werden&lt;br /&gt;
; &amp;lt;tt&amp;gt;-E -dM &amp;lt;filename&amp;gt;&amp;lt;/tt&amp;gt;: Anzeige aller Defines&lt;br /&gt;
; &amp;lt;tt&amp;gt;-MM&amp;lt;/tt&amp;gt;: Für die angegebenen Eingabe-Dateien wird eine Ausgabe erzeugt, die als [[make|Makefile]]-Fragment dienen kann und die Anhängigkeiten (dependencies) der Objekte von den Quellen/Headern beschreibt.&lt;br /&gt;
; &amp;lt;tt&amp;gt;-D&amp;lt;name&amp;gt;&amp;lt;/tt&amp;gt;: Definiert Makro &amp;lt;tt&amp;gt;&amp;lt;name&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
; &amp;lt;tt&amp;gt;-D&amp;lt;name&amp;gt;=&amp;lt;wert&amp;gt;&amp;lt;/tt&amp;gt;: Definiert Makro &amp;lt;tt&amp;gt;&amp;lt;name&amp;gt;&amp;lt;/tt&amp;gt; zu &amp;lt;tt&amp;gt;&amp;lt;wert&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
; &amp;lt;tt&amp;gt;-U&amp;lt;name&amp;gt;&amp;lt;/tt&amp;gt;: Undefiniert Makro &amp;lt;tt&amp;gt;&amp;lt;name&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
; &amp;lt;tt&amp;gt;-save-temps&amp;lt;/tt&amp;gt;: Temporäre Dateien (&amp;lt;tt&amp;gt;*.i&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;*.s&amp;lt;/tt&amp;gt;) werden nicht gelöscht. Teilweise fehlerhaft zusammen mit &amp;lt;tt&amp;gt;-c&amp;lt;/tt&amp;gt;&lt;br /&gt;
; &amp;lt;tt&amp;gt;-Wa,&amp;lt;options&amp;gt;&amp;lt;/tt&amp;gt;: übergibt Komma-getrennte Liste &amp;lt;tt&amp;gt;&amp;lt;options&amp;gt;&amp;lt;/tt&amp;gt; an den Assembler (&amp;lt;tt&amp;gt;avr-as&amp;lt;/tt&amp;gt;)&lt;br /&gt;
:;&amp;lt;tt&amp;gt;-Wa,-a=&amp;lt;filename&amp;gt;&amp;lt;/tt&amp;gt;: Assembler erzeugt ein Listing mit Name &amp;lt;tt&amp;gt;&amp;lt;filename&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
; &amp;lt;tt&amp;gt;-Wp,&amp;lt;options&amp;gt;&amp;lt;/tt&amp;gt;:  übergibt Komma-getrennte Liste &amp;lt;tt&amp;gt;&amp;lt;options&amp;gt;&amp;lt;/tt&amp;gt; an den Preprozessor&lt;br /&gt;
; &amp;lt;tt&amp;gt;-Wl,&amp;lt;options&amp;gt;&amp;lt;/tt&amp;gt;:  übergibt Komma-getrennte Liste &amp;lt;tt&amp;gt;&amp;lt;options&amp;gt;&amp;lt;/tt&amp;gt; an den Linker (&amp;lt;tt&amp;gt;avr-ld&amp;lt;/tt&amp;gt;)&lt;br /&gt;
:;&amp;lt;tt&amp;gt;-Wl,-Map=&amp;lt;filename&amp;gt;&amp;lt;/tt&amp;gt;: Linker erzeugt ein Map-File mit Name &amp;lt;tt&amp;gt;&amp;lt;filename&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
:;&amp;lt;tt&amp;gt;-Wl,--oformat=&amp;lt;format&amp;gt;&amp;lt;/tt&amp;gt;: Linker erzeugt Ausgabe im Format &amp;lt;tt&amp;gt;&amp;lt;format&amp;gt;&amp;lt;/tt&amp;gt;, z.b. &amp;lt;tt&amp;gt;ihex&amp;lt;/tt&amp;gt; für Intel-HEX-File&lt;br /&gt;
:;&amp;lt;tt&amp;gt;-Wl,--section-start=&amp;lt;section&amp;gt;=&amp;lt;address&amp;gt;&amp;lt;/tt&amp;gt;: Linker legt die [[avr-gcc/Interna#Sections|Section]] &amp;lt;tt&amp;gt;&amp;lt;section&amp;gt;&amp;lt;/tt&amp;gt; ab Adresse &amp;lt;tt&amp;gt;&amp;lt;address&amp;gt;&amp;lt;/tt&amp;gt;, z.B: &amp;lt;tt&amp;gt;.eeprom=0x810001&amp;lt;/tt&amp;gt;&lt;br /&gt;
; &amp;lt;tt&amp;gt;-Wall&amp;lt;/tt&amp;gt;: gibt mehr Warnungen, aber immer noch nicht alle&lt;br /&gt;
; &amp;lt;tt&amp;gt;-pedantic&amp;lt;/tt&amp;gt;: geht besonders pedantisch mit Code um&lt;br /&gt;
; &amp;lt;tt&amp;gt;-std=c89&amp;lt;br/&amp;gt;-ansi&amp;lt;/tt&amp;gt;: bricht mit einer Fehlermeldung ab, wenn kein ANSI-C (ISO C89) verwendet wurde&lt;br /&gt;
; &amp;lt;tt&amp;gt;-std=c99&amp;lt;/tt&amp;gt;: bricht mit einer Fehlermeldung ab, wenn kein ISO C99 verwendet wurde&lt;br /&gt;
; &amp;lt;tt&amp;gt;-ffreestanding&amp;lt;/tt&amp;gt;: Das erzeugte Programm läuft nicht in einer Umgebung wie einer Shell. Der Prototyp von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; ist&lt;br /&gt;
:&amp;lt;pre&amp;gt;void main (void);&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Maschinenspezifische Optionen für avr-gcc==&lt;br /&gt;
Maschinenabhängige Optionen beginnen immer mit '''-m'''&lt;br /&gt;
;-mmcu=xxx: Festlegen des Targets (Zielsystem/Controller), für das Code generiert werden soll. Je nach Target muss avr-gcc unterschiedliche Instruktionen verwenden und andere Startup-Dateien (&amp;lt;tt&amp;gt;crtxxx.o&amp;lt;/tt&amp;gt;) einbinden. avr-gcc setzt spezielle Defines, um auch in der Quelle zwischen den Targets unterscheiden zu können, falls das notwendig sein sollte: &lt;br /&gt;
:{| border=&amp;quot;0&amp;quot; cellpadding=&amp;quot;0&amp;quot; cellspacing=&amp;quot;0&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#ifdef __AVR_AT90S2313__&lt;br /&gt;
/* Code fuer AT90S2313 */&lt;br /&gt;
#elif defined (__AVR_ATmega8__) || defined (__AVR_ATmega32__)&lt;br /&gt;
/* Code fuer Mega8 und Mega32 */ &lt;br /&gt;
#else&lt;br /&gt;
#error Das ist noch nicht implementiert für diesen Controller!&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Zwar gibt es für alle AVR-Derivate die &amp;lt;tt&amp;gt;avr/io.h&amp;lt;/tt&amp;gt;, aber die AVR-Familien unterscheiden sich in ihrer Hardware; z.B. darin, wie I/O-Register heissen oder wie Hardware zu initialisieren ist. Diese Abhängigkeit kann man in unterschiedlichen Codestücken aufteilen und wie oben gezeigt bedingt übersetzen. Dadurch hat man Funktionalitäten wie &amp;lt;tt&amp;gt;uart_init&amp;lt;/tt&amp;gt; auf unterschiedlichen Controllern und wahrt den Überblick, weil nicht für jede Controller-Familie eine extra Datei notwendig ist.&lt;br /&gt;
{| &lt;br /&gt;
|- valign=&amp;quot;top&amp;quot; &lt;br /&gt;
| &lt;br /&gt;
:{| {{Blauetabelle}}&lt;br /&gt;
|+ '''AVR classic, &amp;amp;lt;= 8 kByte'''&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|mcu || Builtin define&lt;br /&gt;
 |- &lt;br /&gt;
 |avr2 ||&amp;lt;tt&amp;gt;__AVR_ARCH__=2&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |[[AT90S2313|at90s2313]]  ||&amp;lt;tt&amp;gt;__AVR_AT90S2313__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90s2323 ||&amp;lt;tt&amp;gt;__AVR_AT90S2323__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90s2333 ||&amp;lt;tt&amp;gt;__AVR_AT90S2333__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90s2343 ||&amp;lt;tt&amp;gt;__AVR_AT90S2343__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |attiny22 ||&amp;lt;tt&amp;gt;__AVR_ATtiny22__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |attiny26 ||&amp;lt;tt&amp;gt;__AVR_ATtiny26__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90s4414 ||&amp;lt;tt&amp;gt;__AVR_AT90S4414__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90s4433 ||&amp;lt;tt&amp;gt;__AVR_AT90S4433__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90s4434 ||&amp;lt;tt&amp;gt;__AVR_AT90S4434__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90s8515 ||&amp;lt;tt&amp;gt;__AVR_AT90S8515__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90c8534 ||&amp;lt;tt&amp;gt;__AVR_AT90C8534__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90s8535 ||&amp;lt;tt&amp;gt;__AVR_AT90S8535__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at86rf401 ||&amp;lt;tt&amp;gt;__AVR_AT86RF401__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
 |  &amp;lt;!-----------------------------------------------------------&amp;gt;&lt;br /&gt;
:{| {{Blauetabelle}}&lt;br /&gt;
|+ '''AVR classic, &amp;amp;gt; 8 kByte'''&lt;br /&gt;
|- bgcolor=&amp;quot;#ccccff&amp;quot;&lt;br /&gt;
! |mcu ||Builtin define&lt;br /&gt;
 |- &lt;br /&gt;
 |avr3 ||&amp;lt;tt&amp;gt;__AVR_ARCH__=3&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |atmega103 ||&amp;lt;tt&amp;gt;__AVR_ATmega103__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |atmega603 ||&amp;lt;tt&amp;gt;__AVR_ATmega603__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at43usb320 ||&amp;lt;tt&amp;gt;__AVR_AT43USB320__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at43usb355 ||&amp;lt;tt&amp;gt;__AVR_AT43USB355__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at76c711 ||&amp;lt;tt&amp;gt;__AVR_AT76C711__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&amp;lt;!-----------------------------------------------------------&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| &lt;br /&gt;
 |- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
 |&lt;br /&gt;
:{| {{Blauetabelle}}&lt;br /&gt;
|+ '''AVR enhanced, &amp;amp;lt;= 8 kByte'''&lt;br /&gt;
|- bgcolor=&amp;quot;#ccccff&amp;quot;&lt;br /&gt;
!|mcu || Builtin define&lt;br /&gt;
 |- &lt;br /&gt;
 |avr4 ||&amp;lt;tt&amp;gt;__AVR_ARCH__=4&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |[[Atmel Controller Mega8|atmega8]] ||&amp;lt;tt&amp;gt;__AVR_ATmega8__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |atmega8515 ||&amp;lt;tt&amp;gt;__AVR_ATmega8515__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |atmega8535 ||&amp;lt;tt&amp;gt;__AVR_ATmega8535__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
 |&amp;lt;!-----------------------------------------------------------&amp;gt;&lt;br /&gt;
:{| {{Blauetabelle}}&lt;br /&gt;
|+ '''AVR enhanced, &amp;amp;gt; 8 kByte'''&lt;br /&gt;
|- bgcolor=&amp;quot;#ccccff&amp;quot;&lt;br /&gt;
!|mcu ||Builtin define&lt;br /&gt;
 |- &lt;br /&gt;
 |avr5 ||&amp;lt;tt&amp;gt;__AVR_ARCH__=5&amp;lt;/tt&amp;gt; &lt;br /&gt;
 |-&lt;br /&gt;
 |[[Atmel Controller Mega16 und Mega32|atmega16]] ||&amp;lt;tt&amp;gt;__AVR_ATmega16__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |atmega161 ||&amp;lt;tt&amp;gt;__AVR_ATmega161__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |atmega162 ||&amp;lt;tt&amp;gt;__AVR_ATmega162__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |atmega163 ||&amp;lt;tt&amp;gt;__AVR_ATmega163__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |atmega169 ||&amp;lt;tt&amp;gt;__AVR_ATmega169__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |[[Atmel Controller Mega16 und Mega32|atmega32]] ||&amp;lt;tt&amp;gt;__AVR_ATmega32__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |atmega323 ||&amp;lt;tt&amp;gt;__AVR_ATmega323__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |[[ATMega64|atmega64]] ||&amp;lt;tt&amp;gt;__AVR_ATmega64__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |[[Atmel Controller Mega128|atmega128]] ||&amp;lt;tt&amp;gt;__AVR_ATmega128__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at94k ||&amp;lt;tt&amp;gt;__AVR_AT94K__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&amp;lt;!-----------------------------------------------------------&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:{| {{Blauetabelle}}&lt;br /&gt;
|+ '''AVR, nur Assembler'''&lt;br /&gt;
|- bgcolor=&amp;quot;#ccccff&amp;quot;&lt;br /&gt;
! |mcu ||Builtin define&lt;br /&gt;
 |- &lt;br /&gt;
 |avr1 ||&amp;lt;tt&amp;gt;__AVR_ARCH__=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90s1200 ||&amp;lt;tt&amp;gt;__AVR_AT90S1200__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |attiny11 ||&amp;lt;tt&amp;gt;__AVR_ATtiny11__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |attiny12 ||&amp;lt;tt&amp;gt;__AVR_ATtiny12__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |attiny15 ||&amp;lt;tt&amp;gt;__AVR_ATtiny15__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |attiny28 ||&amp;lt;tt&amp;gt;__AVR_ATtiny28__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
; -minit-stack=xxx: Festlegen der Stack-Adresse&lt;br /&gt;
; -mint8: Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ist nur 8 Bit breit, anstatt 16 Bit. Datentypen mit 32 Bit wie  &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; sind nicht verfügbar&lt;br /&gt;
; -mno-interrupts: Ändert den Stackpointer ohne Interrupts zu deaktivieren&lt;br /&gt;
; -mcall-prologues: Funktions-Prolog und -Epilog werden als Unterroutinen umgesetzt, um die Codegröße zu verkleinern&lt;br /&gt;
; -mtiny-stack: Nur die unteren 8 Bit des Stackpointers werden verändert&lt;br /&gt;
; -mno-tablejump: Für ein &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;-Statement werden keine Sprungtabellen angelegt&lt;br /&gt;
; -mshort-calls: Verwendet &amp;lt;tt&amp;gt;rjmp&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;rcall&amp;lt;/tt&amp;gt; (begrenzte Sprungweite) auf Devices mit mehr als 8 kByte Flash&lt;br /&gt;
; -msize: Ausgabe der Instruktonslängen im asm-File&lt;br /&gt;
; -mdeb: (undokumentiert) Ausgabe von Debug-Informationen für GCC-Entwickler&lt;br /&gt;
; -morder1: (undokumentiert) andere Register-Allokierung&lt;br /&gt;
; -morder2: (undokumentiert) andere Register-Allokierung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=C++=&lt;br /&gt;
&lt;br /&gt;
:''&amp;quot;C++ is a complex language and an evolving one, and its standard definition (the ISO C++ standard) was only recently completed. As a result, your C++ compiler may occasionally surprise you, even when its behavior is correct.&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
Zudem sollte der Einsatz von C++ aus Effizienzgründen sehr kritisch betrachtet werden:&lt;br /&gt;
:''&amp;quot;When programming C++ in space- and runtime-sensitive environments like microcontrollers, extra care should be taken to avoid unwanted side effects of the C++ calling conventions like implied copy constructors that could be called upon function invocation etc. These things could easily add up into a considerable amount of time and program memory wasted. Thus, casual inspection of the generated assembler code (using the &amp;lt;tt&amp;gt;-S&amp;lt;/tt&amp;gt; compiler option) seems to be warranted.&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
Weiterhin unterliegt der Einsatz von C++ je nach Compiler/Lib-Version bestimmten Einschränkungen:&lt;br /&gt;
*Einer kompletten C++ Implementierung fehlt die Unterstützung durch die &amp;lt;tt&amp;gt;libstdc++&amp;lt;/tt&amp;gt;, dadurch fehlen Standardfunktionen, -Klassen und -Templates&lt;br /&gt;
* Die Operatoren &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;delete&amp;lt;/tt&amp;gt; sind nicht implementiert, ihre Verwendung führt zu unauflösbaren externen Referenzen (Linker-Fehler)&lt;br /&gt;
*Nicht alle Header sind C++-sicher und müssen in &amp;lt;tt&amp;gt;extern &amp;quot;C&amp;quot; {...}&amp;lt;/tt&amp;gt; eingeschlossen werden.&lt;br /&gt;
*Exceptions werden nicht unterstützt und müssen via &amp;lt;tt&amp;gt;-fno-exceptions&amp;lt;/tt&amp;gt; abgeschaltet werden, oder der Linker beschwert sich über eine unauflösbare externe Referenz zu &amp;lt;tt&amp;gt;__gxx_personality_sj0&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Als Treiber verwendet man wie immer avr-gcc. Standard-Endungen für C++ sind &amp;lt;tt&amp;gt;.c++&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;.cpp&amp;lt;/tt&amp;gt;. Bei anderen Endungen teilt man mit &amp;lt;tt&amp;gt;-x c++&amp;lt;/tt&amp;gt; mit, daß es sich um C++ Dateien handelt, oder ruft &amp;lt;tt&amp;gt;avr-c++&amp;lt;/tt&amp;gt; direkt auf.&lt;br /&gt;
&lt;br /&gt;
Interrupt-Service-Routinen (ISRs) sind C-Funktionen und werden definiert wie gehabt. Siehe auch [[#Interrupts|Interrupts]].&lt;br /&gt;
 #include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #if defined (__cplusplus)&lt;br /&gt;
 extern &amp;quot;C&amp;quot; {&lt;br /&gt;
 #endif {{comment|__cplusplus}}&lt;br /&gt;
 &lt;br /&gt;
 SIGNAL (SIG_NAME)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|machwas}}&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 INTERRUPT (SIG_NAME)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|mach was}}&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 #if defined (__cplusplus)&lt;br /&gt;
 }&lt;br /&gt;
 #endif {{comment|__cplusplus}}&lt;br /&gt;
&amp;lt;tt&amp;gt;__cplusplus&amp;lt;/tt&amp;gt; ist ein Standard [[avr-gcc/Interna#Builtin Defines|GCC-Builtin-Define]].&lt;br /&gt;
&lt;br /&gt;
Globale Konstruktoren werden in [[avr-gcc/Interna#Sections|Section]] &amp;lt;tt&amp;gt;.init6&amp;lt;/tt&amp;gt; ausgeführt, die Destruktoren in &amp;lt;tt&amp;gt;.fini6&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=Code-Beispiele=&lt;br /&gt;
Dieser Abschnitt enthält Code-Schnippsel für avr-gcc. Es werden Besonderheiten besprochen, die für avr-gcc zu beachten sind. &lt;br /&gt;
&lt;br /&gt;
Dieser Abschnitt ist ''kein'' [[C-Tutorial|Tutorial zur C-Programmierung]] und ''keine'' Einführung in die Programmiersprache C im allgemeinen. Dafür sei auf einschlägige Tutorials/Bücher verwiesen.&lt;br /&gt;
&lt;br /&gt;
==Zugriff auf Special Function Registers (SFRs)==&lt;br /&gt;
&lt;br /&gt;
===Zugiff auf Bytes und Worte===&lt;br /&gt;
For dem Zugriff auf die SFRs gibt es Defines über den Include&lt;br /&gt;
 #include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
Abhängig vom eingestellten Controller werden denn Defines eingebunden, über die auf SFRs wie auf normale Variablen zugegriffen werden kann. Die Namen der Defines sind i.d.R. die gleichen wie im AVR-Manual, also z.b. &amp;lt;tt&amp;gt;SREG&amp;lt;/tt&amp;gt; für das Prozessorstatus-Register SREG:&lt;br /&gt;
 #include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
   {{ccomment|SREG lesen}}&lt;br /&gt;
   uint8_t sreg = SREG;&lt;br /&gt;
   ...&lt;br /&gt;
   {{ccomment|SREG schreiben}}&lt;br /&gt;
   SREG = sreg;&lt;br /&gt;
&amp;lt;!--  &lt;br /&gt;
Auf SFRs wird generell über deren Adresse zugegriffen:&lt;br /&gt;
 {{ccomment|Liest den Inhalt von SREG an Adresse 0x5f}}&lt;br /&gt;
 unsigned char sreg = *((unsigned char volatile*) 0x5f);&lt;br /&gt;
Das bedeutet in etwa: &amp;quot;Lies ein flüchtiges (&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;) Byte (&amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt;) von Adresse &amp;lt;tt&amp;gt;0x5f&amp;lt;/tt&amp;gt;&amp;quot;. Der Speicherinhalt von SFRs ist flüchtig, denn er kann sich ändern, ohne daß avr-gcc dies mitbekommt. Daher muss bei jedem C-Zugriff auf ein SFR dieses wirklich gelesen/geschrieben werden, was der Qualifier &amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt; sicherstellt. Ansonst geht der Compiler u.U. davon aus, daß der Inhalt bekannt ist und verwendet einen alten, in einem GPR befindlichen Wert.&lt;br /&gt;
&lt;br /&gt;
Um lesbaren, weniger fehleranfälligen und unter AVRs halbwegs portierbaren Code zu erhalten, gibt es Makrodefinitionen im Controller-spezifischen Header &amp;lt;tt&amp;gt;ioxxxx.h&amp;lt;/tt&amp;gt;, der neben anderen Dingen mit &amp;lt;tt&amp;gt;avr/io.h&amp;lt;/tt&amp;gt; includet wird:&lt;br /&gt;
Die Bezeichner der SFRs sind die gleichen wie im Manual.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Für einen Überblick über die eingebundenen Defines und kann ein Blick in den Controller-spezifischen Header hilfreich sein. Dieser befindet sich in&lt;br /&gt;
:&amp;lt;tt&amp;gt; &amp;amp;lt;GCC_HOME&amp;amp;gt;/avr/include/avr/io****.h&amp;lt;/tt&amp;gt;&lt;br /&gt;
z.B. &amp;lt;tt&amp;gt;iom32.h&amp;lt;/tt&amp;gt; für einen [[ATmega32]].&lt;br /&gt;
&lt;br /&gt;
Dieser Zugriff geht auch für 16-Bit Register wie &amp;lt;tt&amp;gt;TCNT1&amp;lt;/tt&amp;gt;, für die eine bestimmte Reihenfolge für den Zugriff auf Low- und High-Teil eingehalten werden muss: avr-gcc generiert die Zugriffe in der richtigen Reihenfolge.&lt;br /&gt;
  uint16_t tcnt1 = TCNT1;&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Zu beachten ist, daß dieser Zugriff nicht atomar erfolgt. Das Lesen/Schreiben mehrbytiger Werte muss vom Compiler in mehrere Byte-Zugriffe zerlegt werden. Zwischen diesen Zugriffen kann ein [[Interrupt]] auftreten, wenn Interrupts aktiviert sind. Je nach Programm und welche Aufgaben eine [[ISR]] erledigt, kann dies zu Fehlfunktion führen. In dem Fall müssen diese Code-Stücke atomar gemacht werden, damit sie nicht durch einen [[IRQ]] unterbrochen werden können!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Zugriff auf einzelne Bits===&lt;br /&gt;
Zugriff auf Bits geht wie gewohnt mit den Bitoperationen &lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; (and),&lt;br /&gt;
&amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt; (or),&lt;br /&gt;
&amp;lt;tt&amp;gt;^&amp;lt;/tt&amp;gt; (xor) und&lt;br /&gt;
&amp;lt;tt&amp;gt;~&amp;lt;/tt&amp;gt; (not)&lt;br /&gt;
&lt;br /&gt;
Wieder gibt es Defines in den AVR-Headern, mit denen man Masken für den Zugriff erhalten kann, etwa:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* GIMSK / GICR */&lt;br /&gt;
#define INT1    7&lt;br /&gt;
#define INT0    6&lt;br /&gt;
#define IVSEL   1&lt;br /&gt;
#define IVCE    0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Masken ergeben sich durch Schieben von &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; an die richtige Position:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Ports B_0 und B_1 als Ausgang&lt;br /&gt;
DDRB |= (1&amp;amp;lt;&amp;amp;lt;PB0) | (1&amp;amp;lt;&amp;amp;lt;PB1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
erzeugt&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
87 b3           in      r24, 0x17&lt;br /&gt;
83 60           ori     r24, 0x03&lt;br /&gt;
87 bb           out     0x17, r24&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Etwas anders sieht der Code aus, wenn die Bits einzeln gesetzt werden und das Register im bitadressierbaren Bereich liegt (SRAM &amp;lt;tt&amp;gt;0x20&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;0x3f&amp;lt;/tt&amp;gt; resp. I/O &amp;lt;tt&amp;gt;0x0&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;0x1f&amp;lt;/tt&amp;gt;):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Ports B_0 und B_1 als Ausgang&lt;br /&gt;
DDRB |= (1&amp;amp;lt;&amp;amp;lt;PB0);&lt;br /&gt;
DDRB |= (1&amp;amp;lt;&amp;amp;lt;PB1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
erzeugt&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
b8 9a           sbi     0x17, 0&lt;br /&gt;
b9 9a           sbi     0x17, 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um Bits zu löschen, erzeugt man eine Maske, die an der betreffenden Stelle eine &amp;amp;nbsp;0 hat:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Ports B_2 als Eingang&lt;br /&gt;
DDRB &amp;amp;= ~(1&amp;amp;lt;&amp;amp;lt;PB2);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen| &lt;br /&gt;
Auch hier ist zu beachten, daß es Probleme geben kann, wenn nicht atomarer Code erzeugt wird, weil der AVR-Befehlssatz nicht mehr hergibt:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// toggle PORT B_0: wechseln 0 &amp;amp;lt;--&amp;amp;gt; 1 &lt;br /&gt;
PORTB ^= (1&amp;amp;lt;&amp;amp;lt;PB0);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
ergibt&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
88 b3           in      r24, 0x18&lt;br /&gt;
; Wenn hier ein Interrupt auftritt, in dessen ISR PORTB verändert wird,&lt;br /&gt;
; dann wird die Änderung durch die letzte Instruktion wieder überschrieben!&lt;br /&gt;
91 e0           ldi     r25, 0x01&lt;br /&gt;
; dito&lt;br /&gt;
89 27           eor     r24, r25&lt;br /&gt;
; dito&lt;br /&gt;
88 bb           out     0x18, r24&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
}} &amp;lt;!-- /FarbigerRahmen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auch das Lesen einzelner Port-Pins geht über das Maskieren von SFRs:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DDRB &amp;amp;= ~(1 &amp;lt;&amp;lt; PB2);    // PortB.2 als INPUT &lt;br /&gt;
&lt;br /&gt;
if (PINB &amp;amp; (1 &amp;lt;&amp;lt; PB2))&lt;br /&gt;
   // PortB.2 ist HIGH&lt;br /&gt;
else&lt;br /&gt;
   // PortB.2 ist LOW&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if (!(PINB &amp;amp; (1 &amp;lt;&amp;lt; PB2)))&lt;br /&gt;
   // PortB.2 ist LOW&lt;br /&gt;
else&lt;br /&gt;
   // PortB.2 ist HIGH&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Interrupts==&lt;br /&gt;
&lt;br /&gt;
Um zu kennzeichnen, daß es sich bei einer Funktion um eine Interrupt Sevice Routine (ISR) handelt, gibt es spezielle Attribute. Diese brauchen nicht explizit hingeschrieben zu werden, ebensowenig wie die genaue Nummer des Interrupt Requests (IRQ). Dafür gibt es Includes und die folgenden Makros.&lt;br /&gt;
&lt;br /&gt;
Bitte beachte auch die Hinweise zu den [[#Inkompatibilität|Inkompatibilität]]en von avr-gcc!&lt;br /&gt;
 #include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Eine nichtunterbrechbare Interrupt-Service-Routine}}&lt;br /&gt;
 SIGNAL (SIG_OUTPUT_COMPARE1A)&lt;br /&gt;
 {&lt;br /&gt;
    {{ccomment|ISR-Code}}&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Eine unterbrechbare Interrupt-Service-Routine}}&lt;br /&gt;
 INTERRUPT (SIG_OUTPUT_COMPARE1B)&lt;br /&gt;
 {&lt;br /&gt;
    {{ccomment|ISR-Code}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Dadurch wird die Funktion mit dem richtigen Prolog/Epilog erzeugt, und es wird ein Eintrag in die Interrupt-Vektortabelle gemacht &amp;amp;#150; bei obigem Beispiel also zwei Einträge.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Die Schreibweise des Signal-Names muss genau die sein wie im Header, das schliesst auch Leerzeichen ein! Nicht alle GCC-Versionen bringen Fehler/Warnung, wenn die Schreibweise nicht stimmt.&lt;br /&gt;
 SIGNAL (SIG_OUTPUT_COMPARE1A )  // !!! Macht NICHT das, was man will (Blank am Ende)!!!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;SIGNAL&amp;lt;/tt&amp;gt;: Mit Ausführung einer ISR deaktiviert die AVR-Hardware die Interrupts, so daß die ISR nicht durch andere Interrupt-Anforderungen unterbrochen wird. Beim Verlassen der ISR werden Interrupts wieder automatisch aktiviert. Tritt während der ISR ein IRQ auf, wird diese erst nach Beenden des ISR-Codes ausgeführt. Der Interrupt geht also nicht verloren. Zwischen zwei ISRs wird zusätzlich mindestens ein Befehl des normalen Programm-Codes abgearbeitet.&lt;br /&gt;
;&amp;lt;tt&amp;gt;INTERRUPT&amp;lt;/tt&amp;gt;: Früh im ISR-Prolog werden mit &amp;lt;tt&amp;gt;sei&amp;lt;/tt&amp;gt; die von der AVR-Hardware temporär deaktivierten Interrupts reaktiviert. Dadurch kann die ISR von einer IRQ unterbrochen werden. Das bietet die Möglichkeit, so etwas wie Interrupt-Priorisierung nachzubilden, was AVRs selbst nicht können. Weiterhin kann man schneller auf bestimmte Ereignisse reagieren. Tritt während der ISR ein anderer IRQ auf, der schnell bedient werden muss, kann sofort der dringende ISR-Code ausgeführt werden. Ansonsten (Verwendung von &amp;lt;tt&amp;gt;SIGNAL&amp;lt;/tt&amp;gt;) würde der Code erst ausgeführt werden, nachdem die aktuelle ISR beendet ist.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|Dauert die ISR zu lange und wird sie nochmals von ihrem eigenen IRQ unterbrochen, stürzt man ab.}} &lt;br /&gt;
&lt;br /&gt;
Nachschlagen kann man den Namen in&lt;br /&gt;
:&amp;lt;tt&amp;gt;&amp;amp;lt;GCC_HOME&amp;amp;gt;/avr/include/avr/ioxxxx.h&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Interrupts aktivieren===&lt;br /&gt;
&lt;br /&gt;
Damit eine ISR überhaupt zur Ausführung kommt, müssen drei Bedingungen erfüllt sein&lt;br /&gt;
* Interrupts müssen global aktiviert sein&lt;br /&gt;
* Der entsprechen IRQ muss aktiviert worden sein&lt;br /&gt;
* Das zum IRQ gehörende Ereignis muss eintreten&lt;br /&gt;
 #include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
    ...&lt;br /&gt;
    {{ccomment|enable OutputCompareA Interrupt für Timer1}}&lt;br /&gt;
    TIMSK |= (1 &amp;lt;&amp;lt; OCIE1A);&lt;br /&gt;
 &lt;br /&gt;
    {{ccomment|disable OutputCompareA Interrupt für Timer1}}&lt;br /&gt;
    TIMSK &amp;amp;= ~(1 &amp;lt;&amp;lt; OCIE1A);&lt;br /&gt;
 &lt;br /&gt;
    {{ccomment|Interrupts aktivieren}}&lt;br /&gt;
    sei();&lt;br /&gt;
 &lt;br /&gt;
    {{ccomment|Interrupts abschalten}}&lt;br /&gt;
    cli();&lt;br /&gt;
Sperrt man eine Code-Sequenz durch Einschachteln in ein &amp;lt;tt&amp;gt;cli&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;sei&amp;lt;/tt&amp;gt; Paar (man macht das Codestück &amp;quot;atomar&amp;quot;, also ununterbrechbar), gehen währenddessen keine Interrupt-Anforderungen verloren. Die entsprechenden IRQ-Flags bleiben gesetzt, und nach dem &amp;lt;tt&amp;gt;sei&amp;lt;/tt&amp;gt; werden die IRQs in der Reihenfolge ihrer Prioritäten abgearbeitet. Ausnahme ist, wenn in einem atomaren Block der selbe IRQ mehrfach auftritt. Der ISR-Code wird dann trotzdem nur einmal ausgeführt.&lt;br /&gt;
&lt;br /&gt;
===default Interrupt===&lt;br /&gt;
&lt;br /&gt;
Für nicht implementierte Interrupts macht avr-gcc in die Vektortabelle einen Eintrag,&lt;br /&gt;
der zu &amp;lt;tt&amp;gt;__bad_interrupt&amp;lt;/tt&amp;gt; (definiert im Startup-Code &amp;lt;tt&amp;gt;crt*.o&amp;lt;/tt&amp;gt;) springt&lt;br /&gt;
und von dort aus weiter zu Adresse&amp;amp;nbsp;0. &lt;br /&gt;
Dadurch läuft der AVR wieder von neuem los, wenn ein Interrupt auftritt, &lt;br /&gt;
zu dem man keine ISR definiert hat &lt;br /&gt;
&amp;amp;#150; allerdings ohne die Hardware zurückzusetzen wie bei einem echten Reset.&lt;br /&gt;
&lt;br /&gt;
Möchte man diesen Fall abfangen, dann geht das über eine globale Funktion &lt;br /&gt;
namens &amp;lt;tt&amp;gt;__vector_default&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SIGNAL (__vector_default)&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Damit wird von &amp;lt;tt&amp;gt;__bad_interrupt&amp;lt;/tt&amp;gt; aus nicht nach Adresse&amp;amp;nbsp;0 gesprungen,&lt;br /&gt;
sondern weiter zu &amp;lt;tt&amp;gt;__vector_default&amp;lt;/tt&amp;gt;, welches durch &amp;lt;tt&amp;gt;SIGNAL&amp;lt;/tt&amp;gt; oder&lt;br /&gt;
&amp;lt;tt&amp;gt;INTERRUPT&amp;lt;/tt&amp;gt; den üblichen ISR-Prolog/Epilog bekommt.&lt;br /&gt;
&lt;br /&gt;
So kann man z.B. eine Meldung ausgeben, eine Warnlampe blinken, in einer Endlosschleife landen, oder über den [[Watchdog]] einen richtigen Hardware-Reset auslösen, siehe auch Abschnitt &amp;quot;[[#Reset auslösen|Reset auslösen]]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===ISR mit eigenem Prolog/Epilog===&lt;br /&gt;
&lt;br /&gt;
Wenn man in einer ISR komplett eigenes Zeug machen will, &lt;br /&gt;
dann definiert man eine nackte Funktion.&lt;br /&gt;
Mit &amp;lt;tt&amp;gt;naked&amp;lt;/tt&amp;gt; befreit man die Routine vom Standard-Prolog/Epilog.&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Dabei ist darauf zu achten, daß die ISR mit &amp;lt;tt&amp;gt;reti&amp;lt;/tt&amp;gt; (return from interrupt) &lt;br /&gt;
zurückkehrt und evtl. verwendete Register und den Status (&amp;lt;tt&amp;gt;SREG&amp;lt;/tt&amp;gt;) sichert.&lt;br /&gt;
}}&lt;br /&gt;
 #include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void __attribute__ ((naked)) &lt;br /&gt;
 SIG_OVERFLOW0 (void)&lt;br /&gt;
 {&lt;br /&gt;
    {{ccomment|Port B.6 &amp;amp;#61; 0}}&lt;br /&gt;
    {{ccomment|Diese Instruktion verändert nicht das SREG und kein anderes Register}}&lt;br /&gt;
    {{ccomment|so daß der eigentliche Code nur 1 Befehl lang ist}}&lt;br /&gt;
    __asm__ __volatile (&lt;br /&gt;
       &amp;quot;cbi %0, %1&amp;quot; &amp;quot;\n\t&amp;quot;&lt;br /&gt;
       &amp;quot;reti&amp;quot;&lt;br /&gt;
          : &lt;br /&gt;
          : &amp;quot;M&amp;quot; (_SFR_IO_ADDR (PORTB)), &amp;quot;i&amp;quot; (6)&lt;br /&gt;
    );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Siehe auch [[Inline-Assembler in avr-gcc]].&lt;br /&gt;
Die ISR sieht dann so aus:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
__vector_9:&lt;br /&gt;
   c6 98        cbi   0x18, 6&lt;br /&gt;
   18 95        reti&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wiederum kann man als Funktionsname &amp;lt;tt&amp;gt;__vector_default&amp;lt;/tt&amp;gt; nehmen,&lt;br /&gt;
um nicht-implementierte IRQs abzufangen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void __attribute__ ((naked)) &lt;br /&gt;
__vector_default (void)&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==SRAM, Flash, EEPROM: Datenablage am Beispiel Strings==&lt;br /&gt;
Die Programmiersprache C kennt selber keine Strings; das einzige, was C bekannt ist, ist der Datentyp &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, der ein einzelnes Zeichen repräsentiert. &lt;br /&gt;
===Darstellung in C===&lt;br /&gt;
Ein String im Sinne von C ist ein Array von Charactern bzw. ein Zeiger auf den Anfang des Arrays. Die einzelnen Zeichen folgen im Speicher direkt aufeinander und werden in aufsteigenden Adressen gespeichert. Am String-Ende folgt als Abschluss der Character &amp;lt;tt&amp;gt;'\0'&amp;lt;/tt&amp;gt;, um das Ende zu kennzeichnen. Dies ist besonders bei der Berechnung des Speicherplatzes für Strings zu berücksichtigen, denn für die 0 muss auch Platz reserviert werden.&lt;br /&gt;
&lt;br /&gt;
===Bestimmen der Stringlänge===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 /* Bestimmt die Laenge des Strings ohne die abschliessende '\0' zu zaehlen */&lt;br /&gt;
 unsigned int strlength (const char *str)&lt;br /&gt;
 {&lt;br /&gt;
   unsigned int len = 0;&lt;br /&gt;
   &lt;br /&gt;
   while (*str++)&lt;br /&gt;
      len++;&lt;br /&gt;
   &lt;br /&gt;
   return len;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Stringlänge kann auch mit der Standard-Funktion &amp;lt;tt&amp;gt;strlen&amp;lt;/tt&amp;gt; bestimmt werden, deren Prototyp sich in &amp;lt;tt&amp;gt;string.h&amp;lt;/tt&amp;gt; befindet:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 size_t strlen (const char*);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===String im Flash belassen===&lt;br /&gt;
Oftmals werden Strings nur zu Ausgabezwecken verwendet und nicht verändert. Verwendet man Sequenzen der Gestalt&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 char *str1 = &amp;quot;Hallo Welt!&amp;quot;;&lt;br /&gt;
 char str2[] = &amp;quot;Hallo Welt!&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
dann werden die Strings im SRAM abgelegt. Im Startup-Code werden die Strings vom Flash ins SRAM kopiert und belegen daher sowohl Platz im SRAM als auch im Flash. Wird ein String nicht verändert, braucht er nicht ins SRAM kopiert zu werden. Das spart Platz im knapp bemessenen SRAM. Allerdings muss anders auf den String zugegriffen werden, denn wegen der Harvard-Architektur des AVR-Kerns kann avr-gcc anhand der Adresse nicht unterscheiden, ob diese ins SRAM, ins Flash oder ins EEPROM zeigt.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 const prog_char str3[] = &amp;quot;Hallo Welt!&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
 unsigned int strlen_P (const prog_char *str)&lt;br /&gt;
 {&lt;br /&gt;
    unsigned int len = 0;&lt;br /&gt;
 &lt;br /&gt;
    while (1)&lt;br /&gt;
    {&lt;br /&gt;
       char c = (char) pgm_read_byte (str);&lt;br /&gt;
       if ('\0' == c)&lt;br /&gt;
          return len;&lt;br /&gt;
       len++;&lt;br /&gt;
       str++; &lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void foo()&lt;br /&gt;
 {&lt;br /&gt;
    unsigned int len;&lt;br /&gt;
    len = strlen_P (str3);&lt;br /&gt;
    len = strlen_P (PSTR(&amp;quot;String im Flash&amp;quot;));&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===String ins EEPROM legen===&lt;br /&gt;
Dies geht nach dem gleichen Muster, nach dem Strings ins Flash gelegt werden. Der Zugriff wird vergleichsweise langsam, denn der EEPROM ist langsamer als SRAM bzw. Flash.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #include &amp;lt;avr/eeprom.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 const char str4[] __attribute__ ((section(&amp;quot;.eeprom&amp;quot;))) = &amp;quot;Hallo Welt!&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
 unsigned int strlen_EE (const char *str)&lt;br /&gt;
 {&lt;br /&gt;
    unsigned int len = 0;&lt;br /&gt;
 &lt;br /&gt;
    while (1)&lt;br /&gt;
    {&lt;br /&gt;
       char c = (char) eeprom_read_byte (str);&lt;br /&gt;
       if ('\0' == c)&lt;br /&gt;
          return len;&lt;br /&gt;
       len++;&lt;br /&gt;
       str++; &lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reset auslösen==&lt;br /&gt;
Falls ein Reset per Software ausgelöst werden soll, dann geht das am besten über den [[Watchdog]].&lt;br /&gt;
Einfach nur an den RESET-Punkt an Adresse&amp;amp;nbsp;0 zu springen mit&lt;br /&gt;
 goto *((void**) 0);&lt;br /&gt;
initialisiert zwar den Controller von neuem, aber es macht keinen wirkliches RESET mit Zurücksetzen der Hardware und allen I/O-Registern. &lt;br /&gt;
&lt;br /&gt;
Durch den Watchdog kann man ein 'richtiges' RESET-Signal erzeugen lassen, so daß die AVR-Hardware genau so initialisiert ist, wie nach einem externen RESET. So kann man z.B. via [[UART]] ein RESET-Kommando schicken. Allerdings lässt sich der Watchdog nur minimal auf 15ms einstellen:&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;avr/wdt.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
 ...   &lt;br /&gt;
    cli();                     {{ccomment|Interrupts global abschalten}}&lt;br /&gt;
    wdt_enable (WDTO_15MS);    {{ccomment|Watchdog aufziehen auf 15ms}}&lt;br /&gt;
    while (1);                 {{ccomment|warten, bis er zubeisst...}}&lt;br /&gt;
&lt;br /&gt;
Welches Ereignis einen RESET ausgelöst hat, kann man im Register '''MCUCSR''' (''MCU Control and Status Register'') erfahren. Es gibt 4 mögliche RESET-Quellen:&lt;br /&gt;
* Power-On Reset&lt;br /&gt;
* External Reset&lt;br /&gt;
* Brown-Out Reset&lt;br /&gt;
* Watchdog Reset&lt;br /&gt;
&lt;br /&gt;
Soll der Inhalt von Variablen einen Reset überleben &amp;amp;ndash; eine Variable also nicht initialisiert werden &amp;amp;ndash; dann geht das so:&lt;br /&gt;
 #include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment| status informiert z.B. darüber, ob wir selber den Watchdog ausgelöst haben }}&lt;br /&gt;
 {{ccomment| oder nicht, oder andere Informationen }}&lt;br /&gt;
 unsigned char status __attribute__ ((section (&amp;quot;.noinit&amp;quot;)));&lt;br /&gt;
 &lt;br /&gt;
 void main (void)&lt;br /&gt;
 {&lt;br /&gt;
     {{ccomment|Wert von MCUSCR merken, möglichst früh im Programm }}&lt;br /&gt;
     unsigned char mcucsr = MCUCSR;&lt;br /&gt;
 &lt;br /&gt;
     {{ccomment|MCUCSR zurücksetzen }}&lt;br /&gt;
     MCUCSR = 0;&lt;br /&gt;
 &lt;br /&gt;
     {{ccomment|Watchdog-Reset }}&lt;br /&gt;
     if (mcuscr &amp;amp; (1 &amp;lt;&amp;lt; WDRF))&lt;br /&gt;
     {&lt;br /&gt;
         {{ccomment|status auswerten }}&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     {{ccomment|Power-On Reset: status auf definierten Wert setzen }}&lt;br /&gt;
     if (mcuscr &amp;amp; (1 &amp;lt;&amp;lt; PORF))&lt;br /&gt;
     {&lt;br /&gt;
         status = 0;&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     {{ccomment|status auswerten }}&lt;br /&gt;
     ...&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Die mit&lt;br /&gt;
 #include &amp;lt;...&amp;gt;&lt;br /&gt;
angegebenen Includes werden von avr-gcc in den &lt;br /&gt;
mit der Option '&amp;lt;tt&amp;gt;-I&amp;lt;/tt&amp;gt;' anegegenen Pfaden gesucht. &lt;br /&gt;
Dem Compiler bekannt sind die Pfade &lt;br /&gt;
 &amp;lt;GCC_HOME&amp;gt;/avr/include                           Standard               (stdio.h, ...)&lt;br /&gt;
 &amp;lt;GCC_HOME&amp;gt;/avr/include/avr                       AVR-spezifisch         (avr/io.h, ...)&lt;br /&gt;
 &amp;lt;GCC_HOME&amp;gt;/lib/gcc/avr/&amp;lt;GCC_VERSION&amp;gt;/include     Standard, compilerabh. (limits.h, ...)&lt;br /&gt;
&lt;br /&gt;
Gibt man z.B. an &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
dann wird automatisch in diesem Verzeichnis nach &amp;lt;tt&amp;gt;stdio.h&amp;lt;/tt&amp;gt; gesucht.&lt;br /&gt;
In den Verzeichnissen stehen Standard-Includes, die benötigt werden, wenn man libc-Funktionen &lt;br /&gt;
oder mathematische Funktionen etc. verwendet. &lt;br /&gt;
AVR-spezifische Dinge stehen im Unterverzeichnis &amp;lt;tt&amp;gt;avr&amp;lt;/tt&amp;gt;, etwa:&lt;br /&gt;
 #include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Als Pfad-Separator wird immer ein '''&amp;lt;tt&amp;gt;/&amp;lt;/tt&amp;gt;''' verwendet, auch auf Windows-Betriebssystemen! Also kein '''&amp;lt;tt&amp;gt;\&amp;lt;/tt&amp;gt;'''&amp;amp;nbsp;!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Standard==&lt;br /&gt;
&lt;br /&gt;
 ctype.h                   Zeichen-Umwandlungs-Makros und ctype Makros&lt;br /&gt;
 errno.h                   Symbolische Namen für Fehlercodes&lt;br /&gt;
 inttypes.h                Definiert [u]intN_t wenn man genau N [un]signed Bits &lt;br /&gt;
                           braucht, ISO C99.&lt;br /&gt;
 math.h                    Mathematische Funktionen: sin, cos, log, gamma, bessel, ...&lt;br /&gt;
 setjmp.h                  libc unterstützt setjmp() und longjmp(), um direkt in eine&lt;br /&gt;
                           andere (nicht-lokale) Funktion zu springen. &lt;br /&gt;
 stdio.h                   Standard I/O-Funktionen (printf, ...).&lt;br /&gt;
 stdlib.h                  Deklariert grundlegende ISO C-Makros und -Funktionen &lt;br /&gt;
                           sowie einige AVR-spezifische Erweiterungen&lt;br /&gt;
 string.h                  Stringoperationen auf NULL-terminierten Strings. (strlen, ...)&lt;br /&gt;
 stdarg.h                  Funktionen mit variabler Argumenanzahl&lt;br /&gt;
 limits.h                  Min- und Max-Werte von Skalaren (UCHAR_MAX, LONG_MIN, ...)&lt;br /&gt;
&lt;br /&gt;
==AVR-spezifisch==&lt;br /&gt;
&lt;br /&gt;
Die AVR-spezifischen Includes finden sich wie gesagt im Unterverzeichnis &amp;lt;tt&amp;gt;avr&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Die meisten dort befindlichen Header wird man nie direkt durch Angabe im C-File erhalten,&lt;br /&gt;
sondern durch Angabe von&lt;br /&gt;
 #include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
Dadurch werden z.B. genau die I/O-Header eingebunden, die zum AVR-Modell passen, also&lt;br /&gt;
*&amp;lt;tt&amp;gt;avr/iom8.h&amp;lt;/tt&amp;gt; für [[ATmega8]], &lt;br /&gt;
*&amp;lt;tt&amp;gt;avr/iotn2313.h&amp;lt;/tt&amp;gt; für [[ATtiny2313]], &lt;br /&gt;
*&amp;lt;tt&amp;gt;avr/io2313.h&amp;lt;/tt&amp;gt; für [[AT90S2313]], etc. &lt;br /&gt;
&lt;br /&gt;
Verantwortlich dafür ist der Schalter '&amp;lt;tt&amp;gt;-mmcu=xxx&amp;lt;/tt&amp;gt;'.&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Header nicht explizit angegeben werden müssen, &lt;br /&gt;
kann ein Blick dorthin hilfreich sein, um die Namen von [[SFR|SFRs]] &lt;br /&gt;
oder Signals nachzuschlagen. &lt;br /&gt;
Diese Header werden im folgenden nicht alle einzeln aufgelistet. &lt;br /&gt;
Ihre Namen sind immer &amp;lt;tt&amp;gt;avr/io*.h&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* für ATmega: &amp;lt;tt&amp;gt;avr/iom*.h&amp;lt;/tt&amp;gt; &lt;br /&gt;
* für ATtiny: &amp;lt;tt&amp;gt;avr/iotn*.h&amp;lt;/tt&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
avr/boot.h            Bootloader Support&lt;br /&gt;
avr/crc16.h           [*] Prüfsumme CRC16&lt;br /&gt;
avr/delay.h           [*] Verzögerungsschleifen für kurze, exakte Verzögerungen&lt;br /&gt;
avr/eeprom.h          EEPROM-Routinen&lt;br /&gt;
avr/ina90.h           Kompatibilität mit IAR-AVR-Compiler&lt;br /&gt;
avr/interrupt.h       sei(), cli(), ...&lt;br /&gt;
avr/io.h              --&amp;gt; inttypes.h, io*.h&lt;br /&gt;
avr/io*.h             SFRs, SIG_****, SPM_PAGESIZE, RAMEND, XRAMEND, E2END, FLASHEND&lt;br /&gt;
avr/parity.h          [*] Parität&lt;br /&gt;
avr/pgmspace.h        Zugriff aufs Flash: Byte lesen, PROGMEM, prog_char, prog_uint8_t, ...&lt;br /&gt;
avr/portpins.h        Makros für Port-Pins&lt;br /&gt;
avr/signal.h          [**] Makros SIGNAL() und INTERRUPT(), ...&lt;br /&gt;
avr/sleep.h           Power-Safe&lt;br /&gt;
avr/twi.h             [*] I2C&lt;br /&gt;
avr/wdt.h             Watchdog&lt;br /&gt;
 &lt;br /&gt;
util/crc16.h          Prüfsumme CRC16&lt;br /&gt;
util/delay.h          Verzögerungsschleifen für kurze, exakte Verzögerungen &lt;br /&gt;
util/parity.h         Parität&lt;br /&gt;
util/twi.h            I2C&lt;br /&gt;
 &lt;br /&gt;
[*]  bei neueren avr-gcc-Versionen in util&lt;br /&gt;
[**] entfällt bei neueren avr-gcc-Versionen. Stattdessen avr/interrupt.h verwenden&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Anwendungs-spezifisch==&lt;br /&gt;
Eigene Header, die nur innerhalb eigener Projekte gebraucht werden, includet man mit&lt;br /&gt;
 #include &amp;quot;...&amp;quot;&lt;br /&gt;
Auch hier darf man Unterverzeichnisse angeben oder ins übergeordnete Verzeichnis:&lt;br /&gt;
 #include &amp;quot;../../mein-zeug.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Optimierungen, Tipps &amp;amp; Tricks=&lt;br /&gt;
&lt;br /&gt;
Beim Programmieren in C möchte man sich möglichst wenig mit der Codeerzeugung selbst auseinandersetzen. Man verwendet ja gerade deshalb einen Compiler und programmiert nicht in Assembler, weil man sich nicht um Register-Belegungen o.ä. kümmern will, sondern nur um die zu lösende Aufgabe.&lt;br /&gt;
&lt;br /&gt;
GCC erzeugt zwar recht guten Code, aber er ist nicht perfekt. Gerade auf Systemen wie AVR mit nur sehr begrenzten Resourcen muss man daher dem Compiler hilfreich zur Seite stehen, wenn man noch dichteren/schnelleren Code erhalten möchte.&lt;br /&gt;
&lt;br /&gt;
:''&amp;quot;Unlike most other C compilers, GCC allows you to use -g with -O. The shortcuts taken by optimized code may occasionally produce surprising results: some variables you declared may not exist at all; flow of control may briefly move where you did not expect it; some statements may not be executed because they compute constant results or their values were already at hand; some statements may execute in different places because they were moved out of loops.''&lt;br /&gt;
&lt;br /&gt;
:''Nevertheless it proves possible to debug optimized output. This makes it reasonable to use the optimizer for programs that might have bugs.&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
Um das Ergebnis zu beurteilen, hilft ein Blick ins Listfile. &lt;br /&gt;
Siehe dazu auch die Abschnitte &lt;br /&gt;
&amp;quot;[[Hallo Welt für AVR (LED blinken)#Listfile erstellen|Listfile erstellen]]&amp;quot; &lt;br /&gt;
und&lt;br /&gt;
&amp;quot;[[Hallo Welt für AVR (LED blinken)#Die Größe ermitteln|Die Größe ermitteln]]&amp;quot; &lt;br /&gt;
im [[Hallo Welt für AVR (LED blinken)|Hallo Welt für AVR]].&lt;br /&gt;
&lt;br /&gt;
==Optimierungsgrad==&lt;br /&gt;
Als Optimierungsgrad erweist sich &amp;lt;tt&amp;gt;-Os&amp;lt;/tt&amp;gt; (Optimize for Size) als der beste, evtl. noch &amp;lt;tt&amp;gt;-O2&amp;lt;/tt&amp;gt;. Ohne Angabe eines Optimierungsgrades wird nicht optimiert, was gleichbedeutend mit der Option &amp;lt;tt&amp;gt;-O0&amp;lt;/tt&amp;gt; ist. Abzuraten ist von der maximalen Optimierung &amp;lt;tt&amp;gt;-O3&amp;lt;/tt&amp;gt;, die wegen function inlining und loop unrolling zu sehr breitem Code führt und für AVR absolut nicht angesagt ist.&lt;br /&gt;
&lt;br /&gt;
==Vermeide printf, scanf, malloc==&lt;br /&gt;
Funktionen von diesem Kaliber sind die absoluten Platz- und Zeitfresser. &lt;br /&gt;
&lt;br /&gt;
Alternativen findet man reichlich in der &amp;lt;tt&amp;gt;avr-libc&amp;lt;/tt&amp;gt; wie &amp;lt;tt&amp;gt;itoa&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;atoi&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Und für &amp;lt;tt&amp;gt;malloc&amp;lt;/tt&amp;gt; und Konsorten sind dynamische Arrays und das Compiler-Builtin &amp;lt;tt&amp;gt;__builtin_alloca&amp;lt;/tt&amp;gt; effizientere Alternativen, siehe auch im Abschnitt &amp;quot;[[avr-gcc#Dynamische Speicherallokierung|Dynamische Speicherallokierung]]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Konstante Strings ins Flash== &lt;br /&gt;
Konstante Strings, wie sie zu Ausgabezwecken Verwendung finden, werden im Programm oft nicht verändert und brauchen nicht SRAM zu belegen (und damit auch Flash, von wo aus sie vom Startup-Code ins SRAM kopiert werden), sondern gehören ins Flash! &lt;br /&gt;
&lt;br /&gt;
Entsprechende Routinen, um auf Strings im Flash zuzugreifen, tragen die Suffix &amp;lt;tt&amp;gt;_P&amp;lt;/tt&amp;gt;, wie z.B. &amp;lt;tt&amp;gt;strcmp_P&amp;lt;/tt&amp;gt; mit dem Prototyp&lt;br /&gt;
 extern int *strcmp_P (char *, const prog_char *)&lt;br /&gt;
Die Implementierungen befinden sich in der &amp;lt;tt&amp;gt;avr-libc&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Anwendung:'''&lt;br /&gt;
 #include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 const prog_char str_p[]     = &amp;quot;Ein String im Flash&amp;quot;;&lt;br /&gt;
 const char str2_p[] PROGMEM = &amp;quot;Noch ein String im Flash&amp;quot;;&lt;br /&gt;
 ...&lt;br /&gt;
   {{ccomment|String im SRAM mit String im Flash vergleichen}}&lt;br /&gt;
   if (!strcmp_P (str_sram, str_p))&lt;br /&gt;
   {&lt;br /&gt;
       {{ccomment|mach was bei Gleichheit}}&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
   {{ccomment|&amp;quot;foo&amp;quot; wird im RAM angelegt. Ineffizient für konstante Strings!}}  &lt;br /&gt;
   {{ccomment|Beachte, daß damit strcmp (nicht strcmp_P) benutzt werden muss.}}  &lt;br /&gt;
   if (!strcmp (str_sram, &amp;quot;foo&amp;quot;))&lt;br /&gt;
   {&lt;br /&gt;
       {{ccomment|mach was bei Gleichheit}}&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
   {{ccomment|PSTR bewirkt, daß die String-Konstante &amp;quot;foo&amp;quot;}}&lt;br /&gt;
   {{ccomment|im Flash angelegt wird}}&lt;br /&gt;
   if (!strcmp_P (str_sram, PSTR (&amp;quot;foo&amp;quot;))&lt;br /&gt;
   {&lt;br /&gt;
       {{ccomment|mach was bei Gleichheit}}&lt;br /&gt;
   }&lt;br /&gt;
 ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Sprungtabelle===&lt;br /&gt;
Genauso macht man auch eine Sprungtabelle, um anhand von Kommando-Strings dazugehörige Funktionen ausführen zu lassen:&lt;br /&gt;
 #include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 int func1 (int arg)&lt;br /&gt;
 {&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 #define TEXT_LEN 15&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Die Kommandostruktur}}&lt;br /&gt;
 typedef struct &lt;br /&gt;
 {&lt;br /&gt;
    int (*func)(int);      {{ccomment|Zeiger auf die auszuführende Funktion}}&lt;br /&gt;
    int arg;               {{ccomment|das Argument, das mitübergeben wird}}&lt;br /&gt;
    char text[1+TEXT_LEN]; {{ccomment|Text, maximal TEXT_LEN Zeichen lang}}&lt;br /&gt;
 } command_t;&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Das Array mit den Kommandos.}}&lt;br /&gt;
 {{ccomment|Die funcx sind vom Prototyp (z.B. func1 oben)}}&lt;br /&gt;
 {{ccomment|int funcx (int arg);}}&lt;br /&gt;
 const command_t commands[] PROGMEM =&lt;br /&gt;
 {&lt;br /&gt;
    { func1, 0, &amp;quot;Befehl 1&amp;quot; },&lt;br /&gt;
    { func2, 3, &amp;quot;Befehl für func2&amp;quot; }&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Sucht in commands[] nach text und führt gegebenenfalls}}&lt;br /&gt;
 {{ccomment|die dazugehörige Funktion funcx mit Argument arg aus.}}&lt;br /&gt;
 {{ccomment|Liefert den Rückgabewert von funcx}}&lt;br /&gt;
 {{ccomment|oder -1, falls text nicht gefunden wurde.}}&lt;br /&gt;
 int execute (const char *text)&lt;br /&gt;
 {&lt;br /&gt;
    {{ccomment|Schleifenvariable}}&lt;br /&gt;
    unsigned char i;&lt;br /&gt;
 &lt;br /&gt;
    {{ccomment|Wandert durch das Array mit Kommando-Strukturen}}&lt;br /&gt;
    const command_t * cmd = commands;&lt;br /&gt;
 &lt;br /&gt;
    {{ccomment|sizeof wird von gcc ausgewertet und ist wie eine Konstante,}}&lt;br /&gt;
    {{ccomment|denn beide sizeofs sind zur Compilezeit bekannt}}&lt;br /&gt;
    for (i=0; i &amp;lt; sizeof(commands) / sizeof(command_t); i++)&lt;br /&gt;
    {&lt;br /&gt;
       {{ccomment|Ist das der gesuchte String?}} &lt;br /&gt;
       if (strcmp_P (text, cmd-&amp;gt;text))&lt;br /&gt;
       {&lt;br /&gt;
         {{ccomment|Nein, dann weitersuchen}}&lt;br /&gt;
         cmd++;&lt;br /&gt;
         continue;&lt;br /&gt;
       }&lt;br /&gt;
 &lt;br /&gt;
       {{ccomment|Ja}}&lt;br /&gt;
       int (*func)(int), arg;&lt;br /&gt;
 &lt;br /&gt;
       {{ccomment|Dann Funktionszeiger und Argument besorgen,}}&lt;br /&gt;
       func = (int(*)(int)) pgm_read_word (&amp;amp; cmd-&amp;gt;func);&lt;br /&gt;
       arg  = (int)         pgm_read_word (&amp;amp; cmd-&amp;gt;arg);&lt;br /&gt;
 &lt;br /&gt;
       {{ccomment|Funktion ausführen und deren Wert zurückliefern}} &lt;br /&gt;
       return func (arg);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    {{ccomment|text ist nicht in commands}}&lt;br /&gt;
    return -1;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Nachteil dabei ist, daß jeder String den maximalen Platz von &amp;lt;tt&amp;gt;TEXT_LEN+1&amp;lt;/tt&amp;gt; Zeichen belegt.&lt;br /&gt;
Falls man da noch weiter sparen will, dann kann man die Strings wieder ins Flash legen und ihre Adresse in der Struktur merken. Dadurch belegt ein String nur noch Länge+3 Zeichen (+3 wegen 1 Endezeichen und 2 Bytes für seine in der Struktur gemerkte Adresse). Die Definition der Tabelle wird aber umständlicher, weil jeder String einzeln angegeben werden muss:&lt;br /&gt;
 #include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Die Kommandostruktur}}&lt;br /&gt;
 typedef struct &lt;br /&gt;
 {&lt;br /&gt;
    ...&lt;br /&gt;
    char * text;  {{ccomment|Zeiger auf Text}}&lt;br /&gt;
 } command_t;&lt;br /&gt;
 &lt;br /&gt;
 const prog_char str_1[] = &amp;quot;Befehl 1&amp;quot;;&lt;br /&gt;
 const prog_char str_2[] = &amp;quot;Befehl für func2&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
 const command_t commands[] PROGMEM =&lt;br /&gt;
 {&lt;br /&gt;
    { func1, 0, str_1 },&lt;br /&gt;
    { func2, 3, str_2 }&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Sucht in commands[] nach text und führt gegebenenfalls}}&lt;br /&gt;
 {{ccomment|die dazugehörige Funktion funcx mit Argument arg aus.}}&lt;br /&gt;
 {{ccomment|Liefert den Rückgabewert von funcx}}&lt;br /&gt;
 {{ccomment|oder -1, falls text nicht gefunden wurde.}}&lt;br /&gt;
 int execute (const char *text)&lt;br /&gt;
 {&lt;br /&gt;
    {{ccomment|Schleifenvariable}}&lt;br /&gt;
    unsigned char i;&lt;br /&gt;
 &lt;br /&gt;
    {{ccomment|Wandert durch das Array mit Kommando-Strukturen}}&lt;br /&gt;
    const command_t * cmd = commands;&lt;br /&gt;
 &lt;br /&gt;
    {{ccomment|sizeof wird von gcc ausgewertet und ist wie eine Konstante,}}&lt;br /&gt;
    {{ccomment|denn beide sizeofs sind zur Compilezeit bekannt}}&lt;br /&gt;
    for (i=0; i &amp;lt; sizeof(commands) / sizeof (command_t); i++)&lt;br /&gt;
    {&lt;br /&gt;
       const prog_char * text_P;&lt;br /&gt;
 &lt;br /&gt;
       {{ccomment|Liest die Startadresse von str_x}}&lt;br /&gt;
       text_P = (const prog_char *) pgm_read_word (&amp;amp; cmd-&amp;gt;text);&lt;br /&gt;
 &lt;br /&gt;
       {{ccomment|Ist das der gesuchte String?}}        &lt;br /&gt;
       if (strcmp_P (text, text_P))&lt;br /&gt;
       {&lt;br /&gt;
          ...&lt;br /&gt;
&lt;br /&gt;
==Lokale Variablen verwenden==&lt;br /&gt;
&lt;br /&gt;
Beim Manipulieren globaler Variablen kann es günstig sein, diese in eine lokale Variable zu kopieren, dort zu verändern, und sie danach wieder zu schreiben &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
char var;&lt;br /&gt;
&lt;br /&gt;
void foo1()&lt;br /&gt;
{&lt;br /&gt;
   var++;&lt;br /&gt;
   if (var &amp;gt; 10)&lt;br /&gt;
      var = 1;&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dadurch wird einmal unnötig gespeichert (der dritte Befehl kann vermieden werden).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
foo1:&lt;br /&gt;
  lds r24,var        ; *movqi/4 [length = 2]&lt;br /&gt;
  subi r24,lo8(-(1)) ; addqi3/2 [length = 1]&lt;br /&gt;
  sts var,r24        ; *movqi/3 [length = 2]&lt;br /&gt;
  cpi r24,lo8(11)    ; cmpqi/2  [length = 1]&lt;br /&gt;
  brlt .L3           ; branch   [length = 1]&lt;br /&gt;
  ldi r24,lo8(1)     ; *movqi/2 [length = 1]&lt;br /&gt;
  sts var,r24        ; *movqi/3 [length = 2]&lt;br /&gt;
.L3:&lt;br /&gt;
  ret   &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Indem man eine lokale Variable (&amp;lt;tt&amp;gt;var2&amp;lt;/tt&amp;gt;) verwendet für die Änderung von &amp;lt;tt&amp;gt;var&amp;lt;/tt&amp;gt; vermeidet man dies:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
char var;&lt;br /&gt;
&lt;br /&gt;
void foo2()&lt;br /&gt;
{&lt;br /&gt;
   char var2 = var;&lt;br /&gt;
   &lt;br /&gt;
   var2++;&lt;br /&gt;
   if (var2 &amp;gt; 10)&lt;br /&gt;
      var2 = 1;&lt;br /&gt;
      &lt;br /&gt;
   var = var2;&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dadurch wird erst am Ende gespeichert. &amp;lt;tt&amp;gt;var2&amp;lt;/tt&amp;gt; lebt in Register &amp;lt;tt&amp;gt;r24&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
foo2:&lt;br /&gt;
  lds r24, var       ; *movqi/4   [length = 2]&lt;br /&gt;
  subi r24,lo8(-(1)) ; addqi3/2   [length = 1]&lt;br /&gt;
  cpi r24,lo8(11)    ; cmpqi/2    [length = 1]&lt;br /&gt;
  brlt .L2           ; branch     [length = 1]&lt;br /&gt;
  ldi r24,lo8(1)     ; *movqi/2   [length = 1]&lt;br /&gt;
.L2:&lt;br /&gt;
  sts var, r24       ; *movqi/3   [length = 2]&lt;br /&gt;
  ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei diesem einfachen Beispiel spart man lediglich eine Instruktion. Bei komplexeren Rechnungen oder längeren Datentypen kann es aber durchaus lohnender sein, in lokale Register zu kopieren.&lt;br /&gt;
&lt;br /&gt;
==Arithmetik==&lt;br /&gt;
&lt;br /&gt;
=== Daten zerlegen/zusammensetzen ===&lt;br /&gt;
&lt;br /&gt;
In systemnahen Programmen hat man oft was Problem, auf die einzelnen Bytes oder Bitfelder einer grösseren Datenstruktur zuzugreifen. Indem man sich ein Komposit baut, das die gewünschten Strukturen überlagert, kann man effizient z.B. auf Bytes zugreifen. Ausnahme sind Bitfelder, deren Verwendung etwas breiten Code ergibt. Bitfelder &amp;quot;von Hand&amp;quot; zu manipulieren, ist da manchmal effizienter, führt jedoch zu schlecht lesbarem Code.&lt;br /&gt;
&lt;br /&gt;
Oft benötigt wird der Zugriff auf die einzelnen Bytes eines &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, also der Zugriff auf die Bytes eines 16-Bit-Wertes:&lt;br /&gt;
&lt;br /&gt;
 typedef union&lt;br /&gt;
 {&lt;br /&gt;
    unsigned char  asByte[2];&lt;br /&gt;
    unsigned short asWord;&lt;br /&gt;
    int            asInt;&lt;br /&gt;
 } data16_t;&lt;br /&gt;
 &lt;br /&gt;
 data16_t data;&lt;br /&gt;
 ...&lt;br /&gt;
    int foo;&lt;br /&gt;
    uint8_t wert;&lt;br /&gt;
 &lt;br /&gt;
    data.asInt = foo;&lt;br /&gt;
    wert = data.asByte[1]; {{ccomment|die oberen 8 Bits von foo}}&lt;br /&gt;
&lt;br /&gt;
Ein komplexeres Beispiel, das noch mehr Datentypen überlagert:&lt;br /&gt;
 typedef ... foo_t;&lt;br /&gt;
 &lt;br /&gt;
 typedef union&lt;br /&gt;
 {&lt;br /&gt;
     unsigned char byte[4];      {{ccomment| Zugriff als Bytes (8 Bit) }}&lt;br /&gt;
     unsigned short word[2];     {{ccomment| Zugriff als Words (16 Bit) }}&lt;br /&gt;
     signed long slong;          {{ccomment| Zugriff als signed long (32 Bit) }}&lt;br /&gt;
 &lt;br /&gt;
     struct {{ccomment| Zugriff auf einzelne Bitgruppen }}&lt;br /&gt;
     {&lt;br /&gt;
         unsigned bit_0_3 : 4;   {{ccomment| 4 Bits (0..3) }}&lt;br /&gt;
         unsigned bit_4_8 : 5;   {{ccomment| 5 Bits (4..8) }}&lt;br /&gt;
         unsigned bit_9_21 : 13; {{ccomment| 13 Bits (9..21) }}&lt;br /&gt;
         unsigned bit_22_31: 10; {{ccomment| 10 Bits (22..31) }}&lt;br /&gt;
     };&lt;br /&gt;
 &lt;br /&gt;
     foo_t foo; {{ccomment| Zugriff als foo-Struktur }}&lt;br /&gt;
 } data_t;&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 {&lt;br /&gt;
     data_t data;&lt;br /&gt;
 &lt;br /&gt;
     data.byte[2] = 12;          {{ccomment| setzt byte 2 auf 12 }}&lt;br /&gt;
     data.bit_4_8 = 0x1f;        {{ccomment| setzt bits 4..8 (5 Stück) alle auf 1 }}&lt;br /&gt;
 &lt;br /&gt;
     int anInt = data.foo.anInt; {{ccomment| liest ein Feld von foo (hier ein int) }}&lt;br /&gt;
     ...&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
===libgcc2 verwenden===&lt;br /&gt;
&lt;br /&gt;
In der libgcc2 sind einige Arithmetik-Routinen in Assembler implementiert. Dazu gehören ein paar Algorithmen zu Division (mit Rest) und Multiplikation. &lt;br /&gt;
&lt;br /&gt;
Von diesen Algorithmen werden durch die avr-libc jedoch nur zwei Strukturen und Funktionen veröffentlicht: &amp;lt;tt&amp;gt;div_t&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;ldiv_t&amp;lt;/tt&amp;gt; resp. die Funktionen &amp;lt;tt&amp;gt;div()&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;ldiv()&amp;lt;/tt&amp;gt;. Siehe dazu deine Dokumentation zur avr-libc. Damit kann man Quotient und zusätzlich den Rest bei einer Division 16/16 bzw. 32/32 berechnen lassen; den Rest bekommt man quasi kostenlos als Nebenprodukt. Das ist praktisch, wenn man z.b. eine Zahl in Dezimaldarstellung umwandeln möchte oder von/nach [[BCD]].&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den via avr-libc veröffentlichten Funktionen gibt es aber noch Routinen, die z.B. auf 8-Bit-Werten operieren oder mit &amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt; Typen und dementsprechend effizienter sind.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel: Umwandeln nach Dezimalstring'''&lt;br /&gt;
&lt;br /&gt;
Hier ein Beispiel, das Division mit Rest für &amp;lt;tt&amp;gt;unsigned short&amp;lt;/tt&amp;gt; verwendet, um eine 16-Bit-Zahl in Dezimaldarstellung zu wandeln:&lt;br /&gt;
&lt;br /&gt;
 {{ccomment| Struktur definieren und Funktion bekannt machen }}&lt;br /&gt;
 typedef struct&lt;br /&gt;
 {&lt;br /&gt;
     unsigned short quot;&lt;br /&gt;
     unsigned short rem;&lt;br /&gt;
 } udiv_t;&lt;br /&gt;
 &lt;br /&gt;
 extern udiv_t udiv (unsigned short, unsigned short) __asm__(&amp;quot;__udivmodhi4&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment| 5 Ziffern (0...65535) und evtl. noch eine führende 0 }}&lt;br /&gt;
 #define DIGITS 6&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment| +1 wegen String-Ende (wird im Startup auf 0 gesetzt) }}&lt;br /&gt;
 char string[DIGITS+1];&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment| Wandelt zahl in Dezimaldarstellung um. }}&lt;br /&gt;
 {{ccomment| Der return-Wert zeigt irgendwo ins string[]-Array. }}&lt;br /&gt;
 {{ccomment| string[] wird verändert. }}&lt;br /&gt;
 char* toString (unsigned short zahl)&lt;br /&gt;
 {&lt;br /&gt;
     {{ccomment| s zeigt auf das Ende von string }}&lt;br /&gt;
     {{ccomment| string wird von hinten nach vorne gefüllt }}&lt;br /&gt;
     char *s = string + DIGITS;&lt;br /&gt;
  &lt;br /&gt;
     {{ccomment| qrem enthält Quotient (quot) und Rest (rem) der Divisionen }}&lt;br /&gt;
     udiv_t qrem = {.quot = zahl}; &lt;br /&gt;
 &lt;br /&gt;
     do&lt;br /&gt;
     {&lt;br /&gt;
         {{ccomment| Division mit Rest durch 10 }}&lt;br /&gt;
         {{ccomment| quot: Ergebnis für den nächsten Durchlauf }}&lt;br /&gt;
         {{ccomment| rem: Rest ist die Ziffer im 10er-System }}&lt;br /&gt;
         qrem = udiv (qrem.quot, 10);&lt;br /&gt;
  &lt;br /&gt;
         {{ccomment| Ziffer in Zeichen wandeln und speichern }}&lt;br /&gt;
         *(--s) = '0' + qrem.rem;&lt;br /&gt;
     } &lt;br /&gt;
     while (0 != qrem.quot);&lt;br /&gt;
  &lt;br /&gt;
     {{ccomment| Falls eine führende '0' gespeichert wurde: weg damit }}&lt;br /&gt;
     {{ccomment| ausser zahl war selbst schon 0 }}&lt;br /&gt;
     if (*s == '0' &amp;amp;&amp;amp; *(s+1) != '\0')&lt;br /&gt;
         s++;&lt;br /&gt;
 &lt;br /&gt;
     return s;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Falls man eine Division und/oder Rest für 8-Bit braucht, dann geht für &amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt; analog. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel: BCD-Umrechnung'''&lt;br /&gt;
&lt;br /&gt;
Wandeln einer 8-Bit-Zahl &amp;lt;tt&amp;gt;0 &amp;amp;lt;= num &amp;amp;lt; 100&amp;lt;/tt&amp;gt; nach [[BCD]]&lt;br /&gt;
&lt;br /&gt;
 typedef struct&lt;br /&gt;
 {&lt;br /&gt;
     unsigned char quot; {{ccomment| Quotient }}&lt;br /&gt;
     unsigned char rem;  {{ccomment| Rest (remainder) }}&lt;br /&gt;
 } udiv8_t;&lt;br /&gt;
 &lt;br /&gt;
 extern udiv8_t udiv8 (unsigned char, unsigned char) __asm__ (&amp;quot;__udivmodqi4&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment| Wandelt num nach BCD um, 0 &amp;lt;&amp;amp;#61; num &amp;lt;&amp;amp;#61; 99 }}&lt;br /&gt;
 {{ccomment| return-Wert ist dann 0x0 &amp;lt;&amp;amp;#61; return &amp;lt;&amp;amp;#61; 0x99 }}&lt;br /&gt;
 unsigned char to_bcd (unsigned char num)&lt;br /&gt;
 {&lt;br /&gt;
     udiv8_t qrem = udiv8 (num, 10);&lt;br /&gt;
 &lt;br /&gt;
     return (unsigned char) (qrem.quot &amp;lt;&amp;lt; 4) | qrem.rem;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Division durch Multiplikation===&lt;br /&gt;
===Vermeiden von float und double===&lt;br /&gt;
&lt;br /&gt;
=Inkompatibilität=&lt;br /&gt;
&lt;br /&gt;
[[GCC]] &amp;amp;ndash; und somit auch avr-gcc &amp;amp;ndash; werden ständig weiter entwickelt. Dies betrifft das Beheben von Fehlern, die Unterstützung neuer Architekturen/Sprachen/Betriebssysteme, Implementierung neuer Optimierungsalgorithmen, Vereinheitlichungen, etc.&lt;br /&gt;
&lt;br /&gt;
Leider führt dies auch zu Inkompatibilitäten verschiedener avr-gcc-Versionen untereinander, und eine C-Quelle, die mit einer Version von avr-gcc fehler- und warnungsfrei übersetzt werden kann, ist mit einer anderen Version möglicherweise nicht compilierbar.&lt;br /&gt;
&lt;br /&gt;
Die avr-gcc Version kann man anzeigen lassen, indem man in einer Shell/Eingabeaufforderung eintippt&lt;br /&gt;
 avr-gcc -v&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;#include &amp;lt;avr/signal.h&amp;gt;&amp;lt;/tt&amp;gt;: In Versionen bis 3.4.4 werden in dieser Header-Datei u.a. die Makros &amp;lt;tt&amp;gt;SIGNAL()&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;INTERRUPT()&amp;lt;/tt&amp;gt; definiert, die man braucht, wenn man eine C-Funktion als Interrupt-Routine ([[ISR]]) kennzeichnen will. In neueren Versionen ab 3.4.5 sind diese Definitionen in den Header &amp;lt;tt&amp;gt;avr/interrupt.h&amp;lt;/tt&amp;gt; gewandert, wo auch Makros wie &amp;lt;tt&amp;gt;sei()&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;cli()&amp;lt;/tt&amp;gt; definiert werden. Die Inkludierung von &amp;lt;tt&amp;gt;avr/signal.h&amp;lt;/tt&amp;gt; in den neueren avg-gcc Versionen führt zu einer Warnung, irgendwann vielleicht sogar zu einem Fehler, weil die Datei nicht mehr bei avr-gcc dabei ist und daher nicht mehr gefunden wird.&lt;br /&gt;
: '''Verwendet man bei einer älteren avr-gcc-Version &amp;lt;tt&amp;gt;SIGNAL&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;INTERRUPT&amp;lt;/tt&amp;gt; ohne &amp;lt;tt&amp;gt;avr/signal.h&amp;lt;/tt&amp;gt; zu includen, wird u.U. stillschweigend falscher Code erzeugt.'''&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;#include &amp;lt;util/...h&amp;gt;&amp;lt;/tt&amp;gt;: In &amp;lt;tt&amp;gt;util&amp;lt;/tt&amp;gt; stehen jetzt Header wie &amp;lt;tt&amp;gt;util/parity.h&amp;lt;/tt&amp;gt; oder das vielverwendete &amp;lt;tt&amp;gt;util/delay.h&amp;lt;/tt&amp;gt;, die vormals im Include-Unterverzeichnis &amp;lt;tt&amp;gt;avr&amp;lt;/tt&amp;gt; zu finden waren.&lt;br /&gt;
&lt;br /&gt;
;Interrupt Service Routinen: Auch die API zur Definition von [[ISR]]s hat sich von avr-gcc Version 3.x zur Version 4.x geändert:&lt;br /&gt;
:'''avr-gcc 3.x'''&lt;br /&gt;
::{|&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SIGNAL (SIG_INTERRUPT0)&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt Code */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
INTERRUPT (SIG_OVERFLOW0)&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt Code */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
:'''avr-gcc 4.x'''&lt;br /&gt;
::{|&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ISR (INT0_vect)&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt Code */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void TIMER0_OVF_vect (void) __attribute__((interrupt));&lt;br /&gt;
void TIMER0_OVF_vect (void)&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt Code */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Bugs=&lt;br /&gt;
&lt;br /&gt;
==== Bit 7 bei SFR-Zugriff ====&lt;br /&gt;
&lt;br /&gt;
Bei Sequenzen wie&lt;br /&gt;
 PORTB &amp;amp;= ~ (1 &amp;lt;&amp;lt; 7);&lt;br /&gt;
 PORTD &amp;amp;= ~ (1 &amp;lt;&amp;lt; 7);&lt;br /&gt;
&lt;br /&gt;
macht avr-gcc eine CSE-Optimierung (common subexpression elimination). Er legt die Konstante 127 (&amp;lt;tt&amp;gt;~(1 &amp;lt;&amp;lt; 7)&amp;lt;/tt&amp;gt;) in ein Register und verwendet den Registerinhalt, anstatt die Konstante direkt zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Das führt dazu, daß statt der gewünschten Befehlsfolge&lt;br /&gt;
 ; Sequenz 1&lt;br /&gt;
 cbi 37-0x20, 7	&lt;br /&gt;
 cbi 43-0x20, 7&lt;br /&gt;
Sequenzen folgender Gestalt erzeugt werden:&lt;br /&gt;
 ; Sequenz 2&lt;br /&gt;
 ldi r18,     lo8(127)   ; 127 nach R18&lt;br /&gt;
 &lt;br /&gt;
 in  r19,     37-0x20    ; PORTB nach R19 lesen&lt;br /&gt;
 ; Wird hier eine ISR ausgeführt, die PORTB verändert, dann wird die&lt;br /&gt;
 ; Änderung mit dem folgenden OUT überschrieben&lt;br /&gt;
 and r19,     r18	; oberstes Bit löschen&lt;br /&gt;
 ; dito&lt;br /&gt;
 out 37-0x20, r19	; PORTB schreiben&lt;br /&gt;
 &lt;br /&gt;
 in r19,      43-0x20	; analog&lt;br /&gt;
 and r19,     r18	&lt;br /&gt;
 out 43-0x20, r19	&lt;br /&gt;
&lt;br /&gt;
Abgesehen davon, daß Sequenz&amp;amp;nbsp;2 deutlich mehr Programmspeicher und Laufzeit benötigt als Sequenz&amp;amp;nbsp;1, kann es zu folgendem Fehler kommen:&lt;br /&gt;
&lt;br /&gt;
Bei der zweiten Codesequenz erfolgt der Zugriff auf die SFRs nicht atomar. Wird der C-Code in einem Programm ausgeführt, das in einer [[ISR]] zB Port B3 verändert und wird diese ISR zwischen dem IN und dem OUT Befehl ausgeführt, dann überschreibt der OUT-Befehl den Wert von PORTB und die Aktion für Port B3 in der ISR wird wieder rückgängig gemacht. Das ist dann ein Programmfehler.&lt;br /&gt;
&lt;br /&gt;
Damit das Problem zum Tragen kommt, müssen mehrere Bedingungen erfüllt sein:&lt;br /&gt;
* Bei mindestens zwei C-Befehlen wird der Wert 127 als 8-Bit-Wert benötigt. Das ist zB auch der Fall, wenn dieser Wert nur gespeichert wird oder modulo 0x80 gerechnet wird.&lt;br /&gt;
* Mindestens einer dieser Befehle löscht Bit 7 eines SFR aus dem bitadressierbaren I/O-Bereich. (Ausser PORTx oder DDRx sind in diesem Bereich noch weitere SFR untergebracht.)&lt;br /&gt;
* Im Programm wird auf unterschiedlichen [[Interrupt]]-Ebenen auf dieses SFR zugegriffen und die oben gezeigt Stelle kann von der ISR unterbrochen werden.&lt;br /&gt;
* Die beiden C-Befehle müssen nicht unmittelbar aufeinander folgen. Es können auch andere C-Befehle dazwischen stehen. &lt;br /&gt;
&lt;br /&gt;
Bei den meisten Programmen wird das angesprochene Problem nicht zu einem Fehler führen. Falls doch, kann man dem begegnen mit folgenden &lt;br /&gt;
&lt;br /&gt;
;Workarounds:&lt;br /&gt;
* Die C-Stelle wird in CLI/SEI eingeschlossen und kann damit nicht mehr von einer ISR unterbrochen werden.&lt;br /&gt;
* Alternativ schreibt man vor und nach jedem problematischen SFR-Zugriff folgendes Kommando:&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 __asm volatile (&amp;quot;&amp;quot;::);&lt;br /&gt;
|}&lt;br /&gt;
:Dieses Kommando erzeugt keine Assembler-Instruktionen, vermeidet aber die unerwünschte &amp;quot;Optimierung&amp;quot; im gcc, und es entsteht Code gemäß Sequenz&amp;amp;nbsp;1.&lt;br /&gt;
* Alternativ definiert man sich ein Makro, mit dem man die Portzugriffe tätigt:&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 #define CBI(A,B)    __asm volatile (&amp;quot;cbi\t%0, %1&amp;quot; :: &amp;quot;M&amp;quot; (_SFR_IO_ADDR(A)), &amp;quot;M&amp;quot; (B))&lt;br /&gt;
|}&lt;br /&gt;
:Und löscht das Bit mit&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 CBI (PORTB, 7);&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;tt&amp;gt;__builtin_return_address(0)&amp;lt;/tt&amp;gt; ====&lt;br /&gt;
ist entgegen der Spezifikation nicht implementiert und liefert in der Regel ein falsches Ergebnis.&lt;br /&gt;
&lt;br /&gt;
;Workaround:&lt;br /&gt;
&lt;br /&gt;
(hier für eine ISR):&lt;br /&gt;
 #include &amp;lt;stdarg.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|The return address}}&lt;br /&gt;
 unsigned short volatile return_addr;&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Define our special SIGNAL (INTERRUPT analoguous)}}&lt;br /&gt;
 #define SIGNAL_BRA(signame,var)                                         \&lt;br /&gt;
      void signame (unsigned short var, ...) __attribute__ ((signal));   \&lt;br /&gt;
      void signame (unsigned short var, ...)&lt;br /&gt;
 &lt;br /&gt;
 #define SWAP_BYTES(x) (((x) &amp;gt;&amp;gt; 8) | ((x) &amp;lt;&amp;lt; 8))&lt;br /&gt;
 &lt;br /&gt;
 SIGNAL_BRA (SIG_OUTPUT_COMPARE1A, dummy)&lt;br /&gt;
 {&lt;br /&gt;
    {&lt;br /&gt;
       va_list vlist;&lt;br /&gt;
       va_start (vlist, dummy);&lt;br /&gt;
  &lt;br /&gt;
       {{ccomment|Get the return address from the stack}}&lt;br /&gt;
       dummy = va_arg (vlist, unsigned short);&lt;br /&gt;
 &lt;br /&gt;
       {{ccomment|Convert stack address to code location}}&lt;br /&gt;
       addr = SWAP_BYTES(dummy) &amp;lt;&amp;lt; 1;&lt;br /&gt;
       va_end (vlist);&lt;br /&gt;
    }&lt;br /&gt;
    {{ccomment|ISR Code}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== gcc 4.x ==== &lt;br /&gt;
&lt;br /&gt;
In der 4er-Version gab es tiefgreifende interne Änderungen im Compiler; er ist noch instabil und kann momentan nicht für den Produktiv-Einsatz empfohlen werden (Stand 02/2006). &lt;br /&gt;
&lt;br /&gt;
Die Auswirkungen der Optimierungen auf das Zielsystem &amp;lt;tt&amp;gt;avr&amp;lt;/tt&amp;gt; bleibt abzuwarten, dürfte aber nicht wesentlich sein. Die neue 4-er Version wurde u.a. deshalb aufgelegt, um mit dem Intel-Compiler gleichzuziehen &amp;amp;ndash; also im Hinblick auf das Zielsystem &amp;lt;tt&amp;gt;i386&amp;lt;/tt&amp;gt;) gemacht. &lt;br /&gt;
&lt;br /&gt;
Auch nach dem Release der 4-er Version wird die 3-er Version weiterentwickelt, da erst nach 1-2 Jahren nach Release einer neuer Major-Version ein Umstieg anzuraten ist und auch erst dann getätigt wird (zumindest im professionellen Bereich).&lt;br /&gt;
&lt;br /&gt;
=Abkürzungen und Bezeichnungen=&lt;br /&gt;
; [[GCC]]: GNU Compiler Collection&lt;br /&gt;
; gcc: GNU C-Compiler&lt;br /&gt;
; GPR: '''G'''eneral '''P'''urpose '''R'''egister&lt;br /&gt;
; [[ISR]]: [[Interrupt|'''I'''nterrupt]] '''S'''ervice '''R'''outine&lt;br /&gt;
; [[IRQ]]: '''I'''nterrupt '''R'''e'''q'''uest&lt;br /&gt;
; Prolog/Epilog: Code am Anfang/Ende jeder Funktionen/ISR, der dazu dient, verwendete Register zu sichern, den Stack-Frame für lokale [[Variable|Variablen]] anzulegen (falls benötigt), Stackpointer zu setzen, zurück zu springen (&amp;lt;tt&amp;gt;ret&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;reti&amp;lt;/tt&amp;gt;), etc.&lt;br /&gt;
; SFR: '''S'''pecial '''F'''unction '''R'''egister&lt;br /&gt;
; Target: Zielsystem, in unserem Falle avr&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[C-Tutorial]]&lt;br /&gt;
'''Code-Beispiele'''&lt;br /&gt;
* [[Hallo Welt für AVR (LED blinken)]] - ein erstes Beispiel für avr-gcc&lt;br /&gt;
*[[:Kategorie:Quellcode_C|C-Codebeispiele]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
'''Details'''&lt;br /&gt;
* [[Inline-Assembler in avr-gcc|Inline-Assembler]]&lt;br /&gt;
* [[avr-gcc/Interna|Interna von avr-gcc]]&lt;br /&gt;
&lt;br /&gt;
'''Installation (Linux)'''&lt;br /&gt;
* [[Linuxdistribution_Avr-live-cd]]&lt;br /&gt;
* [[avr-gcc und avrdude installieren]]&lt;br /&gt;
'''Sonstiges'''&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Speicherverbrauch bestimmen mit avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[Dev-Cpp IDE]]&lt;br /&gt;
* [[AVR]]&lt;br /&gt;
----&lt;br /&gt;
* [[Sourcevergleich]]&lt;br /&gt;
* [[Codevergleich AVR-Compiler]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
==Dokumentation==&lt;br /&gt;
* [http://gcc.gnu.org/onlinedocs/ GCC online documentation (en)] Offline findest du die Doku für gcc, cpp (Präprozessor) und avr-libc bei [[WinAVR]] in&lt;br /&gt;
:&amp;lt;pre&amp;gt;&amp;lt;GCC_HOME&amp;gt;/doc/gcc/&amp;lt;/pre&amp;gt;&lt;br /&gt;
: bzw.&lt;br /&gt;
:&amp;lt;pre&amp;gt;&amp;lt;GCC_HOME&amp;gt;/doc/avr-libc/&amp;lt;/pre&amp;gt;&lt;br /&gt;
:Online finden sich die Dokumente in&lt;br /&gt;
* [http://gcc.gnu.org/onlinedocs/gcc.pdf gcc.pdf (1900 kByte)] - Dokumentation des C/C++/Java-Compilers GCC (en)&lt;br /&gt;
* [http://gcc.gnu.org/onlinedocs/cpp.pdf cpp.pdf (470 kByte)] - Dokumentation des C-Präprozessors (en)&lt;br /&gt;
* [http://www.nongnu.org/avr-libc/user-manual/modules.html http://www.nongnu.org/avr-libc/user-manual] - Dokumentation zur avr-libc.&lt;br /&gt;
&lt;br /&gt;
== Downloads==&lt;br /&gt;
* [http://sourceforge.net/projects/winavr/ WinAVR-Projekt bei sourceforge.net (en)]&lt;br /&gt;
* [http://cdk4avr.sourceforge.net/ avr-gcc und toolchain als Linux-Paket bei sourceforge.net (en)]&lt;br /&gt;
* [[Linuxdistribution_Avr-live-cd]]&lt;br /&gt;
== Tipps, Installation ==&lt;br /&gt;
*[http://www.nongnu.org/avr-libc/user-manual/install_tools.html ''&amp;quot;Installing the GNU Tool Chain&amp;quot;''] Hilfe zum Build und Installation von GCC, binutils, etc unter Linux&lt;br /&gt;
* Im GCC-Handbuch, siehe [[#Dokumentation|Dokumentation]].&lt;br /&gt;
* [http://www.linuxfocus.org/Deutsch/November2004/article352.shtml www.linuxfocus.org (Artikel)] - Tipps zu Build und Installation von avr-gcc, binutils und avr-libc unter Linux&lt;br /&gt;
* [http://users.rcn.com/rneswold/avr/ Rich Neswold: ''A GNU Development Environment for the AVR Microcontroller'']&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/24166 www.mikrocontroller.net (Foren-Beitrag)] - Installation von GCC und Toolchain unter Mac OS X&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=125603#125603 www.roboternetz.de (Foren-Beitrag)] ''avrgcc + avrdude installieren''&lt;br /&gt;
&lt;br /&gt;
== Sonstiges ==&lt;br /&gt;
* [http://gcc.gnu.org/ Offizielle Homepage von GCC (en)]&lt;br /&gt;
* [http://de.wikipedia.org/wiki/GNU_Compiler_Collection GCC in der deutschen Wikipedia]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial avr-gcc-Tutorial auf mikrocontroller.net]&lt;br /&gt;
* [http://www.avrfreaks.net/AVRGCC/ avr-gcc bei avrfreaks.net (en)]&lt;br /&gt;
* [http://savannah.nongnu.org/projects/avr-libc/ Nützliche GCC Runtime-Libary]&lt;br /&gt;
&lt;br /&gt;
=Autor=&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:SprinterSB|SprinterSB]] 11:27, 7. Dez 2005 (CET)&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Quellcode C|!]]&lt;br /&gt;
[[Kategorie:Software]]&lt;/div&gt;</summary>
		<author><name>Inrfb2</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Avr-gcc&amp;diff=10431</id>
		<title>Avr-gcc</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Avr-gcc&amp;diff=10431"/>
				<updated>2007-03-20T10:05:57Z</updated>
		
		<summary type="html">&lt;p&gt;Inrfb2: /* Zugiff auf Bytes und Worte */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''avr-gcc''' ist ein freier C-[[Compiler]], mit dem man C-Programme zu ausführbaren Programmen übersetzen kann, die auf [[Microcontroller]]n der [[AVR]]-Familie lauffähig sind. &lt;br /&gt;
An Sprachen versteht avr-gcc sowohl C als auch [[#C%2b%2b|C++]]. &lt;br /&gt;
Neben Standard-C bzw. ANSI-C versteht avr-gcc auch GNU-C, das etwas mehr Möglichkeiten und kleinere Spracherweiterungen bietet.&lt;br /&gt;
&lt;br /&gt;
avr-gcc kann auch dazu verwendet werden, um C/C++ Programme nach Assembler zu übersetzen oder um Bibliotheken zu erstellen, die später in unterschiedlichen Projekten verwendet werden können.&lt;br /&gt;
&lt;br /&gt;
Wie bei allen aus der UNIX-Welt kommenden Programmen ist das Kommando-Interface von avr-gcc die Shell bzw. die Kommandozeile, über die Optionen, Parameter, Einstellungen und die Namen der zu übersetzenden Dateien angegeben werden. &lt;br /&gt;
&lt;br /&gt;
=How to Read=&lt;br /&gt;
&lt;br /&gt;
Dieser Artikel bespricht avr-gcc Version 3.x. Er ist kein C-Tutorial und kein AVR-Handbuch &amp;amp;ndash; das würde den Umfang des Artikels bei weitem sprengen. &lt;br /&gt;
&lt;br /&gt;
Der Artikel ist ein Handbuch zu avr-gcc. Er bespricht zum Beispiel, wie man avr-gcc anwendet und Besonderheiten von avr-gcc-C,&lt;br /&gt;
die nicht zum Sprachumfang von C gehören.&lt;br /&gt;
Dazu zählen die Definition von [[#Interrupts|Interrupt]] Service Routinen ([[ISR|ISRs]]) &lt;br /&gt;
oder wie man Daten ins [[EEPROM]] legt.&lt;br /&gt;
&lt;br /&gt;
Es wird also besprochen, ''wie'' eine ISR zu definieren ist, aber nicht,&lt;br /&gt;
''warum'' das  gegebenenfalls notwendig oder nicht notwendig ist. &lt;br /&gt;
''Warum'' etwas gemacht wird, ist abhängig von der gestellten Aufgabe,&lt;br /&gt;
etwa ''&amp;quot;Initialisiere den [[UART]] zur Benutzung mit 9600 Baud&amp;quot;''.&lt;br /&gt;
Dafür enthält dieser Artikel zusammen mit dem AVR-Handbuch das Rüstzeug, &lt;br /&gt;
bietet aber keine Lösungen für konkrete Aufgaben.&lt;br /&gt;
&lt;br /&gt;
Neben diesem Artikel gibt es den Unterartikel [[avr-gcc/Interna|Interna von avr-gcc]] wo Dinge wie die Registerverwendung, Attribute, Builtins und Sections von avr-gcc dargestellt werden. Zudem findet sich dort ein Überblick über die Arbeitsweise von gcc mit den Schritten&lt;br /&gt;
* Precompilieren&lt;br /&gt;
* Compilieren&lt;br /&gt;
* Assemblieren&lt;br /&gt;
* Linken&lt;br /&gt;
Ein weiterer Unterartikel widmet sich dem Thema [[Inline-Assembler in avr-gcc]].&lt;br /&gt;
&lt;br /&gt;
In den [[:Kategorie:Quellcode C|C-Codebeispielen]]&lt;br /&gt;
befindet sich das ausführlichere Beispiel &amp;quot;[[Hallo Welt für AVR (LED blinken)]]&amp;quot;,&lt;br /&gt;
das nur eine [[Diode#Lumineszenzdiode|LED]] blinkt und zeigt, &lt;br /&gt;
wie ein kleines Projekt mit avr-gcc compiliert werden kann.&lt;br /&gt;
&lt;br /&gt;
Es gibt ein [[C-Tutorial]], das jedoch noch unvollständig und teilweise feherhaft ist (Stand 02/2006). Darüber hinaus gibt es ein [http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial C-Tutorial bei www.mikrocontroller.net].&lt;br /&gt;
&lt;br /&gt;
=Benutzer-Schnittstelle=&lt;br /&gt;
&lt;br /&gt;
Die Benutzer-Schnittstelle von avr-gcc ist &amp;amp;ndash; wie für alle Programme, die aus der UNIX-Welt kommen &amp;amp;ndash; die Kommandozeile einer Shell, Console bzw. Eingabeaufforderung. &lt;br /&gt;
&lt;br /&gt;
Im einfachsten Fall sieht ein Aufruf von avr-gcc also so aus:&lt;br /&gt;
 &amp;gt; avr-gcc&lt;br /&gt;
Dabei das '&amp;lt;tt&amp;gt;&amp;gt;&amp;lt;/tt&amp;gt;' nicht mittippen, und ein ENTER am Ende der Zeile drücken.&lt;br /&gt;
Die Antwort bei korrekter Installation ist dann&lt;br /&gt;
 avr-gcc: no input files&lt;br /&gt;
Was bedeutet: das Programm avr-gcc wurde vom Betriebssystem gefunden und konnte/durfte gestartet werden. Dann gibt avr-gcc eine Fehlermeldung aus und beendet die Ausführung, weil er keine Eingabedatei(en) bekommen hat &amp;amp;#150; was ja auch stimmt. Soweit ist also alles in Butter.&lt;br /&gt;
&lt;br /&gt;
Um eine C-Datei &amp;lt;tt&amp;gt;foo.c&amp;lt;/tt&amp;gt; mir avr-gcc optimiert zu einem lauffähigen elf-Programm &amp;lt;tt&amp;gt;foo.elf&amp;lt;/tt&amp;gt; für einen [[ATmega32]] zu compileren, würde man angeben&lt;br /&gt;
 &amp;gt; avr-gcc -O2 -mmcu=atmega32 foo.c -o foo.elf&lt;br /&gt;
Hat man seine Quellen auf zwei oder mehre Dateien verteilt, geht es analog:&lt;br /&gt;
 &amp;gt; avr-gcc -O2 -mmcu=atmega32 foo.c foo2.c -o foo.elf&lt;br /&gt;
&lt;br /&gt;
Will man nur eine Objekt-Datei erstellen (nur compilieren, nicht linken), dann geht das wie folgt. Das kann günstig sein bei grösseren Projekten, wenn man das Projekt neu erzeugen will, aber nur in einer Quelldatei was geändert hat. Oder wenn das Objekt in einer Bibliothek landen soll.&lt;br /&gt;
 &amp;gt; avr-gcc -O2 -c -mmcu=atmega32 foo.c -o foo.o&lt;br /&gt;
&lt;br /&gt;
Die ausführbare Gesamtdatei &amp;lt;tt&amp;gt;foo_all.elf&amp;lt;/tt&amp;gt; erhält man dann, indem alle Objekte zusammenlinkt:&lt;br /&gt;
 &amp;gt; avr-gcc -mmcu=atmega32 foo.o foo2.o foo3.o -o foo_all.elf&lt;br /&gt;
&lt;br /&gt;
Um die ausführbare Datei in das oft verwendete Intex-HEX-Format umzuwandeln (einmal fürs Programm, einmal für ein Abbild des [[EEPROM]]s) gibt man an:&lt;br /&gt;
 &amp;gt; avr-objcopy -O ihex -j .text -j .data                         foo_all.elf  foo_all.hex&lt;br /&gt;
 &amp;gt; avr-objcopy -O ihex -j .eeprom --change-section-lma .eeprom=0 foo_all.elf  foo_all_eeprom.hex&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[GCC]] war immer Kommandozeilen-orientiert und wird es auch immer bleiben, denn das hat gute Gründe:&lt;br /&gt;
* ein Compiler ist ein Compiler ist ein Compiler (und keine grafische Bedienschnittstelle)&lt;br /&gt;
* die Plattformabhängigkeit wird auf ein Minimum reduziert&lt;br /&gt;
* es gibt die Möglichkeit, avr-gcc per Skript oder [[make]] zu starten&lt;br /&gt;
* avr-gcc kann durchaus in eine Umgebung integriert werden: in einen Editor oder in eine GUI wie neuere Versionen von AVR-Studio erfolgreich beweisen, etc. Der avr-gcc-Aufruf kann sogar von einem Server-Socket oder einer Web-Application heraus erfolgen, welche ein C-Programm empfängt, es von avr-gcc übersetzen lässt, und das Resultat zurückschickt oder sonst was damit anstellt.&lt;br /&gt;
* Lizenzgründe: eine Umgebung, die avr-gcc integriert, kann durchaus proprietär oder nicht quelloffen sein und muss nicht der [[Freie Software|GPL]] unterliegen. Wieder ist AVR-Studio ein Beispiel.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Unterstützte AVR-Derivate=&lt;br /&gt;
;Classic AVR&amp;amp;#58;: [[AT90S1200]], [[AT90S2313]], [[AT90S8515]], [[AT90S8535]], [[AT90S4433]], [[AT90S4414]], [[AT90S4434]], [[AT90S2323]], [[AT90S2333]], [[AT90S2343]], &lt;br /&gt;
&lt;br /&gt;
;tinyAVR&amp;amp;#58;: [[ATtiny10]], [[ATtiny11]], [[ATtiny12]], [[ATtiny15]], [[ATtiny28]], [[ATtiny22]], [[ATtiny26]], [[AT90C8534]], [[AT86rf401]], [[ATtiny13]], [[ATtiny2313]], [[ATtiny261]], [[ATtiny461]], [[ATtiny861]], [[ATtiny24]], [[ATtiny44]], [[ATtiny84]], [[ATtiny25]], [[ATtiny45]], [[ATtiny85]]&lt;br /&gt;
&lt;br /&gt;
;megaAVR&amp;amp;#58;: [[ATmega603]], [[ATmega103]], [[AT76C711]], [[ATmega48]], [[ATmega8]], [[ATmega83]], [[ATmega85]], [[ATmega88]], [[ATmega8515]], [[ATmega8535]], [[ATmega16]], [[ATmega161]], [[ATmega162]], [[ATmega163]], [[ATmega164p]], [[ATmega165]], [[ATmega165P]], [[ATmega168]], [[ATmega32]], [[ATmega323]], [[ATmega324P]], [[ATmega325]], [[ATmega3250]],  [[ATmega64]], [[ATmega640]], [[ATmega644]], [[ATmega644P]], [[ATmega128]], [[ATmega1280]], [[ATmega1281]], [[ATmega645]],  [[ATmega6450]], [[AT94K]]&lt;br /&gt;
&lt;br /&gt;
; [[LCD]] AVR&amp;amp;#58;: [[ATmega169]], [[ATmega169P]], [[ATmega329]], [[ATmega3290]], [[ATmega649]], [[ATmega6490]],&lt;br /&gt;
; Lightning AVR&amp;amp;#58;: [[AT90PWM2]], [[AT90PWM3]]&lt;br /&gt;
; [[CAN]] AVR&amp;amp;#58;: [[AT90CAN32]], [[AT90CAN64]], [[AT90CAN128]]&lt;br /&gt;
; Smart Battery&amp;amp;#58;: [[ATmega406]]&lt;br /&gt;
; [[USB]] AVR&amp;amp;#58;: [[AT43USB320]], [[AT43USB355]], [[AT90USB646]], [[AT90USB647]], [[AT90USB1286]], [[AT90USB1287]]&lt;br /&gt;
;&lt;br /&gt;
&lt;br /&gt;
Diese Liste kann man avr-gcc anzeigen lassen mit&lt;br /&gt;
 &amp;gt; avr-gcc --target-help&lt;br /&gt;
&lt;br /&gt;
=Kommandozeilen-Optionen=&lt;br /&gt;
Die Codegenerierung bei avr-gcc wird über Kommandozeilen-Optionen gesteuert. Diese legen fest, für welchen Controller Code zu erzeugen ist, wie stark optimiert wird, ob Debug-Informationen erzeugt werden, etc. Die Optionen teilen sich in zwei Gruppen: Optionen, die für alle GCC-Ports verfürgbar sind und maschinenspezifische Optionen, die nur für AVR verfügbar sind.&lt;br /&gt;
&lt;br /&gt;
Aus der Masse an GCC-Optionen kann hier nur ein kleiner Auszug der wichtigsten und am häufigsten verwendeten Optionen vorgestellt werden. Eine Auflistung aller GCC-Optionen mit Kurzbeschreibung umfasst knapp 1000 Zeilen &amp;amp;#150; ohne undokumentierte Optionen, versteht sich.&lt;br /&gt;
&lt;br /&gt;
==Allgemeine Optionen für GCC==&lt;br /&gt;
; &amp;lt;tt&amp;gt;--help&amp;lt;/tt&amp;gt;: Anzeige der wichtigsten Optionen&lt;br /&gt;
; &amp;lt;tt&amp;gt;--help -v&amp;lt;/tt&amp;gt;: Überschüttet einen mit Optionen&lt;br /&gt;
; &amp;lt;tt&amp;gt;--target-help&amp;lt;/tt&amp;gt;: Anzeige der wichtigsten maschinenspezifischen Optionen und der unterstützten AVR-Derivate&lt;br /&gt;
; &amp;lt;tt&amp;gt;-O0&amp;lt;/tt&amp;gt;: keine Optimierung&lt;br /&gt;
; &amp;lt;tt&amp;gt;-O1&amp;lt;/tt&amp;gt;: Optimierung&lt;br /&gt;
; &amp;lt;tt&amp;gt;-Os&amp;lt;/tt&amp;gt;: optimiert für Code-Größe&lt;br /&gt;
; &amp;lt;tt&amp;gt;-O2&amp;lt;/tt&amp;gt;: stärkere Optimierung für bessere Laufzeit&lt;br /&gt;
; &amp;lt;tt&amp;gt;-g&amp;lt;/tt&amp;gt;: erzeugt Debug-Informationen&lt;br /&gt;
; &amp;lt;tt&amp;gt;-c&amp;lt;/tt&amp;gt;: (pre)compilert und assembliert nur bis zum Objekt (&amp;lt;tt&amp;gt;*.o&amp;lt;/tt&amp;gt;), kein Link-Lauf&lt;br /&gt;
; &amp;lt;tt&amp;gt;-S&amp;lt;/tt&amp;gt;: (pre)compilert nur und erzeugt Assembler-Ausgabe (*.s)&lt;br /&gt;
; &amp;lt;tt&amp;gt;-E&amp;lt;/tt&amp;gt;: nur Precompilat (&amp;lt;tt&amp;gt;*.i&amp;lt;/tt&amp;gt;) erzeugen, kein Compilieren, kein Assemblieren, kein Linken&lt;br /&gt;
; &amp;lt;tt&amp;gt;-o &amp;lt;filename&amp;gt;&amp;lt;/tt&amp;gt;: legt den Name der Ausgabedatei fest&lt;br /&gt;
; &amp;lt;tt&amp;gt;-v&amp;lt;/tt&amp;gt;: zeigt Versionsinformationen an und ist geschwätzig (verbose): Anzeige der aufgerufenen tools&lt;br /&gt;
; &amp;lt;tt&amp;gt;-I&amp;lt;path&amp;gt;&amp;lt;/tt&amp;gt;: Angabe eines weiteren Include-Pfads, in dem Dateien mit &amp;lt;tt&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/tt&amp;gt; gesucht werden&lt;br /&gt;
; &amp;lt;tt&amp;gt;-E -dM &amp;lt;filename&amp;gt;&amp;lt;/tt&amp;gt;: Anzeige aller Defines&lt;br /&gt;
; &amp;lt;tt&amp;gt;-MM&amp;lt;/tt&amp;gt;: Für die angegebenen Eingabe-Dateien wird eine Ausgabe erzeugt, die als [[make|Makefile]]-Fragment dienen kann und die Anhängigkeiten (dependencies) der Objekte von den Quellen/Headern beschreibt.&lt;br /&gt;
; &amp;lt;tt&amp;gt;-D&amp;lt;name&amp;gt;&amp;lt;/tt&amp;gt;: Definiert Makro &amp;lt;tt&amp;gt;&amp;lt;name&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
; &amp;lt;tt&amp;gt;-D&amp;lt;name&amp;gt;=&amp;lt;wert&amp;gt;&amp;lt;/tt&amp;gt;: Definiert Makro &amp;lt;tt&amp;gt;&amp;lt;name&amp;gt;&amp;lt;/tt&amp;gt; zu &amp;lt;tt&amp;gt;&amp;lt;wert&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
; &amp;lt;tt&amp;gt;-U&amp;lt;name&amp;gt;&amp;lt;/tt&amp;gt;: Undefiniert Makro &amp;lt;tt&amp;gt;&amp;lt;name&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
; &amp;lt;tt&amp;gt;-save-temps&amp;lt;/tt&amp;gt;: Temporäre Dateien (&amp;lt;tt&amp;gt;*.i&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;*.s&amp;lt;/tt&amp;gt;) werden nicht gelöscht. Teilweise fehlerhaft zusammen mit &amp;lt;tt&amp;gt;-c&amp;lt;/tt&amp;gt;&lt;br /&gt;
; &amp;lt;tt&amp;gt;-Wa,&amp;lt;options&amp;gt;&amp;lt;/tt&amp;gt;: übergibt Komma-getrennte Liste &amp;lt;tt&amp;gt;&amp;lt;options&amp;gt;&amp;lt;/tt&amp;gt; an den Assembler (&amp;lt;tt&amp;gt;avr-as&amp;lt;/tt&amp;gt;)&lt;br /&gt;
:;&amp;lt;tt&amp;gt;-Wa,-a=&amp;lt;filename&amp;gt;&amp;lt;/tt&amp;gt;: Assembler erzeugt ein Listing mit Name &amp;lt;tt&amp;gt;&amp;lt;filename&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
; &amp;lt;tt&amp;gt;-Wp,&amp;lt;options&amp;gt;&amp;lt;/tt&amp;gt;:  übergibt Komma-getrennte Liste &amp;lt;tt&amp;gt;&amp;lt;options&amp;gt;&amp;lt;/tt&amp;gt; an den Preprozessor&lt;br /&gt;
; &amp;lt;tt&amp;gt;-Wl,&amp;lt;options&amp;gt;&amp;lt;/tt&amp;gt;:  übergibt Komma-getrennte Liste &amp;lt;tt&amp;gt;&amp;lt;options&amp;gt;&amp;lt;/tt&amp;gt; an den Linker (&amp;lt;tt&amp;gt;avr-ld&amp;lt;/tt&amp;gt;)&lt;br /&gt;
:;&amp;lt;tt&amp;gt;-Wl,-Map=&amp;lt;filename&amp;gt;&amp;lt;/tt&amp;gt;: Linker erzeugt ein Map-File mit Name &amp;lt;tt&amp;gt;&amp;lt;filename&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
:;&amp;lt;tt&amp;gt;-Wl,--oformat=&amp;lt;format&amp;gt;&amp;lt;/tt&amp;gt;: Linker erzeugt Ausgabe im Format &amp;lt;tt&amp;gt;&amp;lt;format&amp;gt;&amp;lt;/tt&amp;gt;, z.b. &amp;lt;tt&amp;gt;ihex&amp;lt;/tt&amp;gt; für Intel-HEX-File&lt;br /&gt;
:;&amp;lt;tt&amp;gt;-Wl,--section-start=&amp;lt;section&amp;gt;=&amp;lt;address&amp;gt;&amp;lt;/tt&amp;gt;: Linker legt die [[avr-gcc/Interna#Sections|Section]] &amp;lt;tt&amp;gt;&amp;lt;section&amp;gt;&amp;lt;/tt&amp;gt; ab Adresse &amp;lt;tt&amp;gt;&amp;lt;address&amp;gt;&amp;lt;/tt&amp;gt;, z.B: &amp;lt;tt&amp;gt;.eeprom=0x810001&amp;lt;/tt&amp;gt;&lt;br /&gt;
; &amp;lt;tt&amp;gt;-Wall&amp;lt;/tt&amp;gt;: gibt mehr Warnungen, aber immer noch nicht alle&lt;br /&gt;
; &amp;lt;tt&amp;gt;-pedantic&amp;lt;/tt&amp;gt;: geht besonders pedantisch mit Code um&lt;br /&gt;
; &amp;lt;tt&amp;gt;-std=c89&amp;lt;br/&amp;gt;-ansi&amp;lt;/tt&amp;gt;: bricht mit einer Fehlermeldung ab, wenn kein ANSI-C (ISO C89) verwendet wurde&lt;br /&gt;
; &amp;lt;tt&amp;gt;-std=c99&amp;lt;/tt&amp;gt;: bricht mit einer Fehlermeldung ab, wenn kein ISO C99 verwendet wurde&lt;br /&gt;
; &amp;lt;tt&amp;gt;-ffreestanding&amp;lt;/tt&amp;gt;: Das erzeugte Programm läuft nicht in einer Umgebung wie einer Shell. Der Prototyp von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; ist&lt;br /&gt;
:&amp;lt;pre&amp;gt;void main (void);&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Maschinenspezifische Optionen für avr-gcc==&lt;br /&gt;
Maschinenabhängige Optionen beginnen immer mit '''-m'''&lt;br /&gt;
;-mmcu=xxx: Festlegen des Targets (Zielsystem/Controller), für das Code generiert werden soll. Je nach Target muss avr-gcc unterschiedliche Instruktionen verwenden und andere Startup-Dateien (&amp;lt;tt&amp;gt;crtxxx.o&amp;lt;/tt&amp;gt;) einbinden. avr-gcc setzt spezielle Defines, um auch in der Quelle zwischen den Targets unterscheiden zu können, falls das notwendig sein sollte: &lt;br /&gt;
:{| border=&amp;quot;0&amp;quot; cellpadding=&amp;quot;0&amp;quot; cellspacing=&amp;quot;0&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#ifdef __AVR_AT90S2313__&lt;br /&gt;
/* Code fuer AT90S2313 */&lt;br /&gt;
#elif defined (__AVR_ATmega8__) || defined (__AVR_ATmega32__)&lt;br /&gt;
/* Code fuer Mega8 und Mega32 */ &lt;br /&gt;
#else&lt;br /&gt;
#error Das ist noch nicht implementiert für diesen Controller!&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Zwar gibt es für alle AVR-Derivate die &amp;lt;tt&amp;gt;avr/io.h&amp;lt;/tt&amp;gt;, aber die AVR-Familien unterscheiden sich in ihrer Hardware; z.B. darin, wie I/O-Register heissen oder wie Hardware zu initialisieren ist. Diese Abhängigkeit kann man in unterschiedlichen Codestücken aufteilen und wie oben gezeigt bedingt übersetzen. Dadurch hat man Funktionalitäten wie &amp;lt;tt&amp;gt;uart_init&amp;lt;/tt&amp;gt; auf unterschiedlichen Controllern und wahrt den Überblick, weil nicht für jede Controller-Familie eine extra Datei notwendig ist.&lt;br /&gt;
{| &lt;br /&gt;
|- valign=&amp;quot;top&amp;quot; &lt;br /&gt;
| &lt;br /&gt;
:{| {{Blauetabelle}}&lt;br /&gt;
|+ '''AVR classic, &amp;amp;lt;= 8 kByte'''&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|mcu || Builtin define&lt;br /&gt;
 |- &lt;br /&gt;
 |avr2 ||&amp;lt;tt&amp;gt;__AVR_ARCH__=2&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |[[AT90S2313|at90s2313]]  ||&amp;lt;tt&amp;gt;__AVR_AT90S2313__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90s2323 ||&amp;lt;tt&amp;gt;__AVR_AT90S2323__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90s2333 ||&amp;lt;tt&amp;gt;__AVR_AT90S2333__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90s2343 ||&amp;lt;tt&amp;gt;__AVR_AT90S2343__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |attiny22 ||&amp;lt;tt&amp;gt;__AVR_ATtiny22__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |attiny26 ||&amp;lt;tt&amp;gt;__AVR_ATtiny26__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90s4414 ||&amp;lt;tt&amp;gt;__AVR_AT90S4414__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90s4433 ||&amp;lt;tt&amp;gt;__AVR_AT90S4433__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90s4434 ||&amp;lt;tt&amp;gt;__AVR_AT90S4434__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90s8515 ||&amp;lt;tt&amp;gt;__AVR_AT90S8515__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90c8534 ||&amp;lt;tt&amp;gt;__AVR_AT90C8534__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90s8535 ||&amp;lt;tt&amp;gt;__AVR_AT90S8535__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at86rf401 ||&amp;lt;tt&amp;gt;__AVR_AT86RF401__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
 |  &amp;lt;!-----------------------------------------------------------&amp;gt;&lt;br /&gt;
:{| {{Blauetabelle}}&lt;br /&gt;
|+ '''AVR classic, &amp;amp;gt; 8 kByte'''&lt;br /&gt;
|- bgcolor=&amp;quot;#ccccff&amp;quot;&lt;br /&gt;
! |mcu ||Builtin define&lt;br /&gt;
 |- &lt;br /&gt;
 |avr3 ||&amp;lt;tt&amp;gt;__AVR_ARCH__=3&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |atmega103 ||&amp;lt;tt&amp;gt;__AVR_ATmega103__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |atmega603 ||&amp;lt;tt&amp;gt;__AVR_ATmega603__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at43usb320 ||&amp;lt;tt&amp;gt;__AVR_AT43USB320__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at43usb355 ||&amp;lt;tt&amp;gt;__AVR_AT43USB355__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at76c711 ||&amp;lt;tt&amp;gt;__AVR_AT76C711__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&amp;lt;!-----------------------------------------------------------&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| &lt;br /&gt;
 |- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
 |&lt;br /&gt;
:{| {{Blauetabelle}}&lt;br /&gt;
|+ '''AVR enhanced, &amp;amp;lt;= 8 kByte'''&lt;br /&gt;
|- bgcolor=&amp;quot;#ccccff&amp;quot;&lt;br /&gt;
!|mcu || Builtin define&lt;br /&gt;
 |- &lt;br /&gt;
 |avr4 ||&amp;lt;tt&amp;gt;__AVR_ARCH__=4&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |[[Atmel Controller Mega8|atmega8]] ||&amp;lt;tt&amp;gt;__AVR_ATmega8__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |atmega8515 ||&amp;lt;tt&amp;gt;__AVR_ATmega8515__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |atmega8535 ||&amp;lt;tt&amp;gt;__AVR_ATmega8535__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
 |&amp;lt;!-----------------------------------------------------------&amp;gt;&lt;br /&gt;
:{| {{Blauetabelle}}&lt;br /&gt;
|+ '''AVR enhanced, &amp;amp;gt; 8 kByte'''&lt;br /&gt;
|- bgcolor=&amp;quot;#ccccff&amp;quot;&lt;br /&gt;
!|mcu ||Builtin define&lt;br /&gt;
 |- &lt;br /&gt;
 |avr5 ||&amp;lt;tt&amp;gt;__AVR_ARCH__=5&amp;lt;/tt&amp;gt; &lt;br /&gt;
 |-&lt;br /&gt;
 |[[Atmel Controller Mega16 und Mega32|atmega16]] ||&amp;lt;tt&amp;gt;__AVR_ATmega16__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |atmega161 ||&amp;lt;tt&amp;gt;__AVR_ATmega161__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |atmega162 ||&amp;lt;tt&amp;gt;__AVR_ATmega162__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |atmega163 ||&amp;lt;tt&amp;gt;__AVR_ATmega163__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |atmega169 ||&amp;lt;tt&amp;gt;__AVR_ATmega169__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |[[Atmel Controller Mega16 und Mega32|atmega32]] ||&amp;lt;tt&amp;gt;__AVR_ATmega32__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |atmega323 ||&amp;lt;tt&amp;gt;__AVR_ATmega323__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |[[ATMega64|atmega64]] ||&amp;lt;tt&amp;gt;__AVR_ATmega64__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |[[Atmel Controller Mega128|atmega128]] ||&amp;lt;tt&amp;gt;__AVR_ATmega128__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at94k ||&amp;lt;tt&amp;gt;__AVR_AT94K__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&amp;lt;!-----------------------------------------------------------&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:{| {{Blauetabelle}}&lt;br /&gt;
|+ '''AVR, nur Assembler'''&lt;br /&gt;
|- bgcolor=&amp;quot;#ccccff&amp;quot;&lt;br /&gt;
! |mcu ||Builtin define&lt;br /&gt;
 |- &lt;br /&gt;
 |avr1 ||&amp;lt;tt&amp;gt;__AVR_ARCH__=1&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |at90s1200 ||&amp;lt;tt&amp;gt;__AVR_AT90S1200__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |attiny11 ||&amp;lt;tt&amp;gt;__AVR_ATtiny11__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |attiny12 ||&amp;lt;tt&amp;gt;__AVR_ATtiny12__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |attiny15 ||&amp;lt;tt&amp;gt;__AVR_ATtiny15__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |attiny28 ||&amp;lt;tt&amp;gt;__AVR_ATtiny28__&amp;lt;/tt&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
; -minit-stack=xxx: Festlegen der Stack-Adresse&lt;br /&gt;
; -mint8: Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ist nur 8 Bit breit, anstatt 16 Bit. Datentypen mit 32 Bit wie  &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; sind nicht verfügbar&lt;br /&gt;
; -mno-interrupts: Ändert den Stackpointer ohne Interrupts zu deaktivieren&lt;br /&gt;
; -mcall-prologues: Funktions-Prolog und -Epilog werden als Unterroutinen umgesetzt, um die Codegröße zu verkleinern&lt;br /&gt;
; -mtiny-stack: Nur die unteren 8 Bit des Stackpointers werden verändert&lt;br /&gt;
; -mno-tablejump: Für ein &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;-Statement werden keine Sprungtabellen angelegt&lt;br /&gt;
; -mshort-calls: Verwendet &amp;lt;tt&amp;gt;rjmp&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;rcall&amp;lt;/tt&amp;gt; (begrenzte Sprungweite) auf Devices mit mehr als 8 kByte Flash&lt;br /&gt;
; -msize: Ausgabe der Instruktonslängen im asm-File&lt;br /&gt;
; -mdeb: (undokumentiert) Ausgabe von Debug-Informationen für GCC-Entwickler&lt;br /&gt;
; -morder1: (undokumentiert) andere Register-Allokierung&lt;br /&gt;
; -morder2: (undokumentiert) andere Register-Allokierung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=C++=&lt;br /&gt;
&lt;br /&gt;
:''&amp;quot;C++ is a complex language and an evolving one, and its standard definition (the ISO C++ standard) was only recently completed. As a result, your C++ compiler may occasionally surprise you, even when its behavior is correct.&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
Zudem sollte der Einsatz von C++ aus Effizienzgründen sehr kritisch betrachtet werden:&lt;br /&gt;
:''&amp;quot;When programming C++ in space- and runtime-sensitive environments like microcontrollers, extra care should be taken to avoid unwanted side effects of the C++ calling conventions like implied copy constructors that could be called upon function invocation etc. These things could easily add up into a considerable amount of time and program memory wasted. Thus, casual inspection of the generated assembler code (using the &amp;lt;tt&amp;gt;-S&amp;lt;/tt&amp;gt; compiler option) seems to be warranted.&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
Weiterhin unterliegt der Einsatz von C++ je nach Compiler/Lib-Version bestimmten Einschränkungen:&lt;br /&gt;
*Einer kompletten C++ Implementierung fehlt die Unterstützung durch die &amp;lt;tt&amp;gt;libstdc++&amp;lt;/tt&amp;gt;, dadurch fehlen Standardfunktionen, -Klassen und -Templates&lt;br /&gt;
* Die Operatoren &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;delete&amp;lt;/tt&amp;gt; sind nicht implementiert, ihre Verwendung führt zu unauflösbaren externen Referenzen (Linker-Fehler)&lt;br /&gt;
*Nicht alle Header sind C++-sicher und müssen in &amp;lt;tt&amp;gt;extern &amp;quot;C&amp;quot; {...}&amp;lt;/tt&amp;gt; eingeschlossen werden.&lt;br /&gt;
*Exceptions werden nicht unterstützt und müssen via &amp;lt;tt&amp;gt;-fno-exceptions&amp;lt;/tt&amp;gt; abgeschaltet werden, oder der Linker beschwert sich über eine unauflösbare externe Referenz zu &amp;lt;tt&amp;gt;__gxx_personality_sj0&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Als Treiber verwendet man wie immer avr-gcc. Standard-Endungen für C++ sind &amp;lt;tt&amp;gt;.c++&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;.cpp&amp;lt;/tt&amp;gt;. Bei anderen Endungen teilt man mit &amp;lt;tt&amp;gt;-x c++&amp;lt;/tt&amp;gt; mit, daß es sich um C++ Dateien handelt, oder ruft &amp;lt;tt&amp;gt;avr-c++&amp;lt;/tt&amp;gt; direkt auf.&lt;br /&gt;
&lt;br /&gt;
Interrupt-Service-Routinen (ISRs) sind C-Funktionen und werden definiert wie gehabt. Siehe auch [[#Interrupts|Interrupts]].&lt;br /&gt;
 #include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #if defined (__cplusplus)&lt;br /&gt;
 extern &amp;quot;C&amp;quot; {&lt;br /&gt;
 #endif {{comment|__cplusplus}}&lt;br /&gt;
 &lt;br /&gt;
 SIGNAL (SIG_NAME)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|machwas}}&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 INTERRUPT (SIG_NAME)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|mach was}}&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 #if defined (__cplusplus)&lt;br /&gt;
 }&lt;br /&gt;
 #endif {{comment|__cplusplus}}&lt;br /&gt;
&amp;lt;tt&amp;gt;__cplusplus&amp;lt;/tt&amp;gt; ist ein Standard [[avr-gcc/Interna#Builtin Defines|GCC-Builtin-Define]].&lt;br /&gt;
&lt;br /&gt;
Globale Konstruktoren werden in [[avr-gcc/Interna#Sections|Section]] &amp;lt;tt&amp;gt;.init6&amp;lt;/tt&amp;gt; ausgeführt, die Destruktoren in &amp;lt;tt&amp;gt;.fini6&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=Code-Beispiele=&lt;br /&gt;
Dieser Abschnitt enthält Code-Schnippsel für avr-gcc. Es werden Besonderheiten besprochen, die für avr-gcc zu beachten sind. &lt;br /&gt;
&lt;br /&gt;
Dieser Abschnitt ist ''kein'' [[C-Tutorial|Tutorial zur C-Programmierung]] und ''keine'' Einführung in die Programmiersprache C im allgemeinen. Dafür sei auf einschlägige Tutorials/Bücher verwiesen.&lt;br /&gt;
&lt;br /&gt;
==Zugriff auf Special Function Registers (SFRs)==&lt;br /&gt;
&lt;br /&gt;
===Zugiff auf Bytes und Worte===&lt;br /&gt;
For dem Zugriff auf die SFRs gibt es Defines über den Include&lt;br /&gt;
 #include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
Abhängig vom eingestellten Controller werden denn Defines eingebunden, über die auf SFRs wie auf normale Variablen zugegriffen werden kann. Die Namen der Defines sind i.d.R. die gleichen wie im AVR-Manual, also z.b. &amp;lt;tt&amp;gt;SREG&amp;lt;/tt&amp;gt; für das Prozessorstatus-Register SREG:&lt;br /&gt;
 #include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
   {{ccomment|SREG lesen}}&lt;br /&gt;
   uint8_t sreg = SREG;&lt;br /&gt;
   ...&lt;br /&gt;
   {{ccomment|SREG schreiben}}&lt;br /&gt;
   SREG = sreg;&lt;br /&gt;
&amp;lt;!--  &lt;br /&gt;
Auf SFRs wird generell über deren Adresse zugegriffen:&lt;br /&gt;
 {{ccomment|Liest den Inhalt von SREG an Adresse 0x5f}}&lt;br /&gt;
 unsigned char sreg = *((unsigned char volatile*) 0x5f);&lt;br /&gt;
Das bedeutet in etwa: &amp;quot;Lies ein flüchtiges (&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;) Byte (&amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt;) von Adresse &amp;lt;tt&amp;gt;0x5f&amp;lt;/tt&amp;gt;&amp;quot;. Der Speicherinhalt von SFRs ist flüchtig, denn er kann sich ändern, ohne daß avr-gcc dies mitbekommt. Daher muss bei jedem C-Zugriff auf ein SFR dieses wirklich gelesen/geschrieben werden, was der Qualifier &amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt; sicherstellt. Ansonst geht der Compiler u.U. davon aus, daß der Inhalt bekannt ist und verwendet einen alten, in einem GPR befindlichen Wert.&lt;br /&gt;
&lt;br /&gt;
Um lesbaren, weniger fehleranfälligen und unter AVRs halbwegs portierbaren Code zu erhalten, gibt es Makrodefinitionen im Controller-spezifischen Header &amp;lt;tt&amp;gt;ioxxxx.h&amp;lt;/tt&amp;gt;, der neben anderen Dingen mit &amp;lt;tt&amp;gt;avr/io.h&amp;lt;/tt&amp;gt; includet wird:&lt;br /&gt;
Die Bezeichner der SFRs sind die gleichen wie im Manual.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Für einen Überblick über die eingebundenen Defines und kann ein Blick in den Controller-spezifischen Header hilfreich sein. Dieser befindet sich in&lt;br /&gt;
:&amp;lt;tt&amp;gt; &amp;amp;lt;GCC_HOME&amp;amp;gt;/avr/include/avr/io****.h&amp;lt;/tt&amp;gt;&lt;br /&gt;
z.B. &amp;lt;tt&amp;gt;iom32.h&amp;lt;/tt&amp;gt; für einen [[ATmega32]].&lt;br /&gt;
&lt;br /&gt;
Dieser Zugriff geht auch für 16-Bit Register wie &amp;lt;tt&amp;gt;TCNT1&amp;lt;/tt&amp;gt;, für die eine bestimmte Reihenfolge für den Zugriff auf Low- und High-Teil eingehalten werden muss: avr-gcc generiert die Zugriffe in der richtigen Reihenfolge.&lt;br /&gt;
  uint16_t tcnt1 = TCNT1;&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Zu beachten ist, daß dieser Zugriff nicht atomar erfolgt. Das Lesen/Schreiben mehrbytiger Werte muss vom Compiler in mehrere Byte-Zugriffe zerlegt werden. Zwischen diesen Zugriffen kann ein [[Interrupt]] auftreten, wenn Interrupts aktiviert sind. Je nach Programm und welche Aufgaben eine [[ISR]] erledigt, kann dies zu Fehlfunktion führen. In dem Fall müssen diese Code-Stücke atomar gemacht werden, damit sie nicht durch einen [[IRQ]] unterbrochen werden können!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Zugriff auf einzelne Bits===&lt;br /&gt;
Zugriff auf Bits geht wie gewohnt mit den Bitoperationen &lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; (and),&lt;br /&gt;
&amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt; (or),&lt;br /&gt;
&amp;lt;tt&amp;gt;^&amp;lt;/tt&amp;gt; (xor) und&lt;br /&gt;
&amp;lt;tt&amp;gt;~&amp;lt;/tt&amp;gt; (not)&lt;br /&gt;
&lt;br /&gt;
Wieder gibt es Defines in den AVR-Headern, mit denen man Masken für den Zugriff erhalten kann, etwa:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* GIMSK / GICR */&lt;br /&gt;
#define INT1    7&lt;br /&gt;
#define INT0    6&lt;br /&gt;
#define IVSEL   1&lt;br /&gt;
#define IVCE    0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Masken ergeben sich durch Schieben von &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; an die richtige Position:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Ports B_0 und B_1 als Ausgang&lt;br /&gt;
DDRB |= (1&amp;amp;lt;&amp;amp;lt;PB0) | (1&amp;amp;lt;&amp;amp;lt;PB1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
erzeugt&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
87 b3           in      r24, 0x17&lt;br /&gt;
83 60           ori     r24, 0x03&lt;br /&gt;
87 bb           out     0x17, r24&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Etwas anders sieht der Code aus, wenn die Bits einzeln gesetzt werden und das Register im bitadressierbaren Bereich liegt (SRAM &amp;lt;tt&amp;gt;0x20&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;0x3f&amp;lt;/tt&amp;gt; resp. I/O &amp;lt;tt&amp;gt;0x0&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;0x1f&amp;lt;/tt&amp;gt;):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Ports B_0 und B_1 als Ausgang&lt;br /&gt;
DDRB |= (1&amp;amp;lt;&amp;amp;lt;PB0);&lt;br /&gt;
DDRB |= (1&amp;amp;lt;&amp;amp;lt;PB1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
erzeugt&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
b8 9a           sbi     0x17, 0&lt;br /&gt;
b9 9a           sbi     0x17, 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um Bits zu löschen, erzeugt man eine Maske, die an der betreffenden Stelle eine &amp;amp;nbsp;0 hat:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Ports B_2 als Eingang&lt;br /&gt;
DDRB &amp;amp;= ~(1&amp;amp;lt;&amp;amp;lt;PB2);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen| &lt;br /&gt;
Auch hier ist zu beachten, daß es Probleme geben kann, wenn nicht atomarer Code erzeugt wird, weil der AVR-Befehlssatz nicht mehr hergibt:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// toggle PORT B_0: wechseln 0 &amp;amp;lt;--&amp;amp;gt; 1 &lt;br /&gt;
PORTB ^= (1&amp;amp;lt;&amp;amp;lt;PB0);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
ergibt&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
88 b3           in      r24, 0x18&lt;br /&gt;
; Wenn hier ein Interrupt auftritt, in dessen ISR PORTB verändert wird,&lt;br /&gt;
; dann wird die Änderung durch die letzte Instruktion wieder überschrieben!&lt;br /&gt;
91 e0           ldi     r25, 0x01&lt;br /&gt;
; dito&lt;br /&gt;
89 27           eor     r24, r25&lt;br /&gt;
; dito&lt;br /&gt;
88 bb           out     0x18, r24&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
}} &amp;lt;!-- /FarbigerRahmen --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auch das Lesen einzelner Port-Pins geht über das Maskieren von SFRs:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DDRB &amp;amp;= ~(1 &amp;lt;&amp;lt; PB2);    // PortB.2 als INPUT &lt;br /&gt;
&lt;br /&gt;
if (PINB &amp;amp; (1 &amp;lt;&amp;lt; PB2))&lt;br /&gt;
   // PortB.2 ist HIGH&lt;br /&gt;
else&lt;br /&gt;
   // PortB.2 ist LOW&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if (!(PINB &amp;amp; (1 &amp;lt;&amp;lt; PB2)))&lt;br /&gt;
   // PortB.2 ist LOW&lt;br /&gt;
else&lt;br /&gt;
   // PortB.2 ist HIGH&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Interrupts==&lt;br /&gt;
&lt;br /&gt;
Um zu kennzeichnen, daß es sich bei einer Funktion um eine Interrupt Sevice Routine (ISR) handelt, gibt es spezielle Attribute. Diese brauchen nicht explizit hingeschrieben zu werden, ebensowenig wie die genaue Nummer des Interrupt Requests (IRQ). Dafür gibt es Includes und die folgenden Makros.&lt;br /&gt;
&lt;br /&gt;
Bitte beachte auch die Hinweise zu den [[#Inkompatibilität|Inkompatibilität]]en von avr-gcc!&lt;br /&gt;
 #include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Eine nichtunterbrachbare Interrupt-Service-Routine}}&lt;br /&gt;
 SIGNAL (SIG_OUTPUT_COMPARE1A)&lt;br /&gt;
 {&lt;br /&gt;
    {{ccomment|ISR-Code}}&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Eine unterbrachbare Interrupt-Service-Routine}}&lt;br /&gt;
 INTERRUPT (SIG_OUTPUT_COMPARE1B)&lt;br /&gt;
 {&lt;br /&gt;
    {{ccomment|ISR-Code}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Dadurch wird die Funktion mit dem richtigen Prolog/Epilog erzeugt, und es wird ein Eintrag in die Interrupt-Vektortabelle gemacht &amp;amp;#150; bei obigem Beispiel also zwei Einträge.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Die Schreibweise des Signal-Names muss genau die sein wie im Header, das schliesst auch Leerzeichen ein! Nicht alle GCC-Versionen bringen Fehler/Warnung, wenn die Schreibweise nicht stimmt.&lt;br /&gt;
 SIGNAL (SIG_OUTPUT_COMPARE1A )  // !!! Macht NICHT das, was man will (Blank am Ende)!!!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;SIGNAL&amp;lt;/tt&amp;gt;: Mit Ausführung einer ISR deaktiviert die AVR-Hardware die Interrupts, so daß die ISR nicht durch andere Interrupt-Anforderungen unterbrochen wird. Beim Verlassen der ISR werden Interrupts wieder automatisch aktiviert. Tritt während der ISR ein IRQ auf, wird diese erst nach Beenden des ISR-Codes ausgeführt. Der Interrupt geht also nicht verloren. Zwischen zwei ISRs wird zusätzlich mindestens ein Befehl des normalen Programm-Codes abgearbeitet.&lt;br /&gt;
;&amp;lt;tt&amp;gt;INTERRUPT&amp;lt;/tt&amp;gt;: Früh im ISR-Prolog werden mit &amp;lt;tt&amp;gt;sei&amp;lt;/tt&amp;gt; die von der AVR-Hardware temporär deaktivierten Interrupts reaktiviert. Dadurch kann die ISR von einer IRQ unterbrochen werden. Das bietet die Möglichkeit, so etwas wie Interrupt-Priorisierung nachzubilden, was AVRs selbst nicht können. Weiterhin kann man schneller auf bestimmte Ereignisse reagieren. Tritt während der ISR ein anderer IRQ auf, der schnell bedient werden muss, kann sofort der dringende ISR-Code ausgeführt werden. Ansonsten (Verwendung von &amp;lt;tt&amp;gt;SIGNAL&amp;lt;/tt&amp;gt;) würde der Code erst ausgeführt werden, nachdem die aktuelle ISR beendet ist.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|Dauert die ISR zu lange und wird sie nochmals von ihrem eigenen IRQ unterbrochen, stürzt man ab.}} &lt;br /&gt;
&lt;br /&gt;
Nachschlagen kann man den Namen in&lt;br /&gt;
:&amp;lt;tt&amp;gt;&amp;amp;lt;GCC_HOME&amp;amp;gt;/avr/include/avr/ioxxxx.h&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Interrupts aktivieren===&lt;br /&gt;
&lt;br /&gt;
Damit eine ISR überhaupt zur Ausführung kommt, müssen drei Bedingungen erfüllt sein&lt;br /&gt;
* Interrupts müssen global aktiviert sein&lt;br /&gt;
* Der entsprechen IRQ muss aktiviert worden sein&lt;br /&gt;
* Das zum IRQ gehörende Ereignis muss eintreten&lt;br /&gt;
 #include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
    ...&lt;br /&gt;
    {{ccomment|enable OutputCompareA Interrupt für Timer1}}&lt;br /&gt;
    TIMSK |= (1 &amp;lt;&amp;lt; OCIE1A);&lt;br /&gt;
 &lt;br /&gt;
    {{ccomment|disable OutputCompareA Interrupt für Timer1}}&lt;br /&gt;
    TIMSK &amp;amp;= ~(1 &amp;lt;&amp;lt; OCIE1A);&lt;br /&gt;
 &lt;br /&gt;
    {{ccomment|Interrupts aktivieren}}&lt;br /&gt;
    sei();&lt;br /&gt;
 &lt;br /&gt;
    {{ccomment|Interrupts abschalten}}&lt;br /&gt;
    cli();&lt;br /&gt;
Sperrt man eine Code-Sequenz durch Einschachteln in ein &amp;lt;tt&amp;gt;cli&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;sei&amp;lt;/tt&amp;gt; Paar (man macht das Codestück &amp;quot;atomar&amp;quot;, also ununterbrechbar), gehen währenddessen keine Interrupt-Anforderungen verloren. Die entsprechenden IRQ-Flags bleiben gesetzt, und nach dem &amp;lt;tt&amp;gt;sei&amp;lt;/tt&amp;gt; werden die IRQs in der Reihenfolge ihrer Prioritäten abgearbeitet. Ausnahme ist, wenn in einem atomaren Block der selbe IRQ mehrfach auftritt. Der ISR-Code wird dann trotzdem nur einmal ausgeführt.&lt;br /&gt;
&lt;br /&gt;
===default Interrupt===&lt;br /&gt;
&lt;br /&gt;
Für nicht implementierte Interrupts macht avr-gcc in die Vektortabelle einen Eintrag,&lt;br /&gt;
der zu &amp;lt;tt&amp;gt;__bad_interrupt&amp;lt;/tt&amp;gt; (definiert im Startup-Code &amp;lt;tt&amp;gt;crt*.o&amp;lt;/tt&amp;gt;) springt&lt;br /&gt;
und von dort aus weiter zu Adresse&amp;amp;nbsp;0. &lt;br /&gt;
Dadurch läuft der AVR wieder von neuem los, wenn ein Interrupt auftritt, &lt;br /&gt;
zu dem man keine ISR definiert hat &lt;br /&gt;
&amp;amp;#150; allerdings ohne die Hardware zurückzusetzen wie bei einem echten Reset.&lt;br /&gt;
&lt;br /&gt;
Möchte man diesen Fall abfangen, dann geht das über eine globale Funktion &lt;br /&gt;
namens &amp;lt;tt&amp;gt;__vector_default&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SIGNAL (__vector_default)&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Damit wird von &amp;lt;tt&amp;gt;__bad_interrupt&amp;lt;/tt&amp;gt; aus nicht nach Adresse&amp;amp;nbsp;0 gesprungen,&lt;br /&gt;
sondern weiter zu &amp;lt;tt&amp;gt;__vector_default&amp;lt;/tt&amp;gt;, welches durch &amp;lt;tt&amp;gt;SIGNAL&amp;lt;/tt&amp;gt; oder&lt;br /&gt;
&amp;lt;tt&amp;gt;INTERRUPT&amp;lt;/tt&amp;gt; den üblichen ISR-Prolog/Epilog bekommt.&lt;br /&gt;
&lt;br /&gt;
So kann man z.B. eine Meldung ausgeben, eine Warnlampe blinken, in einer Endlosschleife landen, oder über den [[Watchdog]] einen richtigen Hardware-Reset auslösen, siehe auch Abschnitt &amp;quot;[[#Reset auslösen|Reset auslösen]]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===ISR mit eigenem Prolog/Epilog===&lt;br /&gt;
&lt;br /&gt;
Wenn man in einer ISR komplett eigenes Zeug machen will, &lt;br /&gt;
dann definiert man eine nackte Funktion.&lt;br /&gt;
Mit &amp;lt;tt&amp;gt;naked&amp;lt;/tt&amp;gt; befreit man die Routine vom Standard-Prolog/Epilog.&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Dabei ist darauf zu achten, daß die ISR mit &amp;lt;tt&amp;gt;reti&amp;lt;/tt&amp;gt; (return from interrupt) &lt;br /&gt;
zurückkehrt und evtl. verwendete Register und den Status (&amp;lt;tt&amp;gt;SREG&amp;lt;/tt&amp;gt;) sichert.&lt;br /&gt;
}}&lt;br /&gt;
 #include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void __attribute__ ((naked)) &lt;br /&gt;
 SIG_OVERFLOW0 (void)&lt;br /&gt;
 {&lt;br /&gt;
    {{ccomment|Port B.6 &amp;amp;#61; 0}}&lt;br /&gt;
    {{ccomment|Diese Instruktion verändert nicht das SREG und kein anderes Register}}&lt;br /&gt;
    {{ccomment|so daß der eigentliche Code nur 1 Befehl lang ist}}&lt;br /&gt;
    __asm__ __volatile (&lt;br /&gt;
       &amp;quot;cbi %0, %1&amp;quot; &amp;quot;\n\t&amp;quot;&lt;br /&gt;
       &amp;quot;reti&amp;quot;&lt;br /&gt;
          : &lt;br /&gt;
          : &amp;quot;M&amp;quot; (_SFR_IO_ADDR (PORTB)), &amp;quot;i&amp;quot; (6)&lt;br /&gt;
    );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Siehe auch [[Inline-Assembler in avr-gcc]].&lt;br /&gt;
Die ISR sieht dann so aus:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
__vector_9:&lt;br /&gt;
   c6 98        cbi   0x18, 6&lt;br /&gt;
   18 95        reti&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wiederum kann man als Funktionsname &amp;lt;tt&amp;gt;__vector_default&amp;lt;/tt&amp;gt; nehmen,&lt;br /&gt;
um nicht-implementierte IRQs abzufangen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void __attribute__ ((naked)) &lt;br /&gt;
__vector_default (void)&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==SRAM, Flash, EEPROM: Datenablage am Beispiel Strings==&lt;br /&gt;
Die Programmiersprache C kennt selber keine Strings; das einzige, was C bekannt ist, ist der Datentyp &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, der ein einzelnes Zeichen repräsentiert. &lt;br /&gt;
===Darstellung in C===&lt;br /&gt;
Ein String im Sinne von C ist ein Array von Charactern bzw. ein Zeiger auf den Anfang des Arrays. Die einzelnen Zeichen folgen im Speicher direkt aufeinander und werden in aufsteigenden Adressen gespeichert. Am String-Ende folgt als Abschluss der Character &amp;lt;tt&amp;gt;'\0'&amp;lt;/tt&amp;gt;, um das Ende zu kennzeichnen. Dies ist besonders bei der Berechnung des Speicherplatzes für Strings zu berücksichtigen, denn für die 0 muss auch Platz reserviert werden.&lt;br /&gt;
&lt;br /&gt;
===Bestimmen der Stringlänge===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 /* Bestimmt die Laenge des Strings ohne die abschliessende '\0' zu zaehlen */&lt;br /&gt;
 unsigned int strlength (const char *str)&lt;br /&gt;
 {&lt;br /&gt;
   unsigned int len = 0;&lt;br /&gt;
   &lt;br /&gt;
   while (*str++)&lt;br /&gt;
      len++;&lt;br /&gt;
   &lt;br /&gt;
   return len;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Stringlänge kann auch mit der Standard-Funktion &amp;lt;tt&amp;gt;strlen&amp;lt;/tt&amp;gt; bestimmt werden, deren Prototyp sich in &amp;lt;tt&amp;gt;string.h&amp;lt;/tt&amp;gt; befindet:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 size_t strlen (const char*);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===String im Flash belassen===&lt;br /&gt;
Oftmals werden Strings nur zu Ausgabezwecken verwendet und nicht verändert. Verwendet man Sequenzen der Gestalt&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 char *str1 = &amp;quot;Hallo Welt!&amp;quot;;&lt;br /&gt;
 char str2[] = &amp;quot;Hallo Welt!&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
dann werden die Strings im SRAM abgelegt. Im Startup-Code werden die Strings vom Flash ins SRAM kopiert und belegen daher sowohl Platz im SRAM als auch im Flash. Wird ein String nicht verändert, braucht er nicht ins SRAM kopiert zu werden. Das spart Platz im knapp bemessenen SRAM. Allerdings muss anders auf den String zugegriffen werden, denn wegen der Harvard-Architektur des AVR-Kerns kann avr-gcc anhand der Adresse nicht unterscheiden, ob diese ins SRAM, ins Flash oder ins EEPROM zeigt.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 const prog_char str3[] = &amp;quot;Hallo Welt!&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
 unsigned int strlen_P (const prog_char *str)&lt;br /&gt;
 {&lt;br /&gt;
    unsigned int len = 0;&lt;br /&gt;
 &lt;br /&gt;
    while (1)&lt;br /&gt;
    {&lt;br /&gt;
       char c = (char) pgm_read_byte (str);&lt;br /&gt;
       if ('\0' == c)&lt;br /&gt;
          return len;&lt;br /&gt;
       len++;&lt;br /&gt;
       str++; &lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void foo()&lt;br /&gt;
 {&lt;br /&gt;
    unsigned int len;&lt;br /&gt;
    len = strlen_P (str3);&lt;br /&gt;
    len = strlen_P (PSTR(&amp;quot;String im Flash&amp;quot;));&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===String ins EEPROM legen===&lt;br /&gt;
Dies geht nach dem gleichen Muster, nach dem Strings ins Flash gelegt werden. Der Zugriff wird vergleichsweise langsam, denn der EEPROM ist langsamer als SRAM bzw. Flash.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #include &amp;lt;avr/eeprom.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 const char str4[] __attribute__ ((section(&amp;quot;.eeprom&amp;quot;))) = &amp;quot;Hallo Welt!&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
 unsigned int strlen_EE (const char *str)&lt;br /&gt;
 {&lt;br /&gt;
    unsigned int len = 0;&lt;br /&gt;
 &lt;br /&gt;
    while (1)&lt;br /&gt;
    {&lt;br /&gt;
       char c = (char) eeprom_read_byte (str);&lt;br /&gt;
       if ('\0' == c)&lt;br /&gt;
          return len;&lt;br /&gt;
       len++;&lt;br /&gt;
       str++; &lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reset auslösen==&lt;br /&gt;
Falls ein Reset per Software ausgelöst werden soll, dann geht das am besten über den [[Watchdog]].&lt;br /&gt;
Einfach nur an den RESET-Punkt an Adresse&amp;amp;nbsp;0 zu springen mit&lt;br /&gt;
 goto *((void**) 0);&lt;br /&gt;
initialisiert zwar den Controller von neuem, aber es macht keinen wirkliches RESET mit Zurücksetzen der Hardware und allen I/O-Registern. &lt;br /&gt;
&lt;br /&gt;
Durch den Watchdog kann man ein 'richtiges' RESET-Signal erzeugen lassen, so daß die AVR-Hardware genau so initialisiert ist, wie nach einem externen RESET. So kann man z.B. via [[UART]] ein RESET-Kommando schicken. Allerdings lässt sich der Watchdog nur minimal auf 15ms einstellen:&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;avr/wdt.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
 ...   &lt;br /&gt;
    cli();                     {{ccomment|Interrupts global abschalten}}&lt;br /&gt;
    wdt_enable (WDTO_15MS);    {{ccomment|Watchdog aufziehen auf 15ms}}&lt;br /&gt;
    while (1);                 {{ccomment|warten, bis er zubeisst...}}&lt;br /&gt;
&lt;br /&gt;
Welches Ereignis einen RESET ausgelöst hat, kann man im Register '''MCUCSR''' (''MCU Control and Status Register'') erfahren. Es gibt 4 mögliche RESET-Quellen:&lt;br /&gt;
* Power-On Reset&lt;br /&gt;
* External Reset&lt;br /&gt;
* Brown-Out Reset&lt;br /&gt;
* Watchdog Reset&lt;br /&gt;
&lt;br /&gt;
Soll der Inhalt von Variablen einen Reset überleben &amp;amp;ndash; eine Variable also nicht initialisiert werden &amp;amp;ndash; dann geht das so:&lt;br /&gt;
 #include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment| status informiert z.B. darüber, ob wir selber den Watchdog ausgelöst haben }}&lt;br /&gt;
 {{ccomment| oder nicht, oder andere Informationen }}&lt;br /&gt;
 unsigned char status __attribute__ ((section (&amp;quot;.noinit&amp;quot;)));&lt;br /&gt;
 &lt;br /&gt;
 void main (void)&lt;br /&gt;
 {&lt;br /&gt;
     {{ccomment|Wert von MCUSCR merken, möglichst früh im Programm }}&lt;br /&gt;
     unsigned char mcucsr = MCUCSR;&lt;br /&gt;
 &lt;br /&gt;
     {{ccomment|MCUCSR zurücksetzen }}&lt;br /&gt;
     MCUCSR = 0;&lt;br /&gt;
 &lt;br /&gt;
     {{ccomment|Watchdog-Reset }}&lt;br /&gt;
     if (mcuscr &amp;amp; (1 &amp;lt;&amp;lt; WDRF))&lt;br /&gt;
     {&lt;br /&gt;
         {{ccomment|status auswerten }}&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     {{ccomment|Power-On Reset: status auf definierten Wert setzen }}&lt;br /&gt;
     if (mcuscr &amp;amp; (1 &amp;lt;&amp;lt; PORF))&lt;br /&gt;
     {&lt;br /&gt;
         status = 0;&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     {{ccomment|status auswerten }}&lt;br /&gt;
     ...&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Die mit&lt;br /&gt;
 #include &amp;lt;...&amp;gt;&lt;br /&gt;
angegebenen Includes werden von avr-gcc in den &lt;br /&gt;
mit der Option '&amp;lt;tt&amp;gt;-I&amp;lt;/tt&amp;gt;' anegegenen Pfaden gesucht. &lt;br /&gt;
Dem Compiler bekannt sind die Pfade &lt;br /&gt;
 &amp;lt;GCC_HOME&amp;gt;/avr/include                           Standard               (stdio.h, ...)&lt;br /&gt;
 &amp;lt;GCC_HOME&amp;gt;/avr/include/avr                       AVR-spezifisch         (avr/io.h, ...)&lt;br /&gt;
 &amp;lt;GCC_HOME&amp;gt;/lib/gcc/avr/&amp;lt;GCC_VERSION&amp;gt;/include     Standard, compilerabh. (limits.h, ...)&lt;br /&gt;
&lt;br /&gt;
Gibt man z.B. an &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
dann wird automatisch in diesem Verzeichnis nach &amp;lt;tt&amp;gt;stdio.h&amp;lt;/tt&amp;gt; gesucht.&lt;br /&gt;
In den Verzeichnissen stehen Standard-Includes, die benötigt werden, wenn man libc-Funktionen &lt;br /&gt;
oder mathematische Funktionen etc. verwendet. &lt;br /&gt;
AVR-spezifische Dinge stehen im Unterverzeichnis &amp;lt;tt&amp;gt;avr&amp;lt;/tt&amp;gt;, etwa:&lt;br /&gt;
 #include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Als Pfad-Separator wird immer ein '''&amp;lt;tt&amp;gt;/&amp;lt;/tt&amp;gt;''' verwendet, auch auf Windows-Betriebssystemen! Also kein '''&amp;lt;tt&amp;gt;\&amp;lt;/tt&amp;gt;'''&amp;amp;nbsp;!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Standard==&lt;br /&gt;
&lt;br /&gt;
 ctype.h                   Zeichen-Umwandlungs-Makros und ctype Makros&lt;br /&gt;
 errno.h                   Symbolische Namen für Fehlercodes&lt;br /&gt;
 inttypes.h                Definiert [u]intN_t wenn man genau N [un]signed Bits &lt;br /&gt;
                           braucht, ISO C99.&lt;br /&gt;
 math.h                    Mathematische Funktionen: sin, cos, log, gamma, bessel, ...&lt;br /&gt;
 setjmp.h                  libc unterstützt setjmp() und longjmp(), um direkt in eine&lt;br /&gt;
                           andere (nicht-lokale) Funktion zu springen. &lt;br /&gt;
 stdio.h                   Standard I/O-Funktionen (printf, ...).&lt;br /&gt;
 stdlib.h                  Deklariert grundlegende ISO C-Makros und -Funktionen &lt;br /&gt;
                           sowie einige AVR-spezifische Erweiterungen&lt;br /&gt;
 string.h                  Stringoperationen auf NULL-terminierten Strings. (strlen, ...)&lt;br /&gt;
 stdarg.h                  Funktionen mit variabler Argumenanzahl&lt;br /&gt;
 limits.h                  Min- und Max-Werte von Skalaren (UCHAR_MAX, LONG_MIN, ...)&lt;br /&gt;
&lt;br /&gt;
==AVR-spezifisch==&lt;br /&gt;
&lt;br /&gt;
Die AVR-spezifischen Includes finden sich wie gesagt im Unterverzeichnis &amp;lt;tt&amp;gt;avr&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Die meisten dort befindlichen Header wird man nie direkt durch Angabe im C-File erhalten,&lt;br /&gt;
sondern durch Angabe von&lt;br /&gt;
 #include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
Dadurch werden z.B. genau die I/O-Header eingebunden, die zum AVR-Modell passen, also&lt;br /&gt;
*&amp;lt;tt&amp;gt;avr/iom8.h&amp;lt;/tt&amp;gt; für [[ATmega8]], &lt;br /&gt;
*&amp;lt;tt&amp;gt;avr/iotn2313.h&amp;lt;/tt&amp;gt; für [[ATtiny2313]], &lt;br /&gt;
*&amp;lt;tt&amp;gt;avr/io2313.h&amp;lt;/tt&amp;gt; für [[AT90S2313]], etc. &lt;br /&gt;
&lt;br /&gt;
Verantwortlich dafür ist der Schalter '&amp;lt;tt&amp;gt;-mmcu=xxx&amp;lt;/tt&amp;gt;'.&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Header nicht explizit angegeben werden müssen, &lt;br /&gt;
kann ein Blick dorthin hilfreich sein, um die Namen von [[SFR|SFRs]] &lt;br /&gt;
oder Signals nachzuschlagen. &lt;br /&gt;
Diese Header werden im folgenden nicht alle einzeln aufgelistet. &lt;br /&gt;
Ihre Namen sind immer &amp;lt;tt&amp;gt;avr/io*.h&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* für ATmega: &amp;lt;tt&amp;gt;avr/iom*.h&amp;lt;/tt&amp;gt; &lt;br /&gt;
* für ATtiny: &amp;lt;tt&amp;gt;avr/iotn*.h&amp;lt;/tt&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
avr/boot.h            Bootloader Support&lt;br /&gt;
avr/crc16.h           [*] Prüfsumme CRC16&lt;br /&gt;
avr/delay.h           [*] Verzögerungsschleifen für kurze, exakte Verzögerungen&lt;br /&gt;
avr/eeprom.h          EEPROM-Routinen&lt;br /&gt;
avr/ina90.h           Kompatibilität mit IAR-AVR-Compiler&lt;br /&gt;
avr/interrupt.h       sei(), cli(), ...&lt;br /&gt;
avr/io.h              --&amp;gt; inttypes.h, io*.h&lt;br /&gt;
avr/io*.h             SFRs, SIG_****, SPM_PAGESIZE, RAMEND, XRAMEND, E2END, FLASHEND&lt;br /&gt;
avr/parity.h          [*] Parität&lt;br /&gt;
avr/pgmspace.h        Zugriff aufs Flash: Byte lesen, PROGMEM, prog_char, prog_uint8_t, ...&lt;br /&gt;
avr/portpins.h        Makros für Port-Pins&lt;br /&gt;
avr/signal.h          [**] Makros SIGNAL() und INTERRUPT(), ...&lt;br /&gt;
avr/sleep.h           Power-Safe&lt;br /&gt;
avr/twi.h             [*] I2C&lt;br /&gt;
avr/wdt.h             Watchdog&lt;br /&gt;
 &lt;br /&gt;
util/crc16.h          Prüfsumme CRC16&lt;br /&gt;
util/delay.h          Verzögerungsschleifen für kurze, exakte Verzögerungen &lt;br /&gt;
util/parity.h         Parität&lt;br /&gt;
util/twi.h            I2C&lt;br /&gt;
 &lt;br /&gt;
[*]  bei neueren avr-gcc-Versionen in util&lt;br /&gt;
[**] entfällt bei neueren avr-gcc-Versionen. Stattdessen avr/interrupt.h verwenden&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Anwendungs-spezifisch==&lt;br /&gt;
Eigene Header, die nur innerhalb eigener Projekte gebraucht werden, includet man mit&lt;br /&gt;
 #include &amp;quot;...&amp;quot;&lt;br /&gt;
Auch hier darf man Unterverzeichnisse angeben oder ins übergeordnete Verzeichnis:&lt;br /&gt;
 #include &amp;quot;../../mein-zeug.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Optimierungen, Tipps &amp;amp; Tricks=&lt;br /&gt;
&lt;br /&gt;
Beim Programmieren in C möchte man sich möglichst wenig mit der Codeerzeugung selbst auseinandersetzen. Man verwendet ja gerade deshalb einen Compiler und programmiert nicht in Assembler, weil man sich nicht um Register-Belegungen o.ä. kümmern will, sondern nur um die zu lösende Aufgabe.&lt;br /&gt;
&lt;br /&gt;
GCC erzeugt zwar recht guten Code, aber er ist nicht perfekt. Gerade auf Systemen wie AVR mit nur sehr begrenzten Resourcen muss man daher dem Compiler hilfreich zur Seite stehen, wenn man noch dichteren/schnelleren Code erhalten möchte.&lt;br /&gt;
&lt;br /&gt;
:''&amp;quot;Unlike most other C compilers, GCC allows you to use -g with -O. The shortcuts taken by optimized code may occasionally produce surprising results: some variables you declared may not exist at all; flow of control may briefly move where you did not expect it; some statements may not be executed because they compute constant results or their values were already at hand; some statements may execute in different places because they were moved out of loops.''&lt;br /&gt;
&lt;br /&gt;
:''Nevertheless it proves possible to debug optimized output. This makes it reasonable to use the optimizer for programs that might have bugs.&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
Um das Ergebnis zu beurteilen, hilft ein Blick ins Listfile. &lt;br /&gt;
Siehe dazu auch die Abschnitte &lt;br /&gt;
&amp;quot;[[Hallo Welt für AVR (LED blinken)#Listfile erstellen|Listfile erstellen]]&amp;quot; &lt;br /&gt;
und&lt;br /&gt;
&amp;quot;[[Hallo Welt für AVR (LED blinken)#Die Größe ermitteln|Die Größe ermitteln]]&amp;quot; &lt;br /&gt;
im [[Hallo Welt für AVR (LED blinken)|Hallo Welt für AVR]].&lt;br /&gt;
&lt;br /&gt;
==Optimierungsgrad==&lt;br /&gt;
Als Optimierungsgrad erweist sich &amp;lt;tt&amp;gt;-Os&amp;lt;/tt&amp;gt; (Optimize for Size) als der beste, evtl. noch &amp;lt;tt&amp;gt;-O2&amp;lt;/tt&amp;gt;. Ohne Angabe eines Optimierungsgrades wird nicht optimiert, was gleichbedeutend mit der Option &amp;lt;tt&amp;gt;-O0&amp;lt;/tt&amp;gt; ist. Abzuraten ist von der maximalen Optimierung &amp;lt;tt&amp;gt;-O3&amp;lt;/tt&amp;gt;, die wegen function inlining und loop unrolling zu sehr breitem Code führt und für AVR absolut nicht angesagt ist.&lt;br /&gt;
&lt;br /&gt;
==Vermeide printf, scanf, malloc==&lt;br /&gt;
Funktionen von diesem Kaliber sind die absoluten Platz- und Zeitfresser. &lt;br /&gt;
&lt;br /&gt;
Alternativen findet man reichlich in der &amp;lt;tt&amp;gt;avr-libc&amp;lt;/tt&amp;gt; wie &amp;lt;tt&amp;gt;itoa&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;atoi&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Und für &amp;lt;tt&amp;gt;malloc&amp;lt;/tt&amp;gt; und Konsorten sind dynamische Arrays und das Compiler-Builtin &amp;lt;tt&amp;gt;__builtin_alloca&amp;lt;/tt&amp;gt; effizientere Alternativen, siehe auch im Abschnitt &amp;quot;[[avr-gcc#Dynamische Speicherallokierung|Dynamische Speicherallokierung]]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Konstante Strings ins Flash== &lt;br /&gt;
Konstante Strings, wie sie zu Ausgabezwecken Verwendung finden, werden im Programm oft nicht verändert und brauchen nicht SRAM zu belegen (und damit auch Flash, von wo aus sie vom Startup-Code ins SRAM kopiert werden), sondern gehören ins Flash! &lt;br /&gt;
&lt;br /&gt;
Entsprechende Routinen, um auf Strings im Flash zuzugreifen, tragen die Suffix &amp;lt;tt&amp;gt;_P&amp;lt;/tt&amp;gt;, wie z.B. &amp;lt;tt&amp;gt;strcmp_P&amp;lt;/tt&amp;gt; mit dem Prototyp&lt;br /&gt;
 extern int *strcmp_P (char *, const prog_char *)&lt;br /&gt;
Die Implementierungen befinden sich in der &amp;lt;tt&amp;gt;avr-libc&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Anwendung:'''&lt;br /&gt;
 #include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 const prog_char str_p[]     = &amp;quot;Ein String im Flash&amp;quot;;&lt;br /&gt;
 const char str2_p[] PROGMEM = &amp;quot;Noch ein String im Flash&amp;quot;;&lt;br /&gt;
 ...&lt;br /&gt;
   {{ccomment|String im SRAM mit String im Flash vergleichen}}&lt;br /&gt;
   if (!strcmp_P (str_sram, str_p))&lt;br /&gt;
   {&lt;br /&gt;
       {{ccomment|mach was bei Gleichheit}}&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
   {{ccomment|&amp;quot;foo&amp;quot; wird im RAM angelegt. Ineffizient für konstante Strings!}}  &lt;br /&gt;
   {{ccomment|Beachte, daß damit strcmp (nicht strcmp_P) benutzt werden muss.}}  &lt;br /&gt;
   if (!strcmp (str_sram, &amp;quot;foo&amp;quot;))&lt;br /&gt;
   {&lt;br /&gt;
       {{ccomment|mach was bei Gleichheit}}&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
   {{ccomment|PSTR bewirkt, daß die String-Konstante &amp;quot;foo&amp;quot;}}&lt;br /&gt;
   {{ccomment|im Flash angelegt wird}}&lt;br /&gt;
   if (!strcmp_P (str_sram, PSTR (&amp;quot;foo&amp;quot;))&lt;br /&gt;
   {&lt;br /&gt;
       {{ccomment|mach was bei Gleichheit}}&lt;br /&gt;
   }&lt;br /&gt;
 ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Sprungtabelle===&lt;br /&gt;
Genauso macht man auch eine Sprungtabelle, um anhand von Kommando-Strings dazugehörige Funktionen ausführen zu lassen:&lt;br /&gt;
 #include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 int func1 (int arg)&lt;br /&gt;
 {&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 #define TEXT_LEN 15&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Die Kommandostruktur}}&lt;br /&gt;
 typedef struct &lt;br /&gt;
 {&lt;br /&gt;
    int (*func)(int);      {{ccomment|Zeiger auf die auszuführende Funktion}}&lt;br /&gt;
    int arg;               {{ccomment|das Argument, das mitübergeben wird}}&lt;br /&gt;
    char text[1+TEXT_LEN]; {{ccomment|Text, maximal TEXT_LEN Zeichen lang}}&lt;br /&gt;
 } command_t;&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Das Array mit den Kommandos.}}&lt;br /&gt;
 {{ccomment|Die funcx sind vom Prototyp (z.B. func1 oben)}}&lt;br /&gt;
 {{ccomment|int funcx (int arg);}}&lt;br /&gt;
 const command_t commands[] PROGMEM =&lt;br /&gt;
 {&lt;br /&gt;
    { func1, 0, &amp;quot;Befehl 1&amp;quot; },&lt;br /&gt;
    { func2, 3, &amp;quot;Befehl für func2&amp;quot; }&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Sucht in commands[] nach text und führt gegebenenfalls}}&lt;br /&gt;
 {{ccomment|die dazugehörige Funktion funcx mit Argument arg aus.}}&lt;br /&gt;
 {{ccomment|Liefert den Rückgabewert von funcx}}&lt;br /&gt;
 {{ccomment|oder -1, falls text nicht gefunden wurde.}}&lt;br /&gt;
 int execute (const char *text)&lt;br /&gt;
 {&lt;br /&gt;
    {{ccomment|Schleifenvariable}}&lt;br /&gt;
    unsigned char i;&lt;br /&gt;
 &lt;br /&gt;
    {{ccomment|Wandert durch das Array mit Kommando-Strukturen}}&lt;br /&gt;
    const command_t * cmd = commands;&lt;br /&gt;
 &lt;br /&gt;
    {{ccomment|sizeof wird von gcc ausgewertet und ist wie eine Konstante,}}&lt;br /&gt;
    {{ccomment|denn beide sizeofs sind zur Compilezeit bekannt}}&lt;br /&gt;
    for (i=0; i &amp;lt; sizeof(commands) / sizeof(command_t); i++)&lt;br /&gt;
    {&lt;br /&gt;
       {{ccomment|Ist das der gesuchte String?}} &lt;br /&gt;
       if (strcmp_P (text, cmd-&amp;gt;text))&lt;br /&gt;
       {&lt;br /&gt;
         {{ccomment|Nein, dann weitersuchen}}&lt;br /&gt;
         cmd++;&lt;br /&gt;
         continue;&lt;br /&gt;
       }&lt;br /&gt;
 &lt;br /&gt;
       {{ccomment|Ja}}&lt;br /&gt;
       int (*func)(int), arg;&lt;br /&gt;
 &lt;br /&gt;
       {{ccomment|Dann Funktionszeiger und Argument besorgen,}}&lt;br /&gt;
       func = (int(*)(int)) pgm_read_word (&amp;amp; cmd-&amp;gt;func);&lt;br /&gt;
       arg  = (int)         pgm_read_word (&amp;amp; cmd-&amp;gt;arg);&lt;br /&gt;
 &lt;br /&gt;
       {{ccomment|Funktion ausführen und deren Wert zurückliefern}} &lt;br /&gt;
       return func (arg);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    {{ccomment|text ist nicht in commands}}&lt;br /&gt;
    return -1;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Nachteil dabei ist, daß jeder String den maximalen Platz von &amp;lt;tt&amp;gt;TEXT_LEN+1&amp;lt;/tt&amp;gt; Zeichen belegt.&lt;br /&gt;
Falls man da noch weiter sparen will, dann kann man die Strings wieder ins Flash legen und ihre Adresse in der Struktur merken. Dadurch belegt ein String nur noch Länge+3 Zeichen (+3 wegen 1 Endezeichen und 2 Bytes für seine in der Struktur gemerkte Adresse). Die Definition der Tabelle wird aber umständlicher, weil jeder String einzeln angegeben werden muss:&lt;br /&gt;
 #include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Die Kommandostruktur}}&lt;br /&gt;
 typedef struct &lt;br /&gt;
 {&lt;br /&gt;
    ...&lt;br /&gt;
    char * text;  {{ccomment|Zeiger auf Text}}&lt;br /&gt;
 } command_t;&lt;br /&gt;
 &lt;br /&gt;
 const prog_char str_1[] = &amp;quot;Befehl 1&amp;quot;;&lt;br /&gt;
 const prog_char str_2[] = &amp;quot;Befehl für func2&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
 const command_t commands[] PROGMEM =&lt;br /&gt;
 {&lt;br /&gt;
    { func1, 0, str_1 },&lt;br /&gt;
    { func2, 3, str_2 }&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Sucht in commands[] nach text und führt gegebenenfalls}}&lt;br /&gt;
 {{ccomment|die dazugehörige Funktion funcx mit Argument arg aus.}}&lt;br /&gt;
 {{ccomment|Liefert den Rückgabewert von funcx}}&lt;br /&gt;
 {{ccomment|oder -1, falls text nicht gefunden wurde.}}&lt;br /&gt;
 int execute (const char *text)&lt;br /&gt;
 {&lt;br /&gt;
    {{ccomment|Schleifenvariable}}&lt;br /&gt;
    unsigned char i;&lt;br /&gt;
 &lt;br /&gt;
    {{ccomment|Wandert durch das Array mit Kommando-Strukturen}}&lt;br /&gt;
    const command_t * cmd = commands;&lt;br /&gt;
 &lt;br /&gt;
    {{ccomment|sizeof wird von gcc ausgewertet und ist wie eine Konstante,}}&lt;br /&gt;
    {{ccomment|denn beide sizeofs sind zur Compilezeit bekannt}}&lt;br /&gt;
    for (i=0; i &amp;lt; sizeof(commands) / sizeof (command_t); i++)&lt;br /&gt;
    {&lt;br /&gt;
       const prog_char * text_P;&lt;br /&gt;
 &lt;br /&gt;
       {{ccomment|Liest die Startadresse von str_x}}&lt;br /&gt;
       text_P = (const prog_char *) pgm_read_word (&amp;amp; cmd-&amp;gt;text);&lt;br /&gt;
 &lt;br /&gt;
       {{ccomment|Ist das der gesuchte String?}}        &lt;br /&gt;
       if (strcmp_P (text, text_P))&lt;br /&gt;
       {&lt;br /&gt;
          ...&lt;br /&gt;
&lt;br /&gt;
==Lokale Variablen verwenden==&lt;br /&gt;
&lt;br /&gt;
Beim Manipulieren globaler Variablen kann es günstig sein, diese in eine lokale Variable zu kopieren, dort zu verändern, und sie danach wieder zu schreiben &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
char var;&lt;br /&gt;
&lt;br /&gt;
void foo1()&lt;br /&gt;
{&lt;br /&gt;
   var++;&lt;br /&gt;
   if (var &amp;gt; 10)&lt;br /&gt;
      var = 1;&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dadurch wird einmal unnötig gespeichert (der dritte Befehl kann vermieden werden).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
foo1:&lt;br /&gt;
  lds r24,var        ; *movqi/4 [length = 2]&lt;br /&gt;
  subi r24,lo8(-(1)) ; addqi3/2 [length = 1]&lt;br /&gt;
  sts var,r24        ; *movqi/3 [length = 2]&lt;br /&gt;
  cpi r24,lo8(11)    ; cmpqi/2  [length = 1]&lt;br /&gt;
  brlt .L3           ; branch   [length = 1]&lt;br /&gt;
  ldi r24,lo8(1)     ; *movqi/2 [length = 1]&lt;br /&gt;
  sts var,r24        ; *movqi/3 [length = 2]&lt;br /&gt;
.L3:&lt;br /&gt;
  ret   &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Indem man eine lokale Variable (&amp;lt;tt&amp;gt;var2&amp;lt;/tt&amp;gt;) verwendet für die Änderung von &amp;lt;tt&amp;gt;var&amp;lt;/tt&amp;gt; vermeidet man dies:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
char var;&lt;br /&gt;
&lt;br /&gt;
void foo2()&lt;br /&gt;
{&lt;br /&gt;
   char var2 = var;&lt;br /&gt;
   &lt;br /&gt;
   var2++;&lt;br /&gt;
   if (var2 &amp;gt; 10)&lt;br /&gt;
      var2 = 1;&lt;br /&gt;
      &lt;br /&gt;
   var = var2;&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dadurch wird erst am Ende gespeichert. &amp;lt;tt&amp;gt;var2&amp;lt;/tt&amp;gt; lebt in Register &amp;lt;tt&amp;gt;r24&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
foo2:&lt;br /&gt;
  lds r24, var       ; *movqi/4   [length = 2]&lt;br /&gt;
  subi r24,lo8(-(1)) ; addqi3/2   [length = 1]&lt;br /&gt;
  cpi r24,lo8(11)    ; cmpqi/2    [length = 1]&lt;br /&gt;
  brlt .L2           ; branch     [length = 1]&lt;br /&gt;
  ldi r24,lo8(1)     ; *movqi/2   [length = 1]&lt;br /&gt;
.L2:&lt;br /&gt;
  sts var, r24       ; *movqi/3   [length = 2]&lt;br /&gt;
  ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei diesem einfachen Beispiel spart man lediglich eine Instruktion. Bei komplexeren Rechnungen oder längeren Datentypen kann es aber durchaus lohnender sein, in lokale Register zu kopieren.&lt;br /&gt;
&lt;br /&gt;
==Arithmetik==&lt;br /&gt;
&lt;br /&gt;
=== Daten zerlegen/zusammensetzen ===&lt;br /&gt;
&lt;br /&gt;
In systemnahen Programmen hat man oft was Problem, auf die einzelnen Bytes oder Bitfelder einer grösseren Datenstruktur zuzugreifen. Indem man sich ein Komposit baut, das die gewünschten Strukturen überlagert, kann man effizient z.B. auf Bytes zugreifen. Ausnahme sind Bitfelder, deren Verwendung etwas breiten Code ergibt. Bitfelder &amp;quot;von Hand&amp;quot; zu manipulieren, ist da manchmal effizienter, führt jedoch zu schlecht lesbarem Code.&lt;br /&gt;
&lt;br /&gt;
Oft benötigt wird der Zugriff auf die einzelnen Bytes eines &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, also der Zugriff auf die Bytes eines 16-Bit-Wertes:&lt;br /&gt;
&lt;br /&gt;
 typedef union&lt;br /&gt;
 {&lt;br /&gt;
    unsigned char  asByte[2];&lt;br /&gt;
    unsigned short asWord;&lt;br /&gt;
    int            asInt;&lt;br /&gt;
 } data16_t;&lt;br /&gt;
 &lt;br /&gt;
 data16_t data;&lt;br /&gt;
 ...&lt;br /&gt;
    int foo;&lt;br /&gt;
    uint8_t wert;&lt;br /&gt;
 &lt;br /&gt;
    data.asInt = foo;&lt;br /&gt;
    wert = data.asByte[1]; {{ccomment|die oberen 8 Bits von foo}}&lt;br /&gt;
&lt;br /&gt;
Ein komplexeres Beispiel, das noch mehr Datentypen überlagert:&lt;br /&gt;
 typedef ... foo_t;&lt;br /&gt;
 &lt;br /&gt;
 typedef union&lt;br /&gt;
 {&lt;br /&gt;
     unsigned char byte[4];      {{ccomment| Zugriff als Bytes (8 Bit) }}&lt;br /&gt;
     unsigned short word[2];     {{ccomment| Zugriff als Words (16 Bit) }}&lt;br /&gt;
     signed long slong;          {{ccomment| Zugriff als signed long (32 Bit) }}&lt;br /&gt;
 &lt;br /&gt;
     struct {{ccomment| Zugriff auf einzelne Bitgruppen }}&lt;br /&gt;
     {&lt;br /&gt;
         unsigned bit_0_3 : 4;   {{ccomment| 4 Bits (0..3) }}&lt;br /&gt;
         unsigned bit_4_8 : 5;   {{ccomment| 5 Bits (4..8) }}&lt;br /&gt;
         unsigned bit_9_21 : 13; {{ccomment| 13 Bits (9..21) }}&lt;br /&gt;
         unsigned bit_22_31: 10; {{ccomment| 10 Bits (22..31) }}&lt;br /&gt;
     };&lt;br /&gt;
 &lt;br /&gt;
     foo_t foo; {{ccomment| Zugriff als foo-Struktur }}&lt;br /&gt;
 } data_t;&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 {&lt;br /&gt;
     data_t data;&lt;br /&gt;
 &lt;br /&gt;
     data.byte[2] = 12;          {{ccomment| setzt byte 2 auf 12 }}&lt;br /&gt;
     data.bit_4_8 = 0x1f;        {{ccomment| setzt bits 4..8 (5 Stück) alle auf 1 }}&lt;br /&gt;
 &lt;br /&gt;
     int anInt = data.foo.anInt; {{ccomment| liest ein Feld von foo (hier ein int) }}&lt;br /&gt;
     ...&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
===libgcc2 verwenden===&lt;br /&gt;
&lt;br /&gt;
In der libgcc2 sind einige Arithmetik-Routinen in Assembler implementiert. Dazu gehören ein paar Algorithmen zu Division (mit Rest) und Multiplikation. &lt;br /&gt;
&lt;br /&gt;
Von diesen Algorithmen werden durch die avr-libc jedoch nur zwei Strukturen und Funktionen veröffentlicht: &amp;lt;tt&amp;gt;div_t&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;ldiv_t&amp;lt;/tt&amp;gt; resp. die Funktionen &amp;lt;tt&amp;gt;div()&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;ldiv()&amp;lt;/tt&amp;gt;. Siehe dazu deine Dokumentation zur avr-libc. Damit kann man Quotient und zusätzlich den Rest bei einer Division 16/16 bzw. 32/32 berechnen lassen; den Rest bekommt man quasi kostenlos als Nebenprodukt. Das ist praktisch, wenn man z.b. eine Zahl in Dezimaldarstellung umwandeln möchte oder von/nach [[BCD]].&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den via avr-libc veröffentlichten Funktionen gibt es aber noch Routinen, die z.B. auf 8-Bit-Werten operieren oder mit &amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt; Typen und dementsprechend effizienter sind.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel: Umwandeln nach Dezimalstring'''&lt;br /&gt;
&lt;br /&gt;
Hier ein Beispiel, das Division mit Rest für &amp;lt;tt&amp;gt;unsigned short&amp;lt;/tt&amp;gt; verwendet, um eine 16-Bit-Zahl in Dezimaldarstellung zu wandeln:&lt;br /&gt;
&lt;br /&gt;
 {{ccomment| Struktur definieren und Funktion bekannt machen }}&lt;br /&gt;
 typedef struct&lt;br /&gt;
 {&lt;br /&gt;
     unsigned short quot;&lt;br /&gt;
     unsigned short rem;&lt;br /&gt;
 } udiv_t;&lt;br /&gt;
 &lt;br /&gt;
 extern udiv_t udiv (unsigned short, unsigned short) __asm__(&amp;quot;__udivmodhi4&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment| 5 Ziffern (0...65535) und evtl. noch eine führende 0 }}&lt;br /&gt;
 #define DIGITS 6&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment| +1 wegen String-Ende (wird im Startup auf 0 gesetzt) }}&lt;br /&gt;
 char string[DIGITS+1];&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment| Wandelt zahl in Dezimaldarstellung um. }}&lt;br /&gt;
 {{ccomment| Der return-Wert zeigt irgendwo ins string[]-Array. }}&lt;br /&gt;
 {{ccomment| string[] wird verändert. }}&lt;br /&gt;
 char* toString (unsigned short zahl)&lt;br /&gt;
 {&lt;br /&gt;
     {{ccomment| s zeigt auf das Ende von string }}&lt;br /&gt;
     {{ccomment| string wird von hinten nach vorne gefüllt }}&lt;br /&gt;
     char *s = string + DIGITS;&lt;br /&gt;
  &lt;br /&gt;
     {{ccomment| qrem enthält Quotient (quot) und Rest (rem) der Divisionen }}&lt;br /&gt;
     udiv_t qrem = {.quot = zahl}; &lt;br /&gt;
 &lt;br /&gt;
     do&lt;br /&gt;
     {&lt;br /&gt;
         {{ccomment| Division mit Rest durch 10 }}&lt;br /&gt;
         {{ccomment| quot: Ergebnis für den nächsten Durchlauf }}&lt;br /&gt;
         {{ccomment| rem: Rest ist die Ziffer im 10er-System }}&lt;br /&gt;
         qrem = udiv (qrem.quot, 10);&lt;br /&gt;
  &lt;br /&gt;
         {{ccomment| Ziffer in Zeichen wandeln und speichern }}&lt;br /&gt;
         *(--s) = '0' + qrem.rem;&lt;br /&gt;
     } &lt;br /&gt;
     while (0 != qrem.quot);&lt;br /&gt;
  &lt;br /&gt;
     {{ccomment| Falls eine führende '0' gespeichert wurde: weg damit }}&lt;br /&gt;
     {{ccomment| ausser zahl war selbst schon 0 }}&lt;br /&gt;
     if (*s == '0' &amp;amp;&amp;amp; *(s+1) != '\0')&lt;br /&gt;
         s++;&lt;br /&gt;
 &lt;br /&gt;
     return s;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Falls man eine Division und/oder Rest für 8-Bit braucht, dann geht für &amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt; analog. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel: BCD-Umrechnung'''&lt;br /&gt;
&lt;br /&gt;
Wandeln einer 8-Bit-Zahl &amp;lt;tt&amp;gt;0 &amp;amp;lt;= num &amp;amp;lt; 100&amp;lt;/tt&amp;gt; nach [[BCD]]&lt;br /&gt;
&lt;br /&gt;
 typedef struct&lt;br /&gt;
 {&lt;br /&gt;
     unsigned char quot; {{ccomment| Quotient }}&lt;br /&gt;
     unsigned char rem;  {{ccomment| Rest (remainder) }}&lt;br /&gt;
 } udiv8_t;&lt;br /&gt;
 &lt;br /&gt;
 extern udiv8_t udiv8 (unsigned char, unsigned char) __asm__ (&amp;quot;__udivmodqi4&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment| Wandelt num nach BCD um, 0 &amp;lt;&amp;amp;#61; num &amp;lt;&amp;amp;#61; 99 }}&lt;br /&gt;
 {{ccomment| return-Wert ist dann 0x0 &amp;lt;&amp;amp;#61; return &amp;lt;&amp;amp;#61; 0x99 }}&lt;br /&gt;
 unsigned char to_bcd (unsigned char num)&lt;br /&gt;
 {&lt;br /&gt;
     udiv8_t qrem = udiv8 (num, 10);&lt;br /&gt;
 &lt;br /&gt;
     return (unsigned char) (qrem.quot &amp;lt;&amp;lt; 4) | qrem.rem;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Division durch Multiplikation===&lt;br /&gt;
===Vermeiden von float und double===&lt;br /&gt;
&lt;br /&gt;
=Inkompatibilität=&lt;br /&gt;
&lt;br /&gt;
[[GCC]] &amp;amp;ndash; und somit auch avr-gcc &amp;amp;ndash; werden ständig weiter entwickelt. Dies betrifft das Beheben von Fehlern, die Unterstützung neuer Architekturen/Sprachen/Betriebssysteme, Implementierung neuer Optimierungsalgorithmen, Vereinheitlichungen, etc.&lt;br /&gt;
&lt;br /&gt;
Leider führt dies auch zu Inkompatibilitäten verschiedener avr-gcc-Versionen untereinander, und eine C-Quelle, die mit einer Version von avr-gcc fehler- und warnungsfrei übersetzt werden kann, ist mit einer anderen Version möglicherweise nicht compilierbar.&lt;br /&gt;
&lt;br /&gt;
Die avr-gcc Version kann man anzeigen lassen, indem man in einer Shell/Eingabeaufforderung eintippt&lt;br /&gt;
 avr-gcc -v&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;#include &amp;lt;avr/signal.h&amp;gt;&amp;lt;/tt&amp;gt;: In Versionen bis 3.4.4 werden in dieser Header-Datei u.a. die Makros &amp;lt;tt&amp;gt;SIGNAL()&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;INTERRUPT()&amp;lt;/tt&amp;gt; definiert, die man braucht, wenn man eine C-Funktion als Interrupt-Routine ([[ISR]]) kennzeichnen will. In neueren Versionen ab 3.4.5 sind diese Definitionen in den Header &amp;lt;tt&amp;gt;avr/interrupt.h&amp;lt;/tt&amp;gt; gewandert, wo auch Makros wie &amp;lt;tt&amp;gt;sei()&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;cli()&amp;lt;/tt&amp;gt; definiert werden. Die Inkludierung von &amp;lt;tt&amp;gt;avr/signal.h&amp;lt;/tt&amp;gt; in den neueren avg-gcc Versionen führt zu einer Warnung, irgendwann vielleicht sogar zu einem Fehler, weil die Datei nicht mehr bei avr-gcc dabei ist und daher nicht mehr gefunden wird.&lt;br /&gt;
: '''Verwendet man bei einer älteren avr-gcc-Version &amp;lt;tt&amp;gt;SIGNAL&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;INTERRUPT&amp;lt;/tt&amp;gt; ohne &amp;lt;tt&amp;gt;avr/signal.h&amp;lt;/tt&amp;gt; zu includen, wird u.U. stillschweigend falscher Code erzeugt.'''&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;#include &amp;lt;util/...h&amp;gt;&amp;lt;/tt&amp;gt;: In &amp;lt;tt&amp;gt;util&amp;lt;/tt&amp;gt; stehen jetzt Header wie &amp;lt;tt&amp;gt;util/parity.h&amp;lt;/tt&amp;gt; oder das vielverwendete &amp;lt;tt&amp;gt;util/delay.h&amp;lt;/tt&amp;gt;, die vormals im Include-Unterverzeichnis &amp;lt;tt&amp;gt;avr&amp;lt;/tt&amp;gt; zu finden waren.&lt;br /&gt;
&lt;br /&gt;
;Interrupt Service Routinen: Auch die API zur Definition von [[ISR]]s hat sich von avr-gcc Version 3.x zur Version 4.x geändert:&lt;br /&gt;
:'''avr-gcc 3.x'''&lt;br /&gt;
::{|&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SIGNAL (SIG_INTERRUPT0)&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt Code */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
INTERRUPT (SIG_OVERFLOW0)&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt Code */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
:'''avr-gcc 4.x'''&lt;br /&gt;
::{|&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ISR (INT0_vect)&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt Code */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void TIMER0_OVF_vect (void) __attribute__((interrupt));&lt;br /&gt;
void TIMER0_OVF_vect (void)&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt Code */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Bugs=&lt;br /&gt;
&lt;br /&gt;
==== Bit 7 bei SFR-Zugriff ====&lt;br /&gt;
&lt;br /&gt;
Bei Sequenzen wie&lt;br /&gt;
 PORTB &amp;amp;= ~ (1 &amp;lt;&amp;lt; 7);&lt;br /&gt;
 PORTD &amp;amp;= ~ (1 &amp;lt;&amp;lt; 7);&lt;br /&gt;
&lt;br /&gt;
macht avr-gcc eine CSE-Optimierung (common subexpression elimination). Er legt die Konstante 127 (&amp;lt;tt&amp;gt;~(1 &amp;lt;&amp;lt; 7)&amp;lt;/tt&amp;gt;) in ein Register und verwendet den Registerinhalt, anstatt die Konstante direkt zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Das führt dazu, daß statt der gewünschten Befehlsfolge&lt;br /&gt;
 ; Sequenz 1&lt;br /&gt;
 cbi 37-0x20, 7	&lt;br /&gt;
 cbi 43-0x20, 7&lt;br /&gt;
Sequenzen folgender Gestalt erzeugt werden:&lt;br /&gt;
 ; Sequenz 2&lt;br /&gt;
 ldi r18,     lo8(127)   ; 127 nach R18&lt;br /&gt;
 &lt;br /&gt;
 in  r19,     37-0x20    ; PORTB nach R19 lesen&lt;br /&gt;
 ; Wird hier eine ISR ausgeführt, die PORTB verändert, dann wird die&lt;br /&gt;
 ; Änderung mit dem folgenden OUT überschrieben&lt;br /&gt;
 and r19,     r18	; oberstes Bit löschen&lt;br /&gt;
 ; dito&lt;br /&gt;
 out 37-0x20, r19	; PORTB schreiben&lt;br /&gt;
 &lt;br /&gt;
 in r19,      43-0x20	; analog&lt;br /&gt;
 and r19,     r18	&lt;br /&gt;
 out 43-0x20, r19	&lt;br /&gt;
&lt;br /&gt;
Abgesehen davon, daß Sequenz&amp;amp;nbsp;2 deutlich mehr Programmspeicher und Laufzeit benötigt als Sequenz&amp;amp;nbsp;1, kann es zu folgendem Fehler kommen:&lt;br /&gt;
&lt;br /&gt;
Bei der zweiten Codesequenz erfolgt der Zugriff auf die SFRs nicht atomar. Wird der C-Code in einem Programm ausgeführt, das in einer [[ISR]] zB Port B3 verändert und wird diese ISR zwischen dem IN und dem OUT Befehl ausgeführt, dann überschreibt der OUT-Befehl den Wert von PORTB und die Aktion für Port B3 in der ISR wird wieder rückgängig gemacht. Das ist dann ein Programmfehler.&lt;br /&gt;
&lt;br /&gt;
Damit das Problem zum Tragen kommt, müssen mehrere Bedingungen erfüllt sein:&lt;br /&gt;
* Bei mindestens zwei C-Befehlen wird der Wert 127 als 8-Bit-Wert benötigt. Das ist zB auch der Fall, wenn dieser Wert nur gespeichert wird oder modulo 0x80 gerechnet wird.&lt;br /&gt;
* Mindestens einer dieser Befehle löscht Bit 7 eines SFR aus dem bitadressierbaren I/O-Bereich. (Ausser PORTx oder DDRx sind in diesem Bereich noch weitere SFR untergebracht.)&lt;br /&gt;
* Im Programm wird auf unterschiedlichen [[Interrupt]]-Ebenen auf dieses SFR zugegriffen und die oben gezeigt Stelle kann von der ISR unterbrochen werden.&lt;br /&gt;
* Die beiden C-Befehle müssen nicht unmittelbar aufeinander folgen. Es können auch andere C-Befehle dazwischen stehen. &lt;br /&gt;
&lt;br /&gt;
Bei den meisten Programmen wird das angesprochene Problem nicht zu einem Fehler führen. Falls doch, kann man dem begegnen mit folgenden &lt;br /&gt;
&lt;br /&gt;
;Workarounds:&lt;br /&gt;
* Die C-Stelle wird in CLI/SEI eingeschlossen und kann damit nicht mehr von einer ISR unterbrochen werden.&lt;br /&gt;
* Alternativ schreibt man vor und nach jedem problematischen SFR-Zugriff folgendes Kommando:&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 __asm volatile (&amp;quot;&amp;quot;::);&lt;br /&gt;
|}&lt;br /&gt;
:Dieses Kommando erzeugt keine Assembler-Instruktionen, vermeidet aber die unerwünschte &amp;quot;Optimierung&amp;quot; im gcc, und es entsteht Code gemäß Sequenz&amp;amp;nbsp;1.&lt;br /&gt;
* Alternativ definiert man sich ein Makro, mit dem man die Portzugriffe tätigt:&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 #define CBI(A,B)    __asm volatile (&amp;quot;cbi\t%0, %1&amp;quot; :: &amp;quot;M&amp;quot; (_SFR_IO_ADDR(A)), &amp;quot;M&amp;quot; (B))&lt;br /&gt;
|}&lt;br /&gt;
:Und löscht das Bit mit&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 CBI (PORTB, 7);&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;tt&amp;gt;__builtin_return_address(0)&amp;lt;/tt&amp;gt; ====&lt;br /&gt;
ist entgegen der Spezifikation nicht implementiert und liefert in der Regel ein falsches Ergebnis.&lt;br /&gt;
&lt;br /&gt;
;Workaround:&lt;br /&gt;
&lt;br /&gt;
(hier für eine ISR):&lt;br /&gt;
 #include &amp;lt;stdarg.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|The return address}}&lt;br /&gt;
 unsigned short volatile return_addr;&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Define our special SIGNAL (INTERRUPT analoguous)}}&lt;br /&gt;
 #define SIGNAL_BRA(signame,var)                                         \&lt;br /&gt;
      void signame (unsigned short var, ...) __attribute__ ((signal));   \&lt;br /&gt;
      void signame (unsigned short var, ...)&lt;br /&gt;
 &lt;br /&gt;
 #define SWAP_BYTES(x) (((x) &amp;gt;&amp;gt; 8) | ((x) &amp;lt;&amp;lt; 8))&lt;br /&gt;
 &lt;br /&gt;
 SIGNAL_BRA (SIG_OUTPUT_COMPARE1A, dummy)&lt;br /&gt;
 {&lt;br /&gt;
    {&lt;br /&gt;
       va_list vlist;&lt;br /&gt;
       va_start (vlist, dummy);&lt;br /&gt;
  &lt;br /&gt;
       {{ccomment|Get the return address from the stack}}&lt;br /&gt;
       dummy = va_arg (vlist, unsigned short);&lt;br /&gt;
 &lt;br /&gt;
       {{ccomment|Convert stack address to code location}}&lt;br /&gt;
       addr = SWAP_BYTES(dummy) &amp;lt;&amp;lt; 1;&lt;br /&gt;
       va_end (vlist);&lt;br /&gt;
    }&lt;br /&gt;
    {{ccomment|ISR Code}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== gcc 4.x ==== &lt;br /&gt;
&lt;br /&gt;
In der 4er-Version gab es tiefgreifende interne Änderungen im Compiler; er ist noch instabil und kann momentan nicht für den Produktiv-Einsatz empfohlen werden (Stand 02/2006). &lt;br /&gt;
&lt;br /&gt;
Die Auswirkungen der Optimierungen auf das Zielsystem &amp;lt;tt&amp;gt;avr&amp;lt;/tt&amp;gt; bleibt abzuwarten, dürfte aber nicht wesentlich sein. Die neue 4-er Version wurde u.a. deshalb aufgelegt, um mit dem Intel-Compiler gleichzuziehen &amp;amp;ndash; also im Hinblick auf das Zielsystem &amp;lt;tt&amp;gt;i386&amp;lt;/tt&amp;gt;) gemacht. &lt;br /&gt;
&lt;br /&gt;
Auch nach dem Release der 4-er Version wird die 3-er Version weiterentwickelt, da erst nach 1-2 Jahren nach Release einer neuer Major-Version ein Umstieg anzuraten ist und auch erst dann getätigt wird (zumindest im professionellen Bereich).&lt;br /&gt;
&lt;br /&gt;
=Abkürzungen und Bezeichnungen=&lt;br /&gt;
; [[GCC]]: GNU Compiler Collection&lt;br /&gt;
; gcc: GNU C-Compiler&lt;br /&gt;
; GPR: '''G'''eneral '''P'''urpose '''R'''egister&lt;br /&gt;
; [[ISR]]: [[Interrupt|'''I'''nterrupt]] '''S'''ervice '''R'''outine&lt;br /&gt;
; [[IRQ]]: '''I'''nterrupt '''R'''e'''q'''uest&lt;br /&gt;
; Prolog/Epilog: Code am Anfang/Ende jeder Funktionen/ISR, der dazu dient, verwendete Register zu sichern, den Stack-Frame für lokale [[Variable|Variablen]] anzulegen (falls benötigt), Stackpointer zu setzen, zurück zu springen (&amp;lt;tt&amp;gt;ret&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;reti&amp;lt;/tt&amp;gt;), etc.&lt;br /&gt;
; SFR: '''S'''pecial '''F'''unction '''R'''egister&lt;br /&gt;
; Target: Zielsystem, in unserem Falle avr&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[C-Tutorial]]&lt;br /&gt;
'''Code-Beispiele'''&lt;br /&gt;
* [[Hallo Welt für AVR (LED blinken)]] - ein erstes Beispiel für avr-gcc&lt;br /&gt;
*[[:Kategorie:Quellcode_C|C-Codebeispiele]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
'''Details'''&lt;br /&gt;
* [[Inline-Assembler in avr-gcc|Inline-Assembler]]&lt;br /&gt;
* [[avr-gcc/Interna|Interna von avr-gcc]]&lt;br /&gt;
&lt;br /&gt;
'''Installation (Linux)'''&lt;br /&gt;
* [[Linuxdistribution_Avr-live-cd]]&lt;br /&gt;
* [[avr-gcc und avrdude installieren]]&lt;br /&gt;
'''Sonstiges'''&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Speicherverbrauch bestimmen mit avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[Dev-Cpp IDE]]&lt;br /&gt;
* [[AVR]]&lt;br /&gt;
----&lt;br /&gt;
* [[Sourcevergleich]]&lt;br /&gt;
* [[Codevergleich AVR-Compiler]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
==Dokumentation==&lt;br /&gt;
* [http://gcc.gnu.org/onlinedocs/ GCC online documentation (en)] Offline findest du die Doku für gcc, cpp (Präprozessor) und avr-libc bei [[WinAVR]] in&lt;br /&gt;
:&amp;lt;pre&amp;gt;&amp;lt;GCC_HOME&amp;gt;/doc/gcc/&amp;lt;/pre&amp;gt;&lt;br /&gt;
: bzw.&lt;br /&gt;
:&amp;lt;pre&amp;gt;&amp;lt;GCC_HOME&amp;gt;/doc/avr-libc/&amp;lt;/pre&amp;gt;&lt;br /&gt;
:Online finden sich die Dokumente in&lt;br /&gt;
* [http://gcc.gnu.org/onlinedocs/gcc.pdf gcc.pdf (1900 kByte)] - Dokumentation des C/C++/Java-Compilers GCC (en)&lt;br /&gt;
* [http://gcc.gnu.org/onlinedocs/cpp.pdf cpp.pdf (470 kByte)] - Dokumentation des C-Präprozessors (en)&lt;br /&gt;
* [http://www.nongnu.org/avr-libc/user-manual/modules.html http://www.nongnu.org/avr-libc/user-manual] - Dokumentation zur avr-libc.&lt;br /&gt;
&lt;br /&gt;
== Downloads==&lt;br /&gt;
* [http://sourceforge.net/projects/winavr/ WinAVR-Projekt bei sourceforge.net (en)]&lt;br /&gt;
* [http://cdk4avr.sourceforge.net/ avr-gcc und toolchain als Linux-Paket bei sourceforge.net (en)]&lt;br /&gt;
* [[Linuxdistribution_Avr-live-cd]]&lt;br /&gt;
== Tipps, Installation ==&lt;br /&gt;
*[http://www.nongnu.org/avr-libc/user-manual/install_tools.html ''&amp;quot;Installing the GNU Tool Chain&amp;quot;''] Hilfe zum Build und Installation von GCC, binutils, etc unter Linux&lt;br /&gt;
* Im GCC-Handbuch, siehe [[#Dokumentation|Dokumentation]].&lt;br /&gt;
* [http://www.linuxfocus.org/Deutsch/November2004/article352.shtml www.linuxfocus.org (Artikel)] - Tipps zu Build und Installation von avr-gcc, binutils und avr-libc unter Linux&lt;br /&gt;
* [http://users.rcn.com/rneswold/avr/ Rich Neswold: ''A GNU Development Environment for the AVR Microcontroller'']&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/24166 www.mikrocontroller.net (Foren-Beitrag)] - Installation von GCC und Toolchain unter Mac OS X&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=125603#125603 www.roboternetz.de (Foren-Beitrag)] ''avrgcc + avrdude installieren''&lt;br /&gt;
&lt;br /&gt;
== Sonstiges ==&lt;br /&gt;
* [http://gcc.gnu.org/ Offizielle Homepage von GCC (en)]&lt;br /&gt;
* [http://de.wikipedia.org/wiki/GNU_Compiler_Collection GCC in der deutschen Wikipedia]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial avr-gcc-Tutorial auf mikrocontroller.net]&lt;br /&gt;
* [http://www.avrfreaks.net/AVRGCC/ avr-gcc bei avrfreaks.net (en)]&lt;br /&gt;
* [http://savannah.nongnu.org/projects/avr-libc/ Nützliche GCC Runtime-Libary]&lt;br /&gt;
&lt;br /&gt;
=Autor=&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:SprinterSB|SprinterSB]] 11:27, 7. Dez 2005 (CET)&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Quellcode C|!]]&lt;br /&gt;
[[Kategorie:Software]]&lt;/div&gt;</summary>
		<author><name>Inrfb2</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10419</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10419"/>
				<updated>2007-03-18T08:39:46Z</updated>
		
		<summary type="html">&lt;p&gt;Inrfb2: /* Reihenfolge der Auswertung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Programmiersprache C wurde 1971 als Gundlage für das Betriebssystem UNIX in den USA entwickelt (UNIX ist zu über 90% in C geschrieben). 1978 wurde von Brian Kernighan und Dennis Ritchie eine eindeutige Sprachdefinition entwickelt. Mittlerweile ist C von ANSI und ISO standardisiert.&lt;br /&gt;
&lt;br /&gt;
Heute sind C und ihr Nachfolger C++ die dominierenden Programmiersprachen. Sehr viele Anwendungen sind in C geschrieben, was inzwischen auch auf eingebettete Systeme zutrifft, die lange in Assembler programmiert werden mussten, da keine ausreichend leistungsfähigen Compiler zur Verfügung standen. &lt;br /&gt;
&lt;br /&gt;
Leider ist C nicht einfach zu lernen &amp;amp;ndash; es wurde weder von noch für Hobby-Programmierer entwickelt &amp;amp;ndash; und eignet sich daher nur bedingt für den Einsteiger. Mit etwas Übung und einem optimierenden Compiler kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
Vom Design her ist C eine Hardware-unabhängig Sprache. Das bedeutet, daß C-Programme mit vertretbarem Aufwand auf ein anderes System portiert werden können. Dazu benötigt man lediglich einen anderen Compiler, und Inline-Assembler-Anweisungen (Assembleranweisungen innerhalb eines C-Programmes) müssen der neuen Hardware (Prozessor) angepasst werden. &lt;br /&gt;
&lt;br /&gt;
==Geschichte==&lt;br /&gt;
;1971: C wird entwickelt&lt;br /&gt;
;1978: Kernighan und Ritchie definieren die Sprache.&lt;br /&gt;
;1983: ANSI und ISO standardisieren C.&lt;br /&gt;
;1992: Bjarne Stroustrup enwickelt die Nachfolgesprache C++.&lt;br /&gt;
&lt;br /&gt;
=Aufbau eines C-Programmes=&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
   C-Programme haben keinen fixen Aufbau wie z.B. Pascal. Es gibt zwar gewisse Regeln, aber sonst sind dem Programmierer alle Freiheiten überlassen. Der folgende &amp;quot;Beispiel-Aufbau&amp;quot; ist daher nicht zwingend und kann durchaus verändert werden.&lt;br /&gt;
&lt;br /&gt;
   Natürlich haben C-Programme einen fixen Aufbau! Ebenso wie Pascal-Programme auch unterliegen sie einer strikten Grammatik! &lt;br /&gt;
Auskommentiert --[[Benutzer:SprinterSB|SprinterSB]] 10:23, 17. Feb 2006 (CET)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Ein einfaches C-Programm könnte folgendermassen aussehen. Das Programm tut eigentlich nichts, aber das Beispiel zeigt den prinzipiellen Aufbau. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 int Zahl1;&lt;br /&gt;
 char Zeichen1;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int zahl2;&lt;br /&gt;
 &lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Beschreibung:'''&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndash; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
 {{comment|void-Definition von main ist nur beim Controller ueblich}}&lt;br /&gt;
 {{comment|spezielle Compilereinstellungen sind noetig, damit bei dieser Definition von main}}&lt;br /&gt;
 {{comment|kein Fehler/Warnung erzeugt wird.}}&lt;br /&gt;
 void main ()&lt;br /&gt;
 {&lt;br /&gt;
     ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
 int main (void)&lt;br /&gt;
 {  {{comment|der Block &amp;quot;main&amp;quot; beginnt}}&lt;br /&gt;
    int zahl;&lt;br /&gt;
    &lt;br /&gt;
    {   {{comment|ein Block beginnt}}&lt;br /&gt;
        {{comment|hier koennen Deklarationen und Anweisungen stehen}}&lt;br /&gt;
    }   {{comment|der Block endet}}&lt;br /&gt;
   &lt;br /&gt;
    return 0;&lt;br /&gt;
 }  {{comment|&amp;quot;main&amp;quot; endet}}&lt;br /&gt;
&lt;br /&gt;
=Datentypen=&lt;br /&gt;
==Elementare Datentypen==&lt;br /&gt;
Der Datentyp einer Variable gibt an, welche Werte eine Variable enthalten kann, welcher Art diese Daten sind und wie sie verarbeitet werden, etwa in arithmetischen Operationen wie einer Addition. So ist es zum Beispiel möglich, in eine Variable vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ganze Zahlen zwischen ca. -32000 und +32000 einzutragen. In einer char-Variable können ASCII-Zeichen gespeichert werden (alles, was Sie mit der Tastatur erzeugen können) oder ganze Zahlen von -128 bis 127.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da C plattformabhängig ist, hängt die Größe eines Datentypes zum Teil von der genutzten Hardware (z.B. 8, 16 oder 32 Bit-Controller) und dem Compiler und dessen Einstellungen ab!&lt;br /&gt;
&lt;br /&gt;
===int, char, short, long (ganze Zahlen)===&lt;br /&gt;
In Variable dieser Typen können Sie ganze Zahlen abspeichern, also z.B. 1, &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;2, 100, 12345. Jeden dieser Typen gibt es in zwei Ausprägungen: als &amp;quot;&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;quot;, also als vorzeichenbehafteten Typ, und als &amp;quot;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&amp;quot;, also ohne Vorzeichen, d.h. das Vorzeichen wird als 0 oder +1 genommen. &lt;br /&gt;
&lt;br /&gt;
Vorzeichenbehaftete Ganzzahl-Typen werden intern im &amp;lt;tt&amp;gt;n-1&amp;lt;/tt&amp;gt;-Komplement dargestellt, das Vorzeichen selbst findet sich also im höchstwertigen Bit. Werden zur Speicherung ''b'' Bits verwendet, dann reicht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;z.B. *zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==Enum==&lt;br /&gt;
&lt;br /&gt;
Über &amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt; können Aufzählungen definiert werden. Die Werte sind &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Werte und beginnen mit&amp;amp;nbsp;0. Der folgende enum hat einen um&amp;amp;nbsp;1 grösseren Wert. Mit einer Zuweisung können auch andere Werte zugeordnet werden. Klarer wird's im Beispiel:&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 enum Farben&lt;br /&gt;
 {&lt;br /&gt;
    ROT,&lt;br /&gt;
    GRUEN,&lt;br /&gt;
    BLAU,&lt;br /&gt;
    BRAUN = 5,&lt;br /&gt;
    SCHWARZ&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
Dies definiert die Konstanten &amp;lt;tt&amp;gt;ROT=0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;GRUEN=1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BLAU=2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BRAUN=5&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;SCHWARZ=6&amp;lt;/tt&amp;gt; und den Typ &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void foo (enum Farben farbe)&lt;br /&gt;
{&lt;br /&gt;
   switch (farbe)&lt;br /&gt;
   {&lt;br /&gt;
      case ROT:&lt;br /&gt;
         ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit kann man anstatt &amp;quot;magischer&amp;quot; Zahlen sprechende Namen im Code verwenden, etwa in Berechnungen und Zuweisungen, Vergleichen oder als Konstante hinter einem &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zusammengesetzte Datentypen==&lt;br /&gt;
===Arrays===&lt;br /&gt;
Oft muß man sehr viele Werte gleichzeitig abspeichern und betrachten, die alle der selben Aufgabe dienen. Man schreibt z.B. ein Programm, das 10 Zahlen einlesen und anschließend wieder ausgeben soll. Man könnte das natürlich mit 10 einzelnen Variablen bewerkstelligen, aber es ist sinnvoller, dabei Arrays &amp;amp;ndash; teilweise auch als ''Felder'' bezeichnet &amp;amp;ndash; zu verwenden.&lt;br /&gt;
&lt;br /&gt;
In einem Array werden mehrere Variablen gleichen Typs zusammengefasst und hintereinander im Speicher abgelegt. So kann man viele tausend Variablen anlegen mit nur einer Zeile Code. Doch es gibt noch größere Vorteile: Sie können das Array mit einer Schleife ganz einfach nach Werten durchsuchen. Stellen Sie sich vor, Sie müssten mit 100 verschiedenen Variablen &amp;lt;tt&amp;gt;Zahl_00&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;Zahl_99&amp;lt;/tt&amp;gt; arbeiten!&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}}&amp;amp;#91;{{Konstante}}&amp;amp;#93;;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 unsigned int werte[100];&lt;br /&gt;
&lt;br /&gt;
Der Name muß natürlich ein gültiger Bezeichner sein, als Datentyp kann jeder Typ genommen werden &amp;amp;ndash; sowohl elementare Datentypen als auch Zeiger, Strukturen, Unions oder selbst definierte Datentypen. In der eckigen Klammer wird die Anzahl der Elemente bekanntgegeben. Ein mit [3] definiertes Array hat Platz für drei Variablen. Da der Index immer bei 0 beginnt, greift man also mit &amp;lt;tt&amp;gt;[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;[1]&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;[2]&amp;lt;/tt&amp;gt; auf den jeweilige Inhalt zu. Um auf eine der im Array enthaltenen Variablen zugreifen zu können, müssen Sie den Variablennamen und in eckigen Klammern den Index (die &amp;quot;Nummer&amp;quot;) der Variablen angeben. Diese Variable verhält sich dann wie eine ganz normale Variable des jeweiligen Datentypes. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #define NZAHLEN 10&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int i;&lt;br /&gt;
    int zahlen[NZAHLEN];  {{comment|zahlen[0] ... zahlen[9]}}&lt;br /&gt;
  &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++)&lt;br /&gt;
    {&lt;br /&gt;
       printf (&amp;quot;Bitte Zahl %d eingeben: &amp;quot;, i);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; zahlen[i]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++) &lt;br /&gt;
       printf (&amp;quot;Zahl %d ist: %d\n&amp;quot;, i, zahlen[i]);&lt;br /&gt;
      &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 10 int-Variablen großes Array angelegt. &lt;br /&gt;
In dieses wird nun der Reihe nach 10 Zahlen eingelesen. &lt;br /&gt;
Anschließend werden alle 10 Zahlen ausgegeben. &lt;br /&gt;
&lt;br /&gt;
Dabei wird die Größe der Arrays und das Schleifenende über das Define &amp;quot;&amp;lt;tt&amp;gt;NZAHLEN&amp;lt;/tt&amp;gt;&amp;quot; angegeben. Dadurch muss nur ''eine Stelle'' im Code geändert werden, wenn die Größe des Arrays einmal einen anderer Wert als 10 haben soll &amp;amp;ndash; dies vermeidet Fehler die dadurch entstehen, wenn man beim Anpassen der Array-Größe eine Codestelle vergisst, zudem wird der Code lesbarer als wenn irgendwo die Zahl &amp;quot;10&amp;quot; auftaucht.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
:Wird ein ungültiger Index angeben (einer, der in der Deklaration nicht enthalten ist) können  undefinierte Dinge passieren, wenn dadurch andere Variableninhalte oder Programmcode überschrieben wird, der hinter oder vor dem Array im Speicher liegt. Schlimmstenfalls kann sogar der Computer/Controller abstürzen. Also darauf achten, daß keine ungültigen Werte als Index auftreten!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Strings (Zeichenketten)===&lt;br /&gt;
Ein String ist nichts anderes als ein Array, das aus einzelnen Zeichen (&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;) gebildet wird. Die Ausgabe auf dem Bildschirm funktioniert am einfachsten mittels Strings.&lt;br /&gt;
&lt;br /&gt;
Die Definition eines Strings erfolgt also genauso wie bei Arrays:&lt;br /&gt;
 char string[21];&lt;br /&gt;
&lt;br /&gt;
Nun haben Sie eine String, in dem Sie 21 Zeichen speichern können. Ganz richtig ist das jedoch nicht. C arbeitet mit &amp;quot;null-terminierten Strings&amp;quot;. Das beudeutet, dass die Länge des Strings nicht abgespeichert wird, sondern das Zeichen mit dem ASCII-Wert 0 das Stringende kennzeichnet. Daher auch die Bezeichnung  &amp;quot;null terminiert&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Das letzte Zeichen eines Strings muß daher immer das ASCII-Zeichen Nr. 0 sein. Ist es das nicht, hat der String kein definiertes Ende, und wenn Sie versuchen, ihn durch eine Standard-Funktion auszugeben zu lassen, könnte es eine Weile dauern, bis sich im Speicher zufällig irgendwo eine 0 befindet. Es stehen ihnen daher bei dem Beispiel nur 20 Zeichen zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
===Mehrdimensionale Arrays===&lt;br /&gt;
Manchmal benötigt man mehr als nur ein eindimensionales Array, wie Sie es bisher kennengelernt haben. Auch dies ist kein Problem. In der Deklaration geben Sie einfach mehrere eckige Klammern hintereinander an. Aber Vorsicht: der Speicherplatz ist begrenzt, ein &amp;quot;&amp;lt;tt&amp;gt;char feld[1024][1024]&amp;lt;/tt&amp;gt;&amp;quot; hat die Speicherplatzgrenzen vermutlich bereits weit überschritten, und der Compiler wird einen (bei gewissen Einstellung auch keinen) Fehler liefern.&lt;br /&gt;
Beim Zugriff auf mehrdimensionale Felder müssen auch mehrere Indizes angeben werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  int x,y;&lt;br /&gt;
  int feld[3][5];&lt;br /&gt;
 &lt;br /&gt;
  for (x=0; x&amp;lt;3; x++) &lt;br /&gt;
  {&lt;br /&gt;
     for (y=0; y&amp;lt;5; y++)&lt;br /&gt;
     {&lt;br /&gt;
       printf (&amp;quot;Feldwert x: %d,  y: %d &amp;quot;, x, y);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; feld[x][y]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  for(x=0; x&amp;lt;3; x++) &lt;br /&gt;
     for (y=0; y&amp;lt;5; y++) &lt;br /&gt;
        printf (&amp;quot;Wert: feld[%d][%d] = %d\n&amp;quot;, x, y, feld[x][y]);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 3 mal 5 &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array angelegt. &lt;br /&gt;
Dann werden die Werte eingegeben: zuerst &amp;lt;tt&amp;gt;feld[0][0]&amp;lt;/tt&amp;gt;, dann &amp;lt;tt&amp;gt;feld[0][1]&amp;lt;/tt&amp;gt;, usw. bis &amp;lt;tt&amp;gt;feld[2][4]&amp;lt;/tt&amp;gt;. &lt;br /&gt;
Zum Schluß werden alle Werte noch einmal ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===Strukturen===&lt;br /&gt;
In C können Sie sogenannte &amp;quot;Strukturen&amp;quot; definieren. Dabei handelt es sich um eine Zusammenfassung mehrerer Datentypen zu einem größeren. Im Unterschied zu Feldern können in Strukturen unterschiedliche Datentypen zusammengestellt und gespeichert werden: &lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 struct {{Bezeichner}}&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur 'Person'}}&lt;br /&gt;
 struct Person &lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;lt;tt&amp;gt;struct Person {&amp;lt;/tt&amp;gt;&amp;quot; leitet die Definition der Struktur mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;Person&amp;lt;/tt&amp;gt;&amp;quot; ein. &lt;br /&gt;
Dann werden in dieser Struktur fünf Komponenten definiert: drei Strings und zwei &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. &lt;br /&gt;
mit &amp;lt;tt&amp;gt;}&amp;lt;/tt&amp;gt; wird die Definition abgeschlossen. Sie haben damit einen Datentyp erstellt. Um eine Variable des Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach an&lt;br /&gt;
 struct Person {{Bezeichner}};&lt;br /&gt;
&lt;br /&gt;
Zum Zugriff auf eine Komponente der Struktur gibt man den Namen der Struktur-Variablen an (im folgenden Beispiel also &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;klaus&amp;lt;/tt&amp;gt;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
 {{comment|Definition zweier Struktur-Variablen}}&lt;br /&gt;
 struct Person hubert, klaus;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Zugriff auf Struktur-Komponenten}}&lt;br /&gt;
 hubert.alter = 32;&lt;br /&gt;
 klaus.alter = hubert.alter + 1;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis:'''&lt;br /&gt;
Der eventuell etwas lästige Gebrauch von &amp;lt;tt&amp;gt;struct&amp;lt;/tt&amp;gt; kann schon bei der Definition der Struktur vermieden werden.&lt;br /&gt;
Der Definition ist ein &amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt; voranzustellen. Der Definition folgt dann ein gültiger (und auch eindeutiger) C-Name.&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 typedef struct {{Bezeichner}}&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 } {{Bezeichner}} ;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur '_Mensch' bzw. 'Mensch'}}&lt;br /&gt;
 struct _Mensch&lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 } Mensch;&lt;br /&gt;
&lt;br /&gt;
Jetzt sind folgende Deklarationen identisch:&lt;br /&gt;
 struct _Mensch {{Bezeichner}};&lt;br /&gt;
 Mensch {{Bezeichner}};&lt;br /&gt;
&lt;br /&gt;
Ist der Struktuname nicht notwendig (im Beispiel oben &amp;lt;tt&amp;gt;_Mensch&amp;lt;/tt&amp;gt;), kann auch kürzer geschrieben werden:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 typedef struct &lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 } {{Bezeichner}} ;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur 'Mensch'}}&lt;br /&gt;
 struct &lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 } Mensch;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall ist lediglich die {{Deklaration}} &amp;lt;tt&amp;gt;Mensch {{Bezeichner}};&amp;lt;/tt&amp;gt; gültig.&lt;br /&gt;
&lt;br /&gt;
Der Hinweis gilt sinngemäß auch für die Definition &amp;lt;tt&amp;gt;union&amp;lt;/tt&amp;gt; im nachfolgenden Abschnitt.&lt;br /&gt;
&lt;br /&gt;
===Unions===&lt;br /&gt;
Eine Union wird ganz analog zu einer Struktur deklariert und verwendet. Sie unterscheidet sich von einer Struktur jedoch dadurch, daß ihre Elemente nicht nacheinander im Speicher abgelegt werden, sondern sich überlagern. Auf die in einer Union enthaltenen Daten gibt es also verschiedene Sichten: je nachdem, welche Sicht bzw. Interpretation der Daten man gerne hätte, wählt man den gewünschten Zugriff.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
union Daten &lt;br /&gt;
{&lt;br /&gt;
   int id;&lt;br /&gt;
&lt;br /&gt;
   struct Person u_person;&lt;br /&gt;
&lt;br /&gt;
   struct u_double&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      double wert;&lt;br /&gt;
   };&lt;br /&gt;
&lt;br /&gt;
   struct u_pointer&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      union Daten * p1;&lt;br /&gt;
      union Daten * p2;&lt;br /&gt;
   };&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
union Daten data;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies definiert eine Union mit den vier Zugriffsmöglichkeiten &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_double&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Größe der Union richtet sich dabei nach der grössten Komponente. In diesem Beispiel sind alle Komponenten so angelegt worden, daß sie an erster Stelle ein &amp;lt;tt&amp;gt;int id&amp;lt;/tt&amp;gt; enthalten. In &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; könnte man sich also merken, wie die Daten in der Union zu interpretieren sind. Würde &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; nicht dieses &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; enthalten, so würde sich &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; mit &amp;lt;tt&amp;gt;data.u_person.vname&amp;lt;/tt&amp;gt; überlagern. Ein Ändern der ersten Buchstaben von &amp;lt;tt&amp;gt;vname&amp;lt;/tt&amp;gt; hätte also ein Ändern von &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; zur Folge, und man könnte es nicht mehr als Merker verwenden. Mit diesem Feld überlagert das &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; die &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;-Felder der anderen Sichten, z.B. ist &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; der selbe Zugriff wie auf &amp;lt;tt&amp;gt;data.u_person.id&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein anderes Beispiel ist eine Union, die es ermöglicht, auf die einzelnen Bytes eines &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; zuzugreifen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef union&lt;br /&gt;
{&lt;br /&gt;
   unsigned long  as_long;&lt;br /&gt;
   unsignen short as_short[2];&lt;br /&gt;
   unsignen char  as_byte[4];&lt;br /&gt;
} data32_t;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies überlagert einen &amp;lt;tt&amp;gt;unsigned long&amp;lt;/tt&amp;gt; &amp;amp;ndash; also eine 32-Bit-Zahl &amp;amp;ndash; mit vier Bytes bzw. zwei Shorts.&lt;br /&gt;
 data32_t wert;&lt;br /&gt;
 &lt;br /&gt;
 wert.as_long = 0x12345678;&lt;br /&gt;
 wert.as_byte[0] = 0xab;&lt;br /&gt;
 {{comment|nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform)}}&lt;br /&gt;
&lt;br /&gt;
==Eigene Datentypen==&lt;br /&gt;
&lt;br /&gt;
=Variablen=&lt;br /&gt;
Eine Variable ist ein Synonym (=anderer Name) für eine Speicherstelle in einem Computer. Einfacher gesagt, eine Variable bietet Raum, um Daten wie Zahlen oder Zeichen zu speichern und wieder zu lesen.&lt;br /&gt;
&lt;br /&gt;
==Variablennamen==&lt;br /&gt;
Ein Variablenname kann zusammengesetzt werden aus den Buchstaben &amp;lt;tt&amp;gt;'''A'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''Z'''&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;'''a'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''z'''&amp;lt;/tt&amp;gt;, den Ziffern &amp;lt;tt&amp;gt;'''0'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''9'''&amp;lt;/tt&amp;gt;, sowie dem Sonderzeichen &amp;quot;Unterstrich&amp;quot; (underscore) &amp;lt;tt&amp;gt;'''_'''&amp;lt;/tt&amp;gt;. Dabei darf an erster Stelle keine Ziffer stehen. Die Bezeichner &amp;lt;tt&amp;gt;hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALLO&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALL0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;_123&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_HALLO&amp;lt;/tt&amp;gt; sind also alle gültige und unterschiedliche Variablennamen.&lt;br /&gt;
&lt;br /&gt;
==Anlegen von Variablen==&lt;br /&gt;
Um eine Variable verwenden zu können, muss sie zuerst vereinbart (&amp;quot;erzeugt&amp;quot;) werden. Dies wird auch als &amp;quot;''Definition der Variablen''&amp;quot; bezeichnet und geht so: Schreiben Sie zuerst den Datentyp, dann den Namen der Variablen. Zum Schluß kommt noch der Strichpunkt, wie nach jeder C-Anweisung oder Deklaration. Und nicht vergessen: C unterscheidet zwischen  Groß- und Kleinschreibung! &lt;br /&gt;
 int Zahl1, Zahl2;&lt;br /&gt;
 char Zeichen;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    float gleitZahl;&lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:'''&lt;br /&gt;
In einer Zeile können auch mehrere Variablen gleichen Types vereinbart werden, wenn man ein Komma dazwischen setzt. Variablen können in jedem Block vereinbart werden. Siehe [[#Gültigkeitsbereich|Gültigkeitsbereich]].&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen==&lt;br /&gt;
Man kann einer vereinbarten Variable Werte [[#Zuweisungen|zuweisen]]. Dazu schreibt man zuerst den Variablennamen, ein Gleichheitszeichen &amp;quot;&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;&amp;quot; und anschliessend den zuzuweisenden [[#Ausdrücke|Ausdruck]]. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, zahl2 = 12;&lt;br /&gt;
  char zeichen1 = 'A';&lt;br /&gt;
&lt;br /&gt;
  zahl1 = 52;&lt;br /&gt;
  zeichen1 = zeichen1 + 1; &lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Zuerst werden drei Variablen angelegt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;: wird gleich bei der Vereinbarung der Wert 12 zugewiesen. &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl1 = 52&amp;lt;/tt&amp;gt;: Hier wird der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; der Wert 52 zugewiesen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;: wird um 1 erhöht. Da in der Variablen &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; gespeichert ist, gibt sich ihr neuer Wert aus &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt;. Weil &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; dem Wert 65 entspricht, ist &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt; gleich 66, was dem Wert für &amp;lt;tt&amp;gt;'B'&amp;lt;/tt&amp;gt; entspricht.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei float==&lt;br /&gt;
Das funktioniert genau wie bei normale Zuweisungen. Nachkommastellen werden durch einen Punkt abgegrenzt: &lt;br /&gt;
 floatVariable = 3.14;&lt;br /&gt;
Zusätzlich kann eine Zehnerpotenz angegeben werden:&lt;br /&gt;
 floatVariable2 = -1.234E-6;&lt;br /&gt;
Dadurch wird der erst Wert mit 10&amp;lt;sup&amp;gt;&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;6&amp;lt;/sup&amp;gt; multipliziert, der Wert der Variablen ist also &lt;br /&gt;
:&amp;lt;math&amp;gt;-1{,}234\cdot10^{-6} = -0.000001234&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei logischen Variablen==&lt;br /&gt;
Wie bereits erwähnt, besitzt C keinen logischen Datentyp. Es müssen also &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; dafür genutzt werden. Die Zuweisung entpricht der Standard-Zuweisung. Wird der Wert 0 zugewiesen, dann ist die Variable &amp;quot;unwahr&amp;quot;, ansonsten ist sie &amp;quot;wahr&amp;quot;. &lt;br /&gt;
 intVariable = !0;   /* entspricht &amp;quot;wahr&amp;quot;   */&lt;br /&gt;
 intVariable = 0;    /* entspricht &amp;quot;unwahr&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
==Konstanten==&lt;br /&gt;
Konstanten können als Variable angesehen werden, die nicht beschrieben, sondern nur gelesen werden können. Ein typisches Beispiel dafür ist die Zahl &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; (rund 3,141592654). Niemand würde in der realen Welt versuchen, ihr einen anderen Wert zuzuweisen. Würde man &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; jedoch wie eine normale Variable anlegen, wäre dies ohne weiteres möglich. Um dies zu verhindern, gibt es das Schlüsselwort &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in C:&lt;br /&gt;
 const {{Type}} {{Bezeichner}} = {{Konstante}};  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Wichtig dabei ist, dass man Konstanten nur bei der Vereinbarung einen Wert zuweisen kann. &lt;br /&gt;
Da Konstanten gewöhnlich im gesamten Programm, zumindest einer Quelldatei genutzt werden, definiert man diese allerdings gewöhnlich außerhalb des main-Blockes entweder am Anfang eines Programmes, oder in einer sogenannten Header-Datei, die per &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; eingebunden wird.&lt;br /&gt;
 const float PI = 3.141592;  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Es sei jedoch erwähnt, daß auch einer Konstanten nachträglich ein anderer Wert zugewieden werden kann. Im obigen Beispiel könnte mit&lt;br /&gt;
 * ((float*) &amp;amp;PI) = 2;&lt;br /&gt;
der Wert von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; im Nachhinein verändert werden. Es wird die Adresse von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; genommen und diese Adresse durch den Cast in eine ganz normale &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;-Adresse umgewandelt, über welche der Wert geändert wird. Die sei der Vollständigkeit halber erwähnt.&lt;br /&gt;
&lt;br /&gt;
Je nachdem, an welcher Stelle sich das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; bei einer Pointer-Deklaration befindet, markiert es den Pointer als konstant oder das Objekt, auf das dieser Pointer zeigt. Eine häufige Parameterdeklaration in Ausgabe-Funktionen, die einen String erhalten, ist&lt;br /&gt;
 void foo (const char * str, ...);&lt;br /&gt;
Dadurch ist &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; der Zeiger auf eine Zeichenkette, die innerhalt der Funktion nicht verändert wird bzw. verändert werden darf. Eine Zuweisung wie &amp;lt;tt&amp;gt;*str = 'a'&amp;lt;/tt&amp;gt; ergibt also einen Fehler. &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; selbst kann aber sehr wohl verändert werden, etwa mit &amp;lt;tt&amp;gt;str++&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Soll ausgedrückt werden, daß &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; unveränderlich ist, dann so:&lt;br /&gt;
 void foo (char * const str, ...);&lt;br /&gt;
Jetzt wäre eine Änderung des Strings in Ordnung, etwa durch &amp;lt;tt&amp;gt;str[10] = 'a'&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Um sich zu merken, worauf das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; wirkt, trennt man die Deklaration in Gedanken beim&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf: Steht das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; links vom&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, dann gehört es zum &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, steht es rechts davon, dann gehört es zum Pointer. Natürlich ist es auch denkbar, beides &amp;amp;ndash; also den Zeiger und sein Ziel &amp;amp;ndash; als konstant zu markieren.&lt;br /&gt;
&lt;br /&gt;
==Gültigkeitsbereich==&lt;br /&gt;
In C können mehrere Variablen den gleichen Namen haben, solange eindeutig ist, welche in welchen Block gültig ist. Dabei gelten folgende Regeln: &lt;br /&gt;
&lt;br /&gt;
;Lokale Variablen: sind Variablen, die innerhalb eines Blockes definiert werden. Jede Variable ist nur in dem Block gültig, in dem sie vereinbart wurde, sowie in allen darin enthaltenen Blöcken; es sei denn, in einem Unter-Block wird eine Variable gleichen Namens definiert. Dann bezieht sich in diesem Unter-Block der Bezeichner auf die im Unter-Block angelegte Variable.&lt;br /&gt;
;Globale Variablen: werden ausserhalb jedes Blockes definiert und gelten ab der Stelle, an der sie deklariert werden, siehe auch [[#Deklaration und Definition|Deklaration und Definition]]. Wird jedoch in einem Block eine Variable gleichen Namens angelegt, gilt ab hier bis zum Ende des Blocks nicht mehr die globale Variable, sondern die im Block deklarierte. Das Spiel kann man weiterspielen: wird in einem Unter-Block wieder eine namensgleiche Variable angelegt, gilt diese in dem Unterblock.&lt;br /&gt;
&lt;br /&gt;
==Speicherklassen==&lt;br /&gt;
Jede Variable in C gehört zu einer bestimmten Speicherklasse&lt;br /&gt;
;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;: Lokale Variablen sind in aller Regal sogenannte ''automatische Variablen''. Das bedeutet, sie werden automatisch angelegt, wenn ein Block bzw. eine Funktion betreten wird und danach wieder entfernt. Das Schlüsselwort &amp;quot;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;&amp;quot; wird praktisch nie hingeschrieben, denn lokale Variablen ohne die ausdrückliche Angabe einer Speicherklasse, sind automatisch automatische Variablen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;: Eine externes Symbol ist im ganzen Programm bekannt bzw. in dem Block, in der die Deklaration steht. In unterschiedlichen Blöcken stehende Deklarationen beziehen sich auf das gleiche Symbol! Obgleich das Datum global zugreifbar ist, ist der Gültigkeitsbereich auf den deklarierenden Block begrenzt bzw. auf das deklarierende Quell-Modul, sofern das Symbol ausserhalb jedes Blocks des Moduls deklariert wird. Siehe auch [[#Deklaration und Definition|Deklaration und Definition]].&lt;br /&gt;
;&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;: Die Variable ist im Block gültig bzw. im Quell-Modul (also in der C-Datei, in der die angelegt wurde), wenn sie nicht innerhalb eines Blockes angelegt wurde. Statische Variablen werden nicht in Registern oder im Frame der Funktion angelegt, sondern im selben Speicherbereich, in dem auch die globalen Variablen liegen; Konstanten evtl. auch im Flash. Eine lokale Variable, die als &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; angelegt wird, &amp;quot;überlebt&amp;quot; also das Verlassen des Blocks und hat beim neuerlichen Betreten des Blockes ihren bisherigen Wert. In unterschiedlichen Blöcken angelegte lokale statische Variablen beziehen sich auf unterschiedliche Speicherstellen, genau wie bei lokalen Variablen auch.&lt;br /&gt;
;&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;: Durch diese Speicherklasse wird eine Variable &amp;amp;ndash; falls möglich &amp;amp;ndash; als Registervariable angelegt, also in einem Maschinenregister des Computer/Controllers gehalten. Dadurch kann auf solche Variablen besonders schnell zugegriffen werden. Dieses Schlüsselwort ist bei modernen Compilern weitgehend überflüssig, da die entsprechenden Optimierungen selbständig vorgenommen werden, wenn ausreichend Register vorhanden sind. Auch globale Variablen können als Register angelegt werden, davon ist dem Anfänger aber dringend abzuraten, weil leicht schwerauffindbare Fehler und Abstürze auftreten, wenn man nicht genau weiss, welche Implikationen in einer solchen Definition stecken!&lt;br /&gt;
;&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;: (FIXME: volatile ist ein Qualifier und keine Speicherklasse) Dies ist das genaue Gegenteil von &amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt; und bewirkt, dass die Variable auf keinen Fall in einem Register zwischengespeichert werden darf, sondern immer aus dem RAM gelesen und ins RAM geschrieben werden soll. &amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt; müssen alle ''globalen'' Variablen markiert werden, die in [[ISR | Interrupt-Handlern]] verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Ausdrücke=&lt;br /&gt;
Eine Variable oder eine Konstante in C stellen einfache Ausdrücke dar.&lt;br /&gt;
Diese elementaren Ausdrücke können durch Operatoren miteinander verknüpft werden und so zu neuen, komplexeren Ausdrücken zusammen gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Einfache Beispiele für Ausdrücke sind also z.B.:&lt;br /&gt;
 1&lt;br /&gt;
 a&lt;br /&gt;
 'a'&lt;br /&gt;
 1 + a&lt;br /&gt;
 a == 1&lt;br /&gt;
&lt;br /&gt;
Auch Funktionen können einen Wert zurückliefern und in Ausdrücken weiter benutzt werden.&lt;br /&gt;
In den folgenden Abschnitten wird gezeigt, welche Operatoren in C vorhanden sind,&lt;br /&gt;
und wei man damit neue Ausdrücke aufbauen kann.&lt;br /&gt;
&lt;br /&gt;
==Lvalues==&lt;br /&gt;
&lt;br /&gt;
Ein Lvalue in C ist ein Ausdruck, dem ein anderer Ausdruck zugewiesen werden kann, dessen Wert also durch eine Zuweisung verändert werden kann.&lt;br /&gt;
das 'L' leitet sich ab von 'left' bwz. 'links' und das 'value' bedeutet Wert: Ein Lvalue ist ein Ausdruck, der auf der linken Seite einer Zuweisung stehen darf. Ein Lvalue ist also immer auch ein gültiger Ausdruck, aber die Umkehrung gilt in alles Regel nicht.&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für einen Lvalue ist eine &amp;quot;normale&amp;quot; Variable, die nicht mit &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; als Konstante markiert ist:&lt;br /&gt;
 a = 1;&lt;br /&gt;
Hingegen ist der Ausdruck &amp;lt;tt&amp;gt;a+1&amp;lt;/tt&amp;gt; kein Lvalue, denn eine Zuweisung wie&lt;br /&gt;
 a+1 = 2;&lt;br /&gt;
die mathematisch durchaus sinnvoll ist, erzeugt einen Compilerfehler, der etwa lauten könnte &amp;quot;illegal lvalue in assignment&amp;quot;:&lt;br /&gt;
&amp;quot;ungültiger Wert in Zuweisung&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Andere Beipiele für Lvalues sind die Komponenten von (nicht-konstanten) [[#Strukturen|Strukturen]] und [[#Unions|Unions]], [[#Arrays|Array]]-Elemente und die Dereferenzierungen von Pointern: Die Konstante&amp;amp;nbsp;4 wird durch den Cast in eine Adresse umgewandelt. Über die Dereferenzierung&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; wird an die Adresse&amp;amp;nbsp;4 im Speicher eine&amp;amp;nbsp;3 geschrieben. Ob das erlaubt bzw. sinnvoll ist, ist abhängig von der jeweiligen Architektur.&lt;br /&gt;
 * ((unsigned int *) 4) = 3;&lt;br /&gt;
Hier ist der gesamte &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;-Ausdruck ein Lvalue&lt;br /&gt;
&lt;br /&gt;
==Logische (boolsche) Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp;amp;&amp;amp;amp; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr oder &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; || gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; || ungleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;= b&amp;lt;/tt&amp;gt; || kleiner oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt; b&amp;lt;/tt&amp;gt; || kleiner als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt;= b&amp;lt;/tt&amp;gt; || glösser oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt; b&amp;lt;/tt&amp;gt; || grösser als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; nicht wahr und vice versa&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine interessante Eigenschaft der Operatoren &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;amp;amp;&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; ist, dass&lt;br /&gt;
sie die Auswertung abbrechen, sobald das Ergebnis feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet. Ein oft anzutreffendes Codestück sieht so aus, dabei sei &amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
  if (p &amp;amp;&amp;amp; *p == 5)&lt;br /&gt;
  {&lt;br /&gt;
     {{comment|mach was}}&lt;br /&gt;
  }&lt;br /&gt;
Zuerst wird in der Bedinung geprüft, ob Zeiger&amp;amp;nbsp;&amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; einen Wert ungleich Null hat, also ob er überhaupt einen gültigen Wert enthält. Es ist weit verbreitete Konvention in C, daß Zeiger, die keinen gültigen Wert haben, die Adresse&amp;amp;nbsp;0 enthalten. '''Nur dann, wenn ein Zeiger nicht ein Null-Pointer ist, darf überhaupt ein Zugriff über ihn erfolgen!'''&lt;br /&gt;
&lt;br /&gt;
==Vergleich von Variablen==&lt;br /&gt;
Skalare Variablen (also ganze Zahlen, Gleitkommazahlen, Zeiger) können miteinander verglichen werden. Dazu gibt es die folgenden Operatoren in C: &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; || ist nicht gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;=&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;=&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das Ergebnis der Auswertung ist eine ganze Zahl. Ist die Bedingung erfüllt, dann ist der Wert ungleich&amp;amp;nbsp;0. Ist die Bedingung nicht erfüllt, dann ist ihr Wert gleich&amp;amp;nbsp;0.&lt;br /&gt;
Meistens wird man diese Operatoren in &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Konstrukten finden wie zum Beispiel&lt;br /&gt;
 if (x &amp;gt;= 10)&lt;br /&gt;
    x = 10;&lt;br /&gt;
oder in Abbruchbedingungen von Schleifen, wie sie weiter unten erklärt werden.&lt;br /&gt;
&lt;br /&gt;
Es ist auch möglich, das Ergebnis der Auswertung in einer &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Variablen zu speichern:&lt;br /&gt;
 int i;&lt;br /&gt;
 int z1, z2;&lt;br /&gt;
 &lt;br /&gt;
 z1 = 5;&lt;br /&gt;
 z2 = 100;&lt;br /&gt;
 i = z1 &amp;lt;= z2;  {{comment|Ein Vergleich. i wird &amp;quot;wahr&amp;quot;, da z1 kleinergleich z2 ist}}&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich&amp;amp;nbsp;0 (&amp;quot;wahr&amp;quot;), wenn &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; kleiner oder gleich &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt; ist. Ist &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; jedoch größer als &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt;, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich&amp;amp;nbsp;0 (&amp;quot;unwahr&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
==Arithmetische Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a + b&amp;lt;/tt&amp;gt; || Summe (Addition)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a - b&amp;lt;/tt&amp;gt; || Differenz (Subtraktion)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a * b&amp;lt;/tt&amp;gt; || Produkt (Multiplikation)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a / b&amp;lt;/tt&amp;gt; || Quotient (Division, evtl. mit Rest)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a % b&amp;lt;/tt&amp;gt; || Rest bei Division (Modulo)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;-a&amp;lt;/tt&amp;gt; || Vorzeichenumkehr (Zweierkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Bit-Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp; b&amp;lt;/tt&amp;gt; || bitweise und (and)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || bitweise oder (or)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a ^ b&amp;lt;/tt&amp;gt; || bitweise exclusiv-oder (xor, exor)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;~a&amp;lt;/tt&amp;gt; || jedes Bit in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; invertieren (not, Einerkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Index-Operator bei Arrays==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a[b]&amp;lt;/tt&amp;gt; || das (b+1)ste Element des Feldes a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Folgendes gilt es bei der Verwendung des Indexoperators zu beachten:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; muss ein [[C-Tutorial#Felder | Feld]] oder [[C-Tutorial#Zeiger | Zeiger]] sein&lt;br /&gt;
# &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; muss ein Integer sein oder ein Datentyp, der sich in einen int umwandeln läßt (z.B. char)&lt;br /&gt;
# Es wird nicht geprüft, ob der Index &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; im Feld &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gültig ist!&lt;br /&gt;
# Der erste Index eines Feldes ist immer 0. Daher ''(b+1)stes Element'' in der Beschreibung&lt;br /&gt;
&lt;br /&gt;
==Komponenten-Auswahl bei Structs und Unions==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a.b&amp;lt;/tt&amp;gt; || Element b der [[C-Tutorial#Strukturen | Struktur]] oder des Unions a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adress-Operator und Dereferenzierung==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&amp;amp;amp;a&amp;lt;/tt&amp;gt; || Speicheradresse der Variablen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;*a&amp;lt;/tt&amp;gt; || Wert, der an der Adresse &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a-&amp;amp;gt;b&amp;lt;/tt&amp;gt; || Wert des Elements &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; der Struktur, deren Adresse in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Adressoperator &amp;amp; kann auf Variablen angewendet werden und&lt;br /&gt;
gibt die Startadresse der Variablen im Speicher zurück.&lt;br /&gt;
&lt;br /&gt;
Handelt es sich bei einer Variable um einen [[C-Tutorial#Zeiger | Zeiger]], so enthält&lt;br /&gt;
sie eine Speicheradresse. Um an den '''Wert''' zu gelangen, der&lt;br /&gt;
an dieser Adresse steht, wird der Operator * vorangestellt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
&lt;br /&gt;
 {{comment|x ist eine Integervariable und hat den Wert 5}}&lt;br /&gt;
 int x = 5;&lt;br /&gt;
     &lt;br /&gt;
 {{comment|z ist ein Zeiger auf eine Integer-Variable und enthaelt somit}}&lt;br /&gt;
 {{comment|die Speicheradresse einer Integer-Variablen}}&lt;br /&gt;
 int *z;       &lt;br /&gt;
  &lt;br /&gt;
 {{comment|Verwendung des Adress-Operators: weist an z die Adresse von x zu}}&lt;br /&gt;
 z = &amp;amp;x;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Verwendung der Dereferenzierung}}&lt;br /&gt;
 {{comment|erhoehe den Wert, der bei Adresse z steht, um eins}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|da z auf x zeigt, hat x jetzt den Wert 6}}&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff auf Struktir- und Union-Elemente eine abkürzende Schreibweise möglich:&lt;br /&gt;
&lt;br /&gt;
Statt &lt;br /&gt;
  (*strukturZeiger).element&lt;br /&gt;
kann geschrieben werden&lt;br /&gt;
  strukturZeiger-&amp;gt;element&lt;br /&gt;
Beide Schreibweisen sind absolut gleichbedeutend, die Klammern bei der ersteren sind notwendig.&lt;br /&gt;
&lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
:Bei der Dereferenzierung durch &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; findet keine Prüfung statt, ob der Zeiger auch auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu einer Änderung '''irgendeiner''' Speicherstelle!&lt;br /&gt;
&lt;br /&gt;
 int *z; {{comment|z ist ein Zeiger auf einen int}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.}}&lt;br /&gt;
 {{comment|z enthaelt irgendeine ungueltige Adresse!!}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|&amp;quot;Erhoehe einen Integer _irgendwo_ im Speicher um 1&amp;quot; -&amp;gt; CRASH !!!}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
&lt;br /&gt;
==Cast-Operator==&lt;br /&gt;
&lt;br /&gt;
Der Cast Operator dient dazu, den Datentyp eines Wertes zu ändern. Dafür wird einfach der neue Datentyp in Klammern vor den Wert geschrieben.&lt;br /&gt;
&lt;br /&gt;
Um zum Beispiel aus einem Float ein Integer zu machen:&lt;br /&gt;
 var  = (int) 5.60;&lt;br /&gt;
Dabei wird der Wert aber auch gerundet, und es findet somit ein Informationsverlust statt.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Umwandeln einer ganzen Zahl in eine Adresse:&lt;br /&gt;
 int * addr;&lt;br /&gt;
 addr = (int*) 0x1234;&lt;br /&gt;
Damit ist &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; an Adresse 0x1234.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
Der Cast-Operator selbst führt ''keine Konvertierung'' von Darstellungen durch, etwa die Umwandlung der ganzen Zahl 123 ein den String &amp;lt;tt&amp;gt;&amp;quot;123&amp;quot;&amp;lt;/tt&amp;gt;, der diese Zahl darstellt! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
  int main(int argc, char ** argv)&lt;br /&gt;
  {&lt;br /&gt;
        char text[] = &amp;quot;5.6&amp;quot;;&lt;br /&gt;
        int zahl = (int) text;&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, zahl);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Anfangsadresse des Strings &amp;lt;tt&amp;gt;&amp;quot;5.6&amp;quot;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Komma-Operator==&lt;br /&gt;
Mit einem &amp;lt;tt&amp;gt;,&amp;lt;/tt&amp;gt; können mehrere Ausdrücke nacheinander ausgewertet werden.&lt;br /&gt;
Die Auswertung erfolgt von links nach rechts.&lt;br /&gt;
&lt;br /&gt;
Solche Konstrukte sieht man manchmal in Abfragen wie&lt;br /&gt;
 FILE  *file;&lt;br /&gt;
 if (file = fopen (&amp;quot;foo.exe&amp;quot;, &amp;quot;r&amp;quot;), file != NULL)&lt;br /&gt;
was erst an &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; einen Wert zuweist und den &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Block nur betritt,&lt;br /&gt;
wenn &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; nicht der Nullpointer ist.&lt;br /&gt;
&lt;br /&gt;
Bequem kann das auch in einer [[#for-Schleife|for-Schleife]] sein, wenn man zwei (oder mehr) Laufvariablen hat oder so:&lt;br /&gt;
 for (i=0, j=0; i &amp;lt; 10; i++, j += 2)&lt;br /&gt;
    &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Zuweisung===&lt;br /&gt;
=== ++ und -- ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; stellen einfachere Schreibweisen dar zum Addieren bzw. Subtrahieren von&amp;amp;nbsp;1.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; (Inkrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo++; &lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo + 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; 3}}&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; (Dekrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo--;&lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo - 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; -1}}&lt;br /&gt;
&lt;br /&gt;
Die beiden Operatoren können sowohl in der Präfix-Schreibweise (vor der Variablen) als auch als Postfix-Schreibweise (hinter der Variablen) notiert werden. &lt;br /&gt;
Der Unterschied liegt darin, dass beim Präfix der Wert zuerst neu berechnet wird und die Variable dann verwendet wird. Beim Postfix wird die Variable zuerst verwendet und erst nach Auswertung des Ausdrucks, in dem sie enthalten ist, neu berechnet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 int ausgabe1, ausgabe2, var1 = 10, var2 = 10;&lt;br /&gt;
 ausgabe1 = 3 * ++var1; {{comment|ausgabe1 &amp;amp;#61; 33; var1 &amp;amp;#61; 11;}}&lt;br /&gt;
 ausgabe2 = 3 * var2++; {{comment|ausgabe2 &amp;amp;#61; 30; var2 &amp;amp;#61; 11;}}&lt;br /&gt;
&lt;br /&gt;
Für Zeiger arbeiten diese Operatoren etwas anders, siehe dazu [[#Zeiger-Arithmetik|Zeiger-Arithmetik]].&lt;br /&gt;
&lt;br /&gt;
===Bedingter Ausdruck===&lt;br /&gt;
 ({{Bedingung}}) ? {{Ausdruck|1}} : {{Ausdruck|2}}&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; erfüllt ist, dann wertet dieser Ausdruck aus zu &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt;. Ist er nicht erfüllt, dann wertet er aus zu &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 x = (x &amp;gt;= 3) ? 0 : x+1;&lt;br /&gt;
Startet man &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; mit dem Wert 0, dann nimmt es bei mehrfacher Anwendung dieser Zeile (z.B. in einer Schleife) nacheinander die folgende Werte an:&lt;br /&gt;
:&amp;lt;tt&amp;gt;1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, ...&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&lt;br /&gt;
Wie auch in der Mathematik gibt es auch in C genaue Regeln über die Abarbeitungsreihenfolge (precedence)&lt;br /&gt;
der Operatoren. Dass sich alle C-Compiler genau an diesen ANSI-Vorschlag halten, ist leider nicht sicher.&lt;br /&gt;
Sicher jedoch ist, dass nicht jeder Programmierer diese Regel jederzeit im Kopf hat. &lt;br /&gt;
Daher ist es sinnvoll, Ausdrücke durch runde Klammern eindeutig zu kennzeichnen. &lt;br /&gt;
Nebenbei stören sich Compiler nicht an überflüssigen Klammerpaaren.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Priorität ||Operator||Assoziativität&lt;br /&gt;
|-&lt;br /&gt;
  &lt;br /&gt;
|&amp;lt;tt&amp;gt;15&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ( ) [ ] -&amp;gt; . &amp;lt;/tt&amp;gt;                      ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;14&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;! ~ ++ -- + - (TYP) * &amp;amp; sizeof &amp;lt;/tt&amp;gt;    ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;13&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; * / % (Rechenoperationen) &amp;lt;/tt&amp;gt;         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;12&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; + - (binär) &amp;lt;/tt&amp;gt;                       ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;11&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;&amp;lt; &amp;gt;&amp;gt; &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;10&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt; &amp;lt;= &amp;gt; &amp;gt;= &amp;lt;/tt&amp;gt;                         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 9&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; == != &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 8&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp; (bit-AND-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 7&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ^ (bit-XOR-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 6&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; (bit-OR-Operator)&amp;lt;/tt&amp;gt;   ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 5&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp;&amp;amp; &amp;lt;/tt&amp;gt;                                ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 4&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; &amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 3&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;? : &amp;lt;/tt&amp;gt;                               ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 2&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; = += -= /= *= %= &amp;gt;&amp;gt;= &amp;lt;&amp;lt;= &amp;amp;= &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;= ^= &amp;lt;/tt&amp;gt; ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 1&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; , (Sequenz-Operator) &amp;lt;/tt&amp;gt;              ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Reihenfolge der Auswertung von Funktionsargumenten ist in der ANSI-Spezifikation nicht angegeben und daher compilerabhängig. Von Konstrukten wie&lt;br /&gt;
 {&lt;br /&gt;
    int i=0;&lt;br /&gt;
    func (i++, i++);&lt;br /&gt;
 }&lt;br /&gt;
ist also dringend abzuraten!&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
Eine Kontrollanweisung ist eine Anweisung, die Einfluss auf den Programmfluss hat. Normalerweise werden Anweisungen so ausgeführt, wie sie in der Quelldatei stehen: Von links nach rechts (falls mehrere Anweisungen in einer Zeile stehen sollten, wovon i.A. abzuraten ist) und von oben nach unten. Mit einer Kontrollanweisung kann dieser lineare Programmfluss durchbrochen werden: Die Codeausführung kann kann abhängig von einer Bedingung gemacht werden (&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;), kann wiederholt werden (Schleife) oder an einer anderen Stelle der Funktion fortgesetzt werden (&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==if-Anweisung==&lt;br /&gt;
Mit Hilfe des if-Befehls kann man Codeteile abhängig davon einer Bedingung ausführen lassen:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
oder mit else-Teil&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 if (x &amp;gt; 100)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;gt; 100 ist: Fehlerausgabe}}&lt;br /&gt;
    printf (&amp;quot;x = %d ist zu gross fuer die Berechnung!\n&amp;quot;, x);&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;lt;&amp;amp;#61; 100 ist: Berechne Summe der Zahlen 1...x}}&lt;br /&gt;
    {{comment|Die lokale Variable x2 lebt nur innerhalb dieses alse-Blocks}}&lt;br /&gt;
    int x2 = x;&lt;br /&gt;
 &lt;br /&gt;
    for (x = 0; x2 &amp;gt; 0; x2--)&lt;br /&gt;
       x += x2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Wenn die Bedingung wahr ist (&amp;lt;tt&amp;gt;x &amp;gt; 100&amp;lt;/tt&amp;gt;), dann wird eine Meldung ausgegeben; danach ist die if-Anweisung beendet. Der else-Block wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung nicht erfüllt (&amp;lt;tt&amp;gt;x &amp;amp;le; 100&amp;lt;/tt&amp;gt;), dann wird gleich zum else-Teil gesprungen, und nach dessen Ausführung der if-Befehl beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Ein häufiger Fehler ist es, statt &amp;lt;tt&amp;gt;if (a &amp;amp;#61;&amp;amp;#61; 23)&amp;lt;/tt&amp;gt; etwas wie &amp;lt;tt&amp;gt;if (a &amp;amp;#61; 23)&amp;lt;/tt&amp;gt; zu schreiben. &lt;br /&gt;
Dann wird allerdings nicht geprüft, ob die Variable&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gleich 23 ist, sondern der Variablen&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wird der Wert 23 zugewiesen. Der Ausdruck &amp;lt;tt&amp;gt;a &amp;amp;#61; 23&amp;lt;/tt&amp;gt; hat den Wert&amp;amp;nbsp;23 und ist damit immer &amp;quot;wahr&amp;quot;! Daher ist diese if-Bedingung immer erfüllt!&lt;br /&gt;
&lt;br /&gt;
Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken sondern bestenfalls eine Warnung. Damit ist dieser Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise &amp;lt;tt&amp;gt;if (23 &amp;amp;#61;&amp;amp;#61; a)&amp;lt;/tt&amp;gt;. Wenn man dort anstatt des Vergleichsoperators '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;amp;#61;&amp;lt;/tt&amp;gt;' den Zuweisungsoperator '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;lt;/tt&amp;gt;' verwendet, spuckt der Compiler sehr wohl einen Fehler aus! Ist die Zuweisung jedoch erwünscht und eine Compiler-Warnung lästig, dann wählt man eine Schreibweise wie &amp;lt;tt&amp;gt;if ((a &amp;amp;#61; b))&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;if (a &amp;amp;#61; b, a)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist zu schreiben &amp;lt;tt&amp;gt;if (Bedingung);&amp;lt;/tt&amp;gt; Richtig muss es heissen &amp;quot;&amp;lt;tt&amp;gt;if(Bedingung)&amp;lt;/tt&amp;gt;&amp;quot; Das Semikolon im ersten Fall ist eine leere Anweisung, die im if-Falle ausgeführt wird &amp;amp;ndash; sie bleibt also ohne Resultet. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt; ein auf das Semikolon folgende Anweisung die eigentlich zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören soll wird immer ausgeführt, die sie nicht mehr zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; dazu gehört.&lt;br /&gt;
}}&lt;br /&gt;
Bei verschachtelten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Konstrukten gehört ein &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zu letzten &amp;quot;freien&amp;quot; &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;. Soll in einer &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Folge das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zum ersten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören, dann ist das so zu hinzuschreiben:&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Ohne die geschweiften Klammern um das zweite &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehörte das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; dort hinzu.&lt;br /&gt;
&lt;br /&gt;
==switch-Anweisung==&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
&lt;br /&gt;
 switch ({{Ausdruck|}}) &lt;br /&gt;
 {&lt;br /&gt;
     case konstante1:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
    &lt;br /&gt;
     case konstante2:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 &lt;br /&gt;
     {{comment|weitere case-Marken}}&lt;br /&gt;
 &lt;br /&gt;
     default:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 } {{comment|Ende von switch}} &lt;br /&gt;
&lt;br /&gt;
Der Ausdruck muss ein skalarer Typ sein, er wird in die nächste ganze Zahl gewandelt und mit den Werten hinter den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Marken verglichen. Bei einer Übereinstimmung werden alle Befehle ab dem zutreffenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; ausgeführt. Stimmt der Ausdruck mit keinem der Werte überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt falls vorhanden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der nachfolgenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;- und des &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitts werden ausgeführt, wenn die Anweisungen des &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitts nicht mit dem Befehl &amp;lt;tt&amp;gt;break;&amp;lt;/tt&amp;gt; beendet werden!&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es dürfen beliebig viele &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitte angegeben werden, pro Vergleichswert jedoch nur einer.&lt;br /&gt;
Der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ist optional. Die Reihenfolge, in der &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt; angegeben werden, ist unerheblich.&lt;br /&gt;
&lt;br /&gt;
==Schleifen==&lt;br /&gt;
Um Anweisungen mehrmals hintereinander auszuführen, benötigt man Schleifen. Diese führen Anweisungen aus, bis oder solange Bedingungen erfüllt sind.&amp;lt;br&amp;gt; &lt;br /&gt;
Wichtig ist also, ob die Bedingung '''vor''' oder '''nach''' den Schleifen-Anweisungen geprüft wird. &lt;br /&gt;
&lt;br /&gt;
===while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 while ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Die while-Schleife wird solange durchlaufen, wie die Bedingung erfüllt ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Die Anweisung kann natürlich auch ein Block sein, der aus mehreren Deklarationen und Anweisungen besteht. &lt;br /&gt;
&lt;br /&gt;
 int zahl1 = 0;&lt;br /&gt;
 int zahl2 = 1;&lt;br /&gt;
 &lt;br /&gt;
 while (zahl1 &amp;lt; 3)&lt;br /&gt;
 {&lt;br /&gt;
    zahl1 = zahl1 + 1;&lt;br /&gt;
    zahl2 = zahl2 * 2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife drei mal durchlaufen. Zu Beginn des vierten Durchlaufs ist die Bedingung nicht mehr erfüllt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
&lt;br /&gt;
===do-while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
Die do-while-Schleife wird auf jeden Fall einmal durchlaufen und dann solange wiederholt, wie die Bedingung erfüllt ist.&lt;br /&gt;
 int i = 2;&lt;br /&gt;
 &lt;br /&gt;
 do &lt;br /&gt;
 {&lt;br /&gt;
     i = i*i;   {{comment|i quadrieren}}&lt;br /&gt;
     printf (&amp;quot;i = %d\n&amp;quot;, i);&lt;br /&gt;
 }&lt;br /&gt;
 while (i &amp;lt; 20);&lt;br /&gt;
&lt;br /&gt;
Die Schleife wird durchlaufen und wiederholt, solange &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; kleiner als 20 ist. Es werden also nacheinander die Werte 2, 4 und 16 ausgegeben. Nach der Schleife hat&amp;amp;nbsp;&amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; den Wert 256.&lt;br /&gt;
&lt;br /&gt;
===for-Schleife===&lt;br /&gt;
'''Syntax:''' &lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Bei den Ausdrücken wird es sich um einen Ausdrücke mit Nebeneffekt handeln wie etwa &amp;lt;tt&amp;gt;i=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;i=i+2&amp;lt;/tt&amp;gt;. Es werden folgende Aktionen ausgeführt:&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# falls die Bedingung wahr ist, dann führe &amp;lt;tt&amp;gt;Anweisung&amp;lt;/tt&amp;gt; aus.&lt;br /&gt;
# falls die Bedingung unwahr ist, dann sprinte zu 7 (Ende).&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# gehe zu 2&lt;br /&gt;
# nächste Anweisung nach der for-Schleife&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int lauf, summe;&lt;br /&gt;
 &lt;br /&gt;
 for (lauf=1, summe=0; lauf &amp;lt;= 10; lauf += 2) &lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel ist &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; ein [[#Komma-Operator|Komma-Ausdruck]], der zwei Anweisungen kombiniert und daher sogar zwei Nebeneffente hat: er setzt &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;1 und &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;0.&lt;br /&gt;
&lt;br /&gt;
Das Äquivalent als while-Schleife:&lt;br /&gt;
&lt;br /&gt;
 int lauf  = 1;                 {{comment|Anfangswerte}}&lt;br /&gt;
 int summe = 0;&lt;br /&gt;
 &lt;br /&gt;
 while (lauf &amp;lt;= 10)             {{comment|Bedingung}}&lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
    lauf  += 2;                 {{comment|Inkrement}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; in jedem Schleifendurchlauf um die Laufvariable &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; erhöht. Da &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nacheinander die ungeraden Werte von&amp;amp;nbsp;1 bis&amp;amp;nbsp;10 annimmt, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von&amp;amp;nbsp;1 bis kleinergleich 10 gespeichert, also der Wert&amp;amp;nbsp;25. &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; hat nach der Schleife den Wert&amp;amp;nbsp;11.&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf = 1&amp;lt;/tt&amp;gt; bedeutet, dass der Variablen &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; vor dem ersten Schleifendurchlauf der Wert&amp;amp;nbsp;1 zugewiesen wird. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf &amp;lt;= 10&amp;lt;/tt&amp;gt; ist die Schleifenbedingung; ist sie nicht erfüllt, wird die Schleife beendet. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf += 2&amp;lt;/tt&amp;gt; bedeutet, dass &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nach jedem Durchlauf um&amp;amp;nbsp;2 erhöht wird.&lt;br /&gt;
&lt;br /&gt;
===continue-Anweisung===&lt;br /&gt;
Innerhalb einer Schleife darf die &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die nachfolgenden Anweisungen übersprungen werden und mit dem nächsten Schleifendurchlauf fortgesetzt wird &amp;amp;ndash; vorausgesetzt die Schleifenbedingung ist noch erfüllt. Ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; etc. stehen, wenn dieses innerhalb einer Schleife steht.&lt;br /&gt;
&lt;br /&gt;
==break-Anweisung==&lt;br /&gt;
Innerhalb einer Schleife oder eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; darf die &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die Schleifen-/Switch-Anweisung sofort verlassen wird und das Programm dahinter weiter macht. Bei mehrfach geschachtelten Schleifen wird nur die innere verlassen. Ein &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; stehen, wenn dieses innerhalb einer Schleife/Switch-Anweisung steht.&lt;br /&gt;
&lt;br /&gt;
==goto-Anweisung==&lt;br /&gt;
&lt;br /&gt;
Innerhalb ein und derselben Funktion kann mit &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; an eine andere Stelle gesprungen werden. Dazu gibt man hinter dem &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einen Bezeichner an, der dadurch als Label fungiert:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 goto {{Bezeichner}};&lt;br /&gt;
Die Bezeichner selbst steht irgendwo in der Funktion und wird dadurch zur Sprungmarke (Label), daß er von einem Doppelpunkt (und mindestens einer C-Anweisung, die auch leer sein darf) gefolgt wird.&lt;br /&gt;
&lt;br /&gt;
Das Beispiel durchsucht das 2-dimensionale &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array &amp;lt;tt&amp;gt;feld&amp;lt;/tt&amp;gt; mit den &amp;lt;tt&amp;gt;SIZE_X &amp;amp;times; SIZE_Y&amp;lt;/tt&amp;gt; Werten nach dem Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;. Wird er gefunden, dann wird die 2-fach geschachtelte Suchschleife verlassen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int x, y;&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y; y++)&lt;br /&gt;
       if (feld[x][y] == 0)&lt;br /&gt;
          goto done;&lt;br /&gt;
 {{Label|done:}};&lt;br /&gt;
&lt;br /&gt;
Der folgende Code hat die gleiche Funktion, arbeitet jedoch ohne &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int x, y;&lt;br /&gt;
 int found = 0; {{comment|FALSE}}&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X &amp;amp;&amp;amp; !found; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y &amp;amp;&amp;amp; !found; y++)&lt;br /&gt;
       found = (0 == feld[x][y]);&lt;br /&gt;
Der Nachteil der &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-losen Variante ist, daß man eine Variable, die merkt, ob das Suchziel gefunden wurde, mitschleppen und in ''jedem'' Schleifendurchlauf abtesten muss. Dies bedeutet einen höheren Programmier- und Laufzeitaufwand und ist nicht so klar formuliert wie das &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-Beispiel.&lt;br /&gt;
&lt;br /&gt;
Gleichwohl sei angemerkt, daß die Verwendung von &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einem gewissen Dogmatismus unterliegt, der sich wie folgt subsummieren liesse:&lt;br /&gt;
:''goto ist böse und sollte keinesfalls verwendet werden! Wer es dennoch tut, offenbart dadurch seinen schlechten Geschmach sowie mangelhafte C-Kenntnis.'' &amp;lt;div align=&amp;quot;right&amp;quot;&amp;gt;http://www.roboternetz.de/phpBB2/images/smiles/icon_wink.gif&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Funktionen=&lt;br /&gt;
Stellen Dir vor, Du hast eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben &amp;amp;ndash; was Dich Zeit beim Erstellen des Programms und Speicherplatz im ausführbaren Programm kostet &amp;amp;ndash; kannst Du den Code-Abschnitt in eine Funktion schreiben und diese von jeder Stelle des Programms aus verwenden. Die Hauptgründe, um Funktionen zu verwenden, sind:&lt;br /&gt;
;Wiederverwendung von Code: Mehrfach verwendete Codestücke müssen nicht mehrfach implementiert werden. Oft unterscheiden sich die Codesequenzen nur in Kleinigkeiten, die man der Funktion über Parameter mitteilen kann.&lt;br /&gt;
;Übersichtlichkeit: Ein gut gegliedertes C-Programm implementiert klar umrissene Aufgaben in einer Funktion, auch wenn diese Funktion nur einmal im Code aufgerufen wird! Dadurch bleibt der Code um die Aufrufstelle besser verständlich, und man kann auf verschiedenen &amp;quot;Ebenen&amp;quot; denken. Eine Funktion wie &amp;quot;Datei öffnen&amp;quot; kann recht komplex sein. Auf höherer Ebene interessieren die Innereien nicht mehr, man möchte sich um andere Dinge kümmern und will den Code an der Stelle garnicht sehen...&lt;br /&gt;
;Rekursive Funktionen: Eine Funktion kann sich auch selbst aufrufen. In dem Falle nennt man die Funktion ''rekursiv''. Zwar lässt sich das, was eine rekursive Funktion tut, auch mit anderen Mitteln formulieren, die keine rekursiven Funktionen brauchen, aber oft ist der rekursive Weg knackiger und klarer formulierbar als eine nicht-rekursiven Ansatz, auch wenn es etwas mehr Resourcen verbraucht.&lt;br /&gt;
;Modulare Programmierung: Funktionen können anhand ihres Aufgabenbereichs auf verschiedene C-Quellen &amp;amp;ndash; sogenannte ''Module'' &amp;amp;ndash; verteilt werden. Funktionen, die etwas mit dem USB-Bus anstellen, werden in einem anderen Modul sein als mathematische Funktionen. Dies erhöht die Übersichtlichkeit und vereinfacht die Entwicklung im Team.&lt;br /&gt;
;Bibliotheken: Standard-Funktionen wie das hier oft auftauchende &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; sind in Bibliotheken gespeichert. Wenn das eigene Programm übersetzt wird, dann müssen nicht mehr alle Standard-Funktionen übersetzt werden, sondern werden nur noch aus der Bibliothek gelesen und ihr Code zum Programm dazugelinkt. Die Bibliotheks-Funktionen wurden schon zu einem früheren Zeitpunkt compiliert und liegen in dieser compilerten Form in der Bibliothek. Das spart mächtig Entwicklungszeit. Man kann auch selbst solche Bibliotheken erstellen und in diversen Projekten wiederverwenden.&lt;br /&gt;
;Generische Programmierung: In C ist es möglich, einer Funktion eine andere Funktion zu übergeben. (Damit ist nicht gemeint, ihr deren ''Rückgabewert'' zu übergeben (was auch ginge), sondern ''die Funktion selbst'' wird als Parameter übergeben und kann aufgerufen werden.) Ein typisches Beispiel dafür sind Sortieralgorithmen. Einem Sortieralgorithmus kann es egal sein, ''was'' er sortiert. Er muss lediglich wissen, ''wie'' er das Zeug zu sortieren hat: aufsteigend, absteigend, als Zahl, in lexikographischer Ordnung, nach der Quersumme, Körper nach Oberfläche, Durchmesser, Gewicht oder Volumen... Diese Vergleichsfunktion, die für zwei Objekte entscheidet, welches davon &amp;quot;kleiner&amp;quot; ist, kann man dem Sortierer übergeben. Will er zwei Werte vergleichen, dann muss er nur die Vergleichsfunktion aufrufen, ohne zu wissen, was diese tut. Damit kann der Sortieralgorithmus unanhängig von den Objekten gehalten werden, mit denen er hantieren soll.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Definition==&lt;br /&gt;
&lt;br /&gt;
In der ''Definition'' der Funktion wird gesagt, welche Werte sie liefern kann, wie sie heisst (Bezeichner) und wieviele und welche Parameter sie hat. Danach folgt ihre Implementierung:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}} ({{Parameterliste}})&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 &lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
Für Funktionen, die keinen Wert zurückliefern, gibt es den speziellen Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der besagt, daß die Funktion nichts zurückgibt. Die einfachste denkbare Funktion ist eine solch void-Funktion. Sie bekommt keine Parameter, gibt nicht zurück und ihr Body ist leer:&lt;br /&gt;
 void dummy()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==return-Anweisung==&lt;br /&gt;
An jeder Stelle des Programmflusses einer Funktion kann diese mit &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; beendet werden.&lt;br /&gt;
&lt;br /&gt;
'''bei void-Funktionen:'''&lt;br /&gt;
 return;&lt;br /&gt;
'''Funktionen mit Rückgabe-Wert:'''&lt;br /&gt;
 return {{Ausdruck|}};&lt;br /&gt;
Die zweite Variante gibt an, welcher Wert zurückgegeben wird.&lt;br /&gt;
 int main (int argc, char * argv[])&lt;br /&gt;
 {&lt;br /&gt;
    if (argc &amp;lt; 2)&lt;br /&gt;
       return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
Falls die letzte Anweisung einer void-Funktion ein &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; ist, kann es auch weggelassen werden wie oben bei der Funktion &amp;lt;tt&amp;gt;dummy&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Aufruf==&lt;br /&gt;
Um die Funktion aufzurufen gibt man ihren Namen an, gefolgt von den durch Komma getrennten Argumenten in runden Klammern wie im Beispiel unten das&lt;br /&gt;
 quadrat (5) &lt;br /&gt;
Da &amp;lt;tt&amp;gt;quadrat&amp;lt;/tt&amp;gt; einen Wert liefert, kann man damit weiter rechnen wie mit einem normalen Ausdruck:&lt;br /&gt;
 if (quadrat (a) + quadrat (b) == quadrat (c))&lt;br /&gt;
    c = quadrat (quadrat (a)); {{comment|c &amp;amp;#61; a hoch 4}}&lt;br /&gt;
&lt;br /&gt;
;Ein Hinweis am Rande: Der Name einer Funktion ohne die beiden runden Klammern ist der Pointer/Zeiger auf ihren Anfang. Damit kann ein Funktionsname überall dort verwendet werden, wo Pointer/Zeiger zulässig sind. Insbesondere kann er als Argument einer weiteren Funktion dienen. Siehe auch [[#Zeiger auf Funktionen|Zeiger auf Funktionen]].&lt;br /&gt;
&lt;br /&gt;
==Rekursive Funktionen==&lt;br /&gt;
Eine Funktion die sich selbst &amp;amp;ndash; möglicheweise auch über andere Zwischenfunktionen &amp;amp;ndash; wieder selbst aufruft, wird als ''rekursive Funktion'' bezeichnet. In der Definition ist nichts besonderes zu beachten. Ist die Verschachtelungstiefe im laufenden Programm zu tief, dann gibt das natürlich Probleme, aber das gilt bei tief verschachtelten 'normalen' Funktionen abenso...&lt;br /&gt;
&lt;br /&gt;
Das Beispiel berechnet den Größten Gemeinsamen Teiler zweier Zahlen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int ggT (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
     if (0 == a)&lt;br /&gt;
        return b;&lt;br /&gt;
 &lt;br /&gt;
    return ggT (b % a, a);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Ein komplettes kleines Programm:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int quadrat (int param1)&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  zahl = param1 * param1;&lt;br /&gt;
  return zahl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl, ergebnis;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Bitte Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = quadrat (zahl);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, zahl, ergebnis);&lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, 5, quadrat (5));&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur ausserhalb von Blöcken. Geschachtelte Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen beim Aufruf die Klammern angeben werden:&lt;br /&gt;
 dummy();&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Prototypen==&lt;br /&gt;
Wie oben erwähnt, kann ein Unterprogramm an jeder beliebigen Stelle im Programm stehen. Damit ist jedoch eine Bedingung verknüpft: Das Unterprogramm muß in der Datei oberhalb des ersten Aufrufes definiert worden sein. Wenn Sie ein Unterprogramm in Zeile 10 zum ersten mal aufrufen, müssen Sie die Deklaration davor erledigt haben. Verstanden?&lt;br /&gt;
Um dies zu erreichen, gibt es zwei Möglichkeiten: &lt;br /&gt;
&lt;br /&gt;
Entweder Sie schreiben alle Unterprogramme vor &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; in die Datei. Dies muß jedoch wiederum so geschehen, dass Funktionen zum Zeitpunkt ihres Aufrufes bereits bekannt sind! &lt;br /&gt;
Wo dies nicht möglich ist (z.B. sich gegenseitig aufrufende Unterprogramme), oder wenn Sie das stört, müssen Sie Prototypen verwenden. &lt;br /&gt;
Wie definiert man nun Prototypen? Sie kopieren einfach die erste Zeile des Unterprogrammes (z.B. &amp;quot;&amp;lt;tt&amp;gt;void ausgeben (int zahl)&amp;lt;/tt&amp;gt;&amp;quot;), fügen einen Strichpunkt&amp;amp;nbsp;&amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;an und fügen es an einer geeigneten Stelle ein (so, dass alle Aufrufe später in der Datei kommen). &lt;br /&gt;
Solche Definitionen stehen gewöhnlich am Anfang der Quelldatei oder in einer Header-Datei, die eingebunden wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl);  /* Der Prototyp */&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
   ausgeben (12);&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl)   /* Die eigentliche Prozedur */&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Ausgabe: %d\n&amp;quot;, zahl);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Parameterübergabe==&lt;br /&gt;
&lt;br /&gt;
Alle Werte, die an Prozeduren und Funktionen übergeben werden, werden grundsätzlich '''kopiert'''.&lt;br /&gt;
Das hat folgende Auswirkungen:&lt;br /&gt;
&lt;br /&gt;
# Änderungen an einem Parameter in einer Funktion erscheinen ''nicht'' beim Aufrufer!&lt;br /&gt;
# Möchte man, dass eine Funktion einen Wert trotzdem dauerhaft ändern soll, so muss die Adresse des Wertes via [[#Zeiger|Zeiger]] übergeben werden.&lt;br /&gt;
# Werden [[#Strukturen|Strukturen]] übergeben, so wird von ihnen eine Kopie erstellt, was bei großen Strukturen viel Zeit und Arbeitsspeicher kostet. Deshalb wird häufig nur die Adresse von Strukturen übergeben, da die Adresse viel schneller und platzsparender als die Struktur selbst kopiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele:'''&lt;br /&gt;
 void erhoehe (int x)&lt;br /&gt;
 {&lt;br /&gt;
    x = x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe(a);&lt;br /&gt;
    {{comment|a ist immer noch 0}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Beim Aufruf von &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; wird eine Kopie des Wertes von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; (im Beispiel also 0) erstellt und der Prozedur als Parameter &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; übergeben. Weil dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat dies keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|erhoehe den Wert an der Adresse x um eins}}&lt;br /&gt;
    *x = *x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe (&amp;amp;a);&lt;br /&gt;
    {{comment|a ist jetzt 1}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Jetzt wird im Hauptprogramm mittels [[#Adress-Operator und Dereferenzierung|Adress-Operator]] &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; die Speicheradresse von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; bestimmt. Dann wird eine ''Kopie der Adresse'' an das Unterprogramm &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; übergeben. Jetzt kennt das Unterprogramm die&lt;br /&gt;
Adresse des Originals &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und kann direkt mit dem Inhalts-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&lt;br /&gt;
'''Besonderheit bei Feldern'''&lt;br /&gt;
&lt;br /&gt;
Bei der Übergabe von [[#Felder|Feldern]] gibt es eine Besonderheit. Schreibt man nämlich den Namen eines Feldes, so ist das nichts anderes als die '''Speicheradresse des ersten Elements'''.&lt;br /&gt;
Bei der Übergabe eines Feldes wird also eine Kopie der Startadresse übergeben. Somit kann das Unterprogramm auf den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 void erhoehe (int x[])&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
   int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
   erhoehe (a);&lt;br /&gt;
   {{comment|a hat jetzt folgenden Inhalte: 11, 23, 35}}&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Dass die Übergabe einer Adresse erfolgt, sieht man an folgendem Beispiel, das von der Funktionsweise '''absolut identisch''' mit dem vorhergehenden ist:&lt;br /&gt;
&lt;br /&gt;
 {{comment|Bei Parametern gibt es keinen Unterschied zwischen Zeiger und Feld}}&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
    int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
    erhoehe (a);&lt;br /&gt;
 &lt;br /&gt;
    {{comment|a hat jetzt folgenden Inhalt: 11, 23, 35}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
Die Länge des Feldes wird nicht automatisch übergeben. Dafür ist ggf. ein zusätzlicher Parameter notwendig.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Variable Argumentanzahl==&lt;br /&gt;
== Funktionen indirekt aufrufen ==&lt;br /&gt;
Siehe [[#Zeiger auf Funktionen|Zeiger auf Funktionen]]&lt;br /&gt;
&lt;br /&gt;
=Zeiger II=&lt;br /&gt;
&lt;br /&gt;
Zeiger haben wir bereits weiter oben kennen gelernt. Zeiger sind ein zentrales Konzept in C und sollen hier etwas eingehender behandelt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger-Arithmetik==&lt;br /&gt;
In C kann man den Wert eines Zeigers verändern. Betrachten wir dazu die Funktion &amp;lt;tt&amp;gt;suche_0&amp;lt;/tt&amp;gt;, die einen Zeiger auf einen &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; erhält. Die Funktion soll ab der gegebenen Adresse nach dem ersten long-Wert suchen, der 0 ist, und dessen Adresse zurückgeben:&lt;br /&gt;
 long * suche_0 (long * addr)&lt;br /&gt;
 {&lt;br /&gt;
    while (*addr != 0)&lt;br /&gt;
       addr = addr + 1;&lt;br /&gt;
 &lt;br /&gt;
    return addr;&lt;br /&gt;
 }&lt;br /&gt;
In der Bedingung der while-Schleife wird der Inhalt an der Speicherstelle &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf 0 getestet. Ist der Wert 0, dann wird die Schleife beendet und die Adresse zurückgeliefert. Ist der Wert ungleich 0, dann wird &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf den nächste long gesetzt, &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; also um 4 Bytes weitergezählt. &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ist ja ein Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, und ein &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; ist 4 Bytes lang.&lt;br /&gt;
&lt;br /&gt;
Die Bedeutung von&lt;br /&gt;
 address + n&lt;br /&gt;
ist also, die Adresse um das &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;-fache der Größe des Typs, auf den &amp;lt;tt&amp;gt;address&amp;lt;/tt&amp;gt; zeigt, zu erhöhen. Dabei ist &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; eine ganze Zahl und darf auch negativ sein.&lt;br /&gt;
&lt;br /&gt;
Hier noch ein Beispiel einer Funktion, die nach einer Person mit einer bestimmten ID sucht (für die Definition von &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; siehe [[#Strukturen|Strukturen]]). Der Parameter &amp;lt;tt&amp;gt;person&amp;lt;/tt&amp;gt; ist dabei ein Array von Strukturen. Eine Person mit der gesuchten ID muss existieren, ansonsten hat die Suchfunktion kein definiertes Verhalten.&lt;br /&gt;
 {{comment|Sucht nach einer Person mit der ID person_id}}&lt;br /&gt;
 struct Person * &lt;br /&gt;
 suche_person_id (struct Person * person, int person_id)&lt;br /&gt;
 {&lt;br /&gt;
    while (person-&amp;gt;id != person_id)&lt;br /&gt;
       person++;&lt;br /&gt;
 &lt;br /&gt;
    return person;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:1em; padding:1em; border:solid 2px #FF0040;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- Vorlage:FarbigerRahmen funzt hier net --&amp;gt;&lt;br /&gt;
Beachte, daß es nicht sinnvoll ist, zwei Zeiger zu addieren oder zu multiplizieren. Ausserdem ist das &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt; der Zeiger-Arithmetik nicht kommutativ. Eine Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, der an Adresse 1 im Speicher zeigt, wird man schreiben als&lt;br /&gt;
 (long *) 1&lt;br /&gt;
Addiert man darauf eine ganze Zahl, dann haben die entstehenden Ausdrücke unterschiedliche Werte:&lt;br /&gt;
 (long *) 1 + 2    {{comment|zeigt zu Adresse 9}}&lt;br /&gt;
 (long *) 2 + 1    {{comment|zeigt zu Adresse 6}}&lt;br /&gt;
 (long *) (1 + 2)  {{comment|zeigt zu Adresse 3}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==void-Pointer==&lt;br /&gt;
Eine besondere Art von Zeiger ist der void-Pointer&lt;br /&gt;
 void * addr;&lt;br /&gt;
Ein void-Pointer ist ein &amp;quot;Zeiger auf irgendwas&amp;quot;, dementsprechend kann er nicht dereferenziert werden, Anwenden von &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf einen solchen Zeiger gibt also einen Fehler. Ausserdem ist es nicht möglich, mit einem void-Pointer Zeigerarithmetik zu machen, weil er nicht auf eine definierte Art von Objekt zeigt. Der Vorteil eines void-Pointers ist, daß er jede Art von Zeiger aufnehmen kann.&lt;br /&gt;
&lt;br /&gt;
Dazu betrachten wir die Funktion &amp;lt;tt&amp;gt;send_buf&amp;lt;/tt&amp;gt;, die eine Adresse erhält und ab dieser Adresse &amp;lt;tt&amp;gt;num&amp;lt;/tt&amp;gt; Bytes versenden soll. Wir könnten die Funktion so schreiben:&lt;br /&gt;
 void send_buf (unsigned char * buf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   ...&lt;br /&gt;
Das ist jedoch hässlich, wenn wir damit etwas anderes verschicken wollen als &amp;lt;tt&amp;gt; unsigned char&amp;lt;/tt&amp;gt;, etwa eine Struktur wie &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; (vom Typ &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;):&lt;br /&gt;
 send_buf ((unsigned char*) &amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
Ohne den Cast der Adresse von &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; zu einem Zeiger auf &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt; bekommt man eine Warnung oder gar einen Compilerfehler.&lt;br /&gt;
Dieses Zeiger gecaste ist mühsam und hässlich, es muss bei jedem Aufruf der Funktion explizit hingeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Besser ist es, den ersten Parameter der Funktion als void-Pointer zu definieren und den Cast in der Funktion zu machen:&lt;br /&gt;
 void send_buf (void * vbuf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   unsigned char *buf = (unsigned char*) vbuf;&lt;br /&gt;
   ...&lt;br /&gt;
Durch den Cast in der Funktion kann auf den Inhalt des Zeigers zugegriffen werden. Man muss nur festlegen, ''wie'' man zugreifen will, nämlich als &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Der Aufruf kann jetzt ohne Pointer-Cast erfolgen: &lt;br /&gt;
 send_buf (&amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
&lt;br /&gt;
==Null-Pointer==&lt;br /&gt;
==Zeiger als Parameter==&lt;br /&gt;
Wenn Sie ein Unterprogramm aufrufen, können Sie diesem Parameter übergeben, aber keine Werte zurückgekommen (außer den Funktionswert bei Funktionen). Dies hat einen guten Grund: beim Aufruf werden nicht die aufgerufenen Parameter benutzt, sondern es werden deren Werte in neue Variablen kopiert. Diese Variablen werden am Ende des Unterprogrammes &amp;quot;zerstört&amp;quot;, ohne ihre Werte an die aufrufenden Parameter zu übergeben. Jede Veränderung eines Parameters hat daher keine Auswirkung auf den Parameter.&lt;br /&gt;
&lt;br /&gt;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der C-Compiler legt dann immer noch Kopien an. In dieser Kopie steht aber kein Wert, sondern die Adresse einer Varaiblen. Und auf diese können Sie dann zugreifen. Denken Sie nur an &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; &amp;amp;ndash; da übergeben Sie ja auch die Adresse einer Variablen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void erhoehe (int *zeiger)&lt;br /&gt;
{&lt;br /&gt;
  *zeiger = 1 + *zeiger;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  erhoehe (&amp;amp;zahl);&lt;br /&gt;
  printf (&amp;quot;\nDie erhoehte Zahl lautet: %d\n&amp;quot;, zahl);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Zeiger auf Funktionen==&lt;br /&gt;
&lt;br /&gt;
Stell dir vor, du willst einen Sortieralgorithmus wie Bubble-Sort oder Quick-Sort oder wie sie alle heissen implementieren. Für den Sortieralgorithmus ist eigentlich egal, ''was'' er zu sortieren hat. Ihm ist es egal, ob er Zahlen aufwärts sortieren soll oder Strings in lexikographischer Reihenfolge, ob Objekte nach Größe oder Gewicht, Personen nach Alter oder Adressen nach Postleitzahl. Das einzige, was der Algorithmus wissen muss, ist ''wie'' er zwei Objekte zu vergleichen hat und wann eines davon &amp;quot;kleiner&amp;quot; (im Sinne der Ordnung, nach der sortiert werden soll) ist. &lt;br /&gt;
&lt;br /&gt;
Eine einfache Sortierfunktion, die nur zwei Zahlen sortiert, könnte man also so schreiben: &lt;br /&gt;
 {{comment|Sortiert ein Array von 2 int-Zeigern nach den Inhalten &lt;br /&gt;
  * an den Zeiger-Adressen}}&lt;br /&gt;
 void sort2_a (int * p[])&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Inhalte vergleichen...}}&lt;br /&gt;
    if (*p[0] &amp;gt; *p[1])&lt;br /&gt;
    {&lt;br /&gt;
       {{comment|... und ggf. Dreieckstausch der 2 Zeiger}}&lt;br /&gt;
       int * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Die Funktion bekommt ein Array der Länge&amp;amp;nbsp;2. In diesem Array stehen Zeiger auf die zu sortierenden Zahlen. Ein Array mit Zeigern zu verwenden und nicht ein Array von &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; scheint recht umständlich, und das ist es hier auch. Aber stell dir vor, du willst Strukturen wie &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; sortieren. Das Tauschen zweier Strukturen würde bedeuten, ihre kompletten Inhalte umzukopieren! Das wäre sehr aufwändig. Viel einfacher ist das Kopieren, wenn nur die Adressen zu kopieren sind.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; könnte dann so aussehen:&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void sortiere (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|p[] enthält 2 int-Zeiger: die Adressen von a und b}}&lt;br /&gt;
    int * p[2];&lt;br /&gt;
    p[0] = &amp;amp;a; &lt;br /&gt;
    p[1] = &amp;amp;b; &lt;br /&gt;
 &lt;br /&gt;
    {{comment|Sortiere die Zeiger}} &lt;br /&gt;
    sort2_a (p);&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Sortiert: %d, %d\n&amp;quot;, *p[0], *p[1]);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Für den nächsten Schritt überlegen wir uns, daß das Array in &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; ebensogut void-Pointer enthalten kann. Die einzige Stelle, an der wir auf die endgültigen int-Objekte zugreifen, ist der Vergleich. Diesen Vergleich lagern wir in die Funktion &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; aus:&lt;br /&gt;
 {{comment|Bekommt zwei void-Pointer und vergleicht die Inhalte.&lt;br /&gt;
  * Liefert 0 bei Gleichheit,&lt;br /&gt;
  * -1 wenn der erste Wert kleiner ist als der zweite und&lt;br /&gt;
  * 1  wenn der erste Wert größer ist als der zweite}}&lt;br /&gt;
 int compare_int (void * p0, void * p1)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Um über die Zeiger zugreifen zu können müssen wir diese&lt;br /&gt;
     * erst zu int-Zeigern casten}}&lt;br /&gt;
    int a0 = * (int*) p0;&lt;br /&gt;
    int a1 = * (int*) p1;&lt;br /&gt;
 &lt;br /&gt;
    if (a0 &amp;gt; a1)  return  1;&lt;br /&gt;
    if (a0 &amp;lt; a1)  return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void sort2_b (void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare_int (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Ein Aufruf von &amp;lt;tt&amp;gt;sort2_b&amp;lt;/tt&amp;gt; sieht dann genauso aus wie ein Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt definieren wir uns den neuen Datentyp &amp;lt;tt&amp;gt;comparator_t&amp;lt;/tt&amp;gt;. Dieser ist ein Zeiger auf eine Funktion, die zwei void-Pointer erhält und einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; zurückliefert, also analog arbeitet zu &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; von oben. &lt;br /&gt;
&lt;br /&gt;
Unsere Sortierfunktion bekommt nun neben dem zu sortierenden Zeiger-Array auch eine Vergleichsfunktion &amp;lt;tt&amp;gt;compare&amp;lt;/tt&amp;gt; mitgeliefert, die sie aufruft, wenn sie zwei Objekte vergleichen will&lt;br /&gt;
 {{comment|comparator_t sind Zeiger auf Funktionen, die 2 void-Pointer&lt;br /&gt;
  * erhalten und einen int zurückliefern}}&lt;br /&gt;
 typedef int (*comparator_t) (void*, void*);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Der Sortierer bekommt einen Funktionszeiger auf den Vergleicher.&lt;br /&gt;
  * Der Aufruf vom compare geht so als wäre es eine &amp;quot;normale&amp;quot; Funktion&lt;br /&gt;
  * (ist es im Endeffekt ja auch)}}&lt;br /&gt;
 void sort2_c (comparator_t compare, void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Bei einem Aufruf von &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; muss man dann einen Komparator mit angeben. In einem Beispiel analog zu &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; von oben ist das:&lt;br /&gt;
 sort2_c (compare_int, p);&lt;br /&gt;
Um zwei Strings lexikographisch zu sortieren nehmen wie die Standard-Funktion &amp;lt;tt&amp;gt;strcmp&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void foo()&lt;br /&gt;
 {&lt;br /&gt;
    char * worte[] = { &amp;quot;Wort1&amp;quot;, &amp;quot;Wort2&amp;quot; };&lt;br /&gt;
 &lt;br /&gt;
    sort2_c ((comparator_t) strcmp, (void**) worte);&lt;br /&gt;
 }&lt;br /&gt;
Die Casts sind hier erforderlich. Alternativ könnte man &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; mit reinen void-Pointern versorgen und diese dann dort umcasten.&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
&lt;br /&gt;
Die Syntax zur Definition/Deklaration von Funktionszeigern ist etwas verzwackt. Zur Verdeutlichung ein paar Beispiele. Dabei legt das linke &amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt; jeweils den Return-Typ fest.&lt;br /&gt;
 {{comment|definiert einen neuen Funktionszeiger-Typ}}&lt;br /&gt;
 typedef {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert einen Funktionszeiger}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert ein Array von Funktionszeigern (mit Initializer)}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}[]) ({{type}}, {{type}}, ...) = { wert1, wert2, ... };&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer}}&lt;br /&gt;
 ({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer und ruft die Funktion auf}}&lt;br /&gt;
 (({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}) (arg1, arg2, ...);&lt;br /&gt;
&lt;br /&gt;
=Standard-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==String-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===strcpy===&lt;br /&gt;
Bei vielen Compilern können sie einem String nicht direkt einen Wert (Text) zuweisen. Dazu müssen Sie dann die Prozedur strcpy() benutzen. Diese erwartet als ersten Parameter den Namen einer String-Variablen (ohne eckige Klammern) und als zweiten Parameter den eines (anderen) Strings. Letzterer kann auch ein in doppelten Hochkommas (&amp;quot;) eingeschlossener Text sein. Die Funktion fügt am Ende automatisch ein 0-Zeichen ein. Um diese Funktion nutzen zu können, müssen Sie die Datei string.h includieren! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri1[21], eingabe[21];&lt;br /&gt;
&lt;br /&gt;
  strcpy (stri1, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Der 1. String: %s\n&amp;quot;, stri1);&lt;br /&gt;
  printf (&amp;quot;Bitte geben Sie maximal 20 Zeichen ein: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%s&amp;quot;, eingabe);&lt;br /&gt;
  strcpy (stri1, eingabe);&lt;br /&gt;
  printf (&amp;quot;\n%s = %s&amp;quot;, stri1, eingabe);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis:''' &lt;br /&gt;
Da ein String, wie jedes Feld, eigentlich ein Zeiger ist, dürfen Sie kein &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; bei &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; angeben!&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
Es werden zwei gleich große Strings definiert: &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;eingabe&amp;lt;/tt&amp;gt;, mit je 20 &amp;quot;nutzbaren&amp;quot; Zeichen. &lt;br /&gt;
In &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; wird die Zeichenkette &amp;lt;tt&amp;gt;&amp;quot;hallo&amp;quot;&amp;lt;/tt&amp;gt; hineinkopiert. Das 0-Zeichen am Ende wird automatisch angefügt. &lt;br /&gt;
Der String wird ausgegeben. Als neues &amp;quot;Sonderzeichen&amp;quot; kommt &amp;lt;tt&amp;gt;%s&amp;lt;/tt&amp;gt; ins Spiel. Es hat die gleiche Aufgabe wie &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt;, nur für Strings. &lt;br /&gt;
Sie werden gebeten, eine String einzugeben. &lt;br /&gt;
Dieser String wird danach in die Variable &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; kopiert. &lt;br /&gt;
Beide Strings, die ja nun die gleiche Zeichenkette enthalten, werden ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===strlen===&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;strlen&amp;lt;/tt&amp;gt;, die als Parameter eine String-Variable erwartet, liefert die Länge diese Strings zurück. Sie werden jetzt vermutlich sagen: &amp;quot;Das ist doch klar, wie lang der String ist. Ich habe es ja bei der Deklaratin angegeben&amp;quot;. Das stimmt schon, aber denken Sie noch einmal an die null-terminierten Strings. Das 0-Zeichen steht am Ende des Strings (am Ende der gültigen Zeichenfolge), aber nicht unbedingt am Ende des reservierten Speicherplatzes. Haben Sie eine Variable &amp;quot;char Variable[21];&amp;quot;, und ihr den Wert &amp;quot;hallo&amp;quot; zugewiesen, dann steht das null-Zeichen in Variable[5]. Der &amp;quot;gültige&amp;quot; String ist also 5 Zeichen (0-4) lang. Und genau das (5) würde strlen zurück liefern. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri[21];&lt;br /&gt;
  &lt;br /&gt;
  strcpy (stri, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
  printf (&amp;quot;Der String ist %d Zeichen lang&amp;quot;, strlen (stri));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird vor allem gebraucht, wenn Sie direkt auf den String zugreifen, mittels &amp;lt;tt&amp;gt;stri[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;stri[1]&amp;lt;/tt&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
==Ein- und Ausgabe-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===Bildschirm-Ausgabe===&lt;br /&gt;
Bisher war das Tutorial trotz aller Beispiele reine Theorie. Sie konnten zwar Programme schreiben, aber die Funktion nicht testen. Hier lernen Sie nun, wie Sie etwas am Bildschirm ausgeben.&lt;br /&gt;
&lt;br /&gt;
Die dazu notwendige Funktione heisst &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (das '&amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt;' ist kein Fehler!). Diese Anweisung gibt die ihr übergebenen Parameter auf das Standard-Ausgabegerät aus, in der Regel also auf den Bildschirm. Sie kann beliebig viele Parameter übernehmen. Es müssen jedoch Standard-Datentypen (z.B. &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;...) sein! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
    int zahl1 = 12;&lt;br /&gt;
    char zeichen1 = 'A';&lt;br /&gt;
    &lt;br /&gt;
    printf (&amp;quot;Das ist Text, und er wird als solcher ausgegeben. \n&amp;quot;);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zahl1' ist: %d \n&amp;quot;, zahl1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %c \n&amp;quot;, zeichen1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %d \n&amp;quot;, zeichen1);&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt Text aus. Das Zeichen am Ende (&amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;) bedeutet &amp;quot;New Line&amp;quot;, es bewegt den Cursor an den Anfang der nächsten Zeile. &lt;br /&gt;
&lt;br /&gt;
Der zweite &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt auch Text aus, am Ende befindet sich wieder das &amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;, um einen Zeilenvorschub zu erreichen. Das &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; wird vom Compiler durch den ersten Parameter ersetzt, der nach dem Text angegeben wird. In diesem Fall wird &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; also durch den Wert der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ersetzt. Das &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; im &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; bedeutet &amp;quot;Dezimalzahl&amp;quot;, der Computer gibt also eine ganze Zahl aus. &lt;br /&gt;
&lt;br /&gt;
In der dritten Ausgabe wird ein Zeichen ausgegeben. Diesmal bedeutet &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; &amp;quot;char&amp;quot; (Zeichen). Es wird also &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; durch ein &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt; ersetzt, denn die Variable &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; wird als Character interpretiert. &lt;br /&gt;
&lt;br /&gt;
Die letzte Ausgabe interpretiert den Inhalt von &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; als Zahl, und gibt dager den ASCII-Wert von &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, also 65 aus. Das ist ein typisches Beispiel für das mögliche unterschiedliche Interpretieren einer  Variablen!&lt;br /&gt;
&lt;br /&gt;
===Tastatur-Eingabe===&lt;br /&gt;
&lt;br /&gt;
Um ein &amp;quot;gscheites&amp;quot; Programm schreiben zu können, muß man wissen, wie der Benutzer über die Tastatur Befehle eingeben kann. Die dafür notwendigen Funktionen stelle ich in diesem Kapitel vor.&lt;br /&gt;
Die wichtigste Funktion ist &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt;. Er liest Daten von der Tastatur. Die Syntax entspricht derer von &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int  zahl1;&lt;br /&gt;
char zeichen1;&lt;br /&gt;
&lt;br /&gt;
printf (&amp;quot;Bitte geben Sie eine Zahl ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl1);&lt;br /&gt;
printf (&amp;quot;Geben Sie einen Zeichen ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%c&amp;quot;, &amp;amp;zeichen1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Programm gibt eine Eingabeaufforderung aus. Dann erwartet es vom Benutzer, daß er eine Zahl eingibt, die mit [ENTER] bestätigt wird. Dieser Wert wird in &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; abgespeichert. Danach erfolgt wiederum eine Aufforderung zur Eingabe, diesmal eines einzelnen Zeichens. Dieses kann man nun eingeben und ebenfalls mit [ENTER] bestätigen.&lt;br /&gt;
&lt;br /&gt;
Macht man keine dem Datentyp der erwarteten Variable entsprechende Eingabe, dann bricht das Programm mit einer Fehlermeldung ab (wenn man z.B. &amp;quot;1_T2&amp;quot; eingibt, wenn eine Zahl erwartet wird)!&lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; vor den Parametern ist notwendig. Warum, das erfahren Sie im Kapitel &amp;quot;Unterprogramme&amp;quot;. Für die Profis eine Kurz-Erklärung: Das Unterprogramm &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; bekommt zwar einen Wert übergeben, kann aber keinen zurückliefern (&amp;quot;call by value&amp;quot;). Daher wird kein Wert, sondern ein Zeiger auf eine Variable übergeben. Mit dem &amp;amp; Zeichen bekommen Sie die Adresse einer Variablen (&amp;quot;call by reference&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=Parameter von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;=&lt;br /&gt;
Das Unterprogramm &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; kann, wie jede andere Funktion, Parameter besitzen. Doch keine selbst gewählten, sondern nur bestimmte. Doch warum braucht main Parameter? Denken Sie einmal an alle Betriebssystembefehle:&lt;br /&gt;
&amp;lt;tt&amp;gt;dir *.exe &amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;copy *.* a:&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;ls -la &amp;lt;/tt&amp;gt;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen!&lt;br /&gt;
&lt;br /&gt;
=Kurzreferenz=&lt;br /&gt;
==Syntax-Bausteine==&lt;br /&gt;
&lt;br /&gt;
Die Erklärung des Aufbaus von C-Befehlen erfolgt neben einfachen Beispielen auch durch ihren prinzipellen Aufbau. In diesen Syntax-Beschreibungen finden sich immer wieder die gleichen Bausteine, die hier näher erklärt werden sollen. Falls Dir solch ein Syntax-Baustein begegnet, kannst Du ihn anklicken und kommst dann zu seiner Erläuterung. &lt;br /&gt;
&lt;br /&gt;
In den Beispielen selbst gehören auch die spitzen Klammern zu dem Baustein (was daran zu erkennen ist, daß auch die Klammern eingefärbt sind). Die Klammern dürfen in einem konkreten C-Programm daher nicht eingetippt werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bezeichner&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Bezeichner in C dienen dazu, Variablen zu identifizieren und ihnen sprechende Namen zu geben, um die Quelle lesbarer zu machen. Man braucht Bezeichner auch, um selbstdefinierte Datentypen zu benennen und zum Benennen von Struct- und Union-Komponenten sowie als Namen für Funktionen und Sprungmarken (Labels).&lt;br /&gt;
&lt;br /&gt;
Bezeichner dürfen aus den Kleinbuchstaben &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;z&amp;lt;/tt&amp;gt;, den Großbuchstaben &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;Z&amp;lt;/tt&amp;gt;, dem Unterstrich&amp;amp;nbsp;&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt; und den Ziffern &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;9&amp;lt;/tt&amp;gt; aufgebaut werden, wobei an erster Stelle jedoch keine Ziffer stehen darf.&lt;br /&gt;
&lt;br /&gt;
Es wird zwischen Groß- und Kleinschreibung unterschieden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Ausdruck in C ist ein Konstrukt, das einen Wert hat. Ob dieser Wert eine ganze Zahl ist, eine Kommazahl oder ein Zeiger, etc. ist dabei egal. Die einfachsten Ausdrücke sind Konstanten wie&lt;br /&gt;
 2&lt;br /&gt;
oder Variablen wie&lt;br /&gt;
 ein_zahl&lt;br /&gt;
Mehrere Ausdrücke können durch [[#Liste der Operatoren|Operatoren]] zu komplexeren Ausdrücken kombiniert werden, etwa&lt;br /&gt;
 eine_zahl + andere_zahl == 2&lt;br /&gt;
oder &lt;br /&gt;
 eine_zahl = 2&lt;br /&gt;
Letzterer hat den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; und den Nebeneffekt, daß er diesen Wert an &amp;lt;tt&amp;gt;eine_zahl&amp;lt;/tt&amp;gt; zuweist.&lt;br /&gt;
&lt;br /&gt;
Auch der Aufruf einer Funktion, die einen Rückgabewert liefert, ist ein Ausdruck:&lt;br /&gt;
 sin (1.2)&lt;br /&gt;
und kann zum Aufbau komplexerer Ausdrüche verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bedingung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Bedingung ist ein Ausdruck, bei der nur interessiert, ob dieser zu&amp;amp;nbsp;0 (unwahr) auswertet oder zu ungleich&amp;amp;nbsp;0 (wahr). Solche Ausdrücke findet man in if-Anweisungen, in Schleifenbedingungen und bedingten Zuweisungen&lt;br /&gt;
 (ein_wert &amp;lt; 2) || (ein_wert &amp;gt; 40)&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Lvalue ist ein Ausdruck, dem etwas zugewiesen werden kann. Der Name ''Lvalue'' kommt aus dem Englischen. Das ''L'' steht abkürzend für left. Ein Lvalue ist damit ein Ausdruck, der auf der linken Seite eine Zuweisung in C stehen darf. Das &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; in den folgenden Beispiel-Ausdrücken muss ein Lvalue sein:&lt;br /&gt;
 x = y-1&lt;br /&gt;
&lt;br /&gt;
 x++&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Konstante&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Konstante ist ein Ausdruck, dessen Wert dem Compiler bekannt ist. Beispiele für Konstanten sind etwa&lt;br /&gt;
 7&lt;br /&gt;
 'B'&lt;br /&gt;
 -13.98e12&lt;br /&gt;
 1+(2*3)&lt;br /&gt;
und die Werte von [[#Enum|Enum]]s. &lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; aus dem folgenden Codestück definiert jedoch keine Konstante in diesem Sinne&lt;br /&gt;
 const double Pi = 3.14159256;&lt;br /&gt;
denn in einem anderen Quellmodul könnte durch die Deklaration&lt;br /&gt;
 extern const double Pi;&lt;br /&gt;
das Symbol &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; bekannt sein, ohne daß sein Wert bekannt ist!&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Adresse&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Adresse ist ein Ausdruck, der einen Speicherort (physikalisch oder virtuell) halten kann. Adressen erhält man dadurch, daß man einem Bezeichner den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt;voranstellt, Adressen durch Arithmetik berechnet oder Zahlen zu Adressen castet. Folgende Ausdrücke sind Adressen (eine sinnvolle Deklaration der auftretenden Variablen vorausgesetzt)&lt;br /&gt;
 &amp;amp; eine_zahl&lt;br /&gt;
 &amp;amp; ein_array[10]&lt;br /&gt;
 &amp;amp; ein_struct&lt;br /&gt;
 &amp;amp; ein_struct.komponente&lt;br /&gt;
 (int *) 0x1234&lt;br /&gt;
 (int *) eine_zahl&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Deklaration&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Anweisungen sind gewissermassen die Atome (oder Moleküle?), aus denen ein C-Programm besteht. Jedes C-Programm ist eine Abfolge von Deklarationen und Anweisungen. Einfache Anweisungen erhält man, in dem man einen Ausdruck nimmt und einen Strichpunkt dahinter schreibt:&lt;br /&gt;
 {{Ausdruck|}};&lt;br /&gt;
wie in&lt;br /&gt;
 x = x+1;&lt;br /&gt;
&lt;br /&gt;
Andere Anweisungen sind die unten aufgeführten Schleifen und die if- sowie die switch-Anweisung.&lt;br /&gt;
&lt;br /&gt;
Mehrere Deklarationen und Anweisungen können zu einem Block zusammengefasst werden. Dieser Block stellt dann wieder eine einzelne Anweisung dar und kann genau so gehandhabt werden!&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
In diesem Sinne ist auch z.B. die Syntax der if-Anweisung zu verstehen&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
besagt, daß der abhängig ausgeführte Code eine einzelne Anweisung sein darf oder eben ein kompletter Block oder die Verschachtelung mehrerer Blöcke etc.&lt;br /&gt;
&lt;br /&gt;
Eine Anweisung kann auch &amp;quot;leer&amp;quot; sein, also nichts tun. Diese Anweisungen sind der leere Block&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
und der Strichpunkt&lt;br /&gt;
 ;&lt;br /&gt;
die man gelegentlich in Schleifen findet:&lt;br /&gt;
 while (!timeout())&lt;br /&gt;
    {}&lt;br /&gt;
oder hinter Sprungmarken, die sonst direkt vor einer schliessenden Blockklammer stünden:&lt;br /&gt;
 {&lt;br /&gt;
    ...&lt;br /&gt;
    goto ein_label;&lt;br /&gt;
    ...&lt;br /&gt;
    {{Label|ein_label}}:;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Nicht jede Anweisung ist an jeder Stelle eines C-Programms erlaubt, so darf ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; nut innerhalb einer Schleife stehen. Gleiches gilt für &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;, das aber auch innerhalb eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; vorkommen darf.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Dies steht für einen Datentyp. Es kann ein elementarer Typ sein wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;, ein Zeiger darauf wie &amp;lt;tt&amp;gt;char*&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;void*&amp;lt;/tt&amp;gt;, und auch Qualifier enthalten wie das &amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt; im Typ &amp;lt;tt&amp;gt;unsigned long long&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Zu den Typen gehören auch zusammengesetzte Datentypen wie Strukturen und Unions, mit &amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt; selbst definierte Typen und natürlich Zeiger darauf, wie aus dem Abschnitt [[#Datentypen|Datentypen]]:&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person *&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;data32_t&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;&lt;br /&gt;
und Zeiger auf Funktionen.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Parameterliste&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
Die Parameterliste bei einer Funktionsdefinition gibt an, wieviel Übergabeparameter sie bekommt, wie diese heissen und welchen Typs diese sind. Der prinzipielle Aufbau ist&lt;br /&gt;
 {{Type}} {{Bezeichner}}, {{Type}} {{Bezeichner}}, ...&lt;br /&gt;
Falls die Funktion keine Parameter hat, dann ist die Parameterliste leer.&lt;br /&gt;
&lt;br /&gt;
Hier als Beispiel die zweiparametrige Funktion &amp;lt;tt&amp;gt;produkt&amp;lt;/tt&amp;gt;. Der erste Parameter heisst&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und ist ein &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;. Der zweite namens&amp;amp;nbsp;&amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; ist vom Typ &amp;quot;Zeiger auf double&amp;quot;, der Inhalt &amp;lt;tt&amp;gt;*b&amp;lt;/tt&amp;gt; ist also auch ein double.&lt;br /&gt;
&lt;br /&gt;
'''Definition der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b)&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
In älteren C-Quellen findet man noch eine andere Syntax für die Deklaration der Parameter, die aber heute praktisch nicht mehr verwendet wird:&lt;br /&gt;
'''alte Definition der Funktion:'''&lt;br /&gt;
 double produkt (a, b)&lt;br /&gt;
 double a, *b;&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Um die Funktion bekannt zu machen, werdendet man eine Deklaration bzw. den Prototypen, der dem Compiler nur mitteilt, welche Parameter die Funktion bekommt und was sie zurückliefert. Für den Aufruf der Funktion muss der Compiler nur diesen Prototyp kennen, ''was'' die Funktion im Endeffekt macht und wie sie implementiert wurde ist egal, sie wird als BlackBox angesehen.&lt;br /&gt;
&lt;br /&gt;
'''Prototyp der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b);&lt;br /&gt;
Hier dürfen die Bezeichner auch fehlen:&lt;br /&gt;
 double produkt (double, double*);&lt;br /&gt;
&lt;br /&gt;
==if==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==if-else==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==for==&lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Eine for-Schleife entspricht folgendem Konstrukt. Dabei sind die drei Ausdrücke optional. Fehlt die Bedingung, dann wird diese als &amp;quot;wahr&amp;quot; angenommen. Die beiden anderen Ausdrücke wird man als Ausdrücke mit Nebeneffekt wählen wie z.B. &amp;lt;tt&amp;gt;x=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;x=x-2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
 {&lt;br /&gt;
    {{Ausdruck|1}};&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_loop}}:&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
    else&lt;br /&gt;
       goto _break;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_continue}}:&lt;br /&gt;
    {{Ausdruck|2}};&lt;br /&gt;
    goto _loop;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_break}}:;&lt;br /&gt;
 }&lt;br /&gt;
Die Labels &amp;lt;tt&amp;gt;_break&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_continue&amp;lt;/tt&amp;gt; entsprechen den Sprungzielen einer &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Anweisung innerhalb von &amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==do-while==&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while  ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
==while==&lt;br /&gt;
 while  ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==switch==&lt;br /&gt;
 switch  ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    ...&lt;br /&gt;
  &lt;br /&gt;
    default:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#break-Anweisung|&amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Konstanten|&amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#continue-Anweisung|&amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#do-while-Schleife|&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Enum|&amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#for-Schleife|&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#goto-Anweisung|&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#return-Anweisung|&amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Liste der Operatoren|sizeof]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Strukturen|&amp;lt;tt&amp;gt;struct&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Eigene Datentypen|&amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Unions|&amp;lt;tt&amp;gt;union&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#while-Schleife|&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund2}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Arithmetische Operatoren&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Dies sind die &amp;quot;normalen&amp;quot; arithmetischen Operationen, wie man sie aus der Schule kennt. Man kann damit und allen anderen Operatoren auch komplexere Ausdrücke aufbauen. Die Prioritäten sind so, wie man sie kennt, also &amp;quot;Punktrechnung vor Strichrechnung&amp;quot;. Will man dies ändern, dann mit den runden Klammern:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;1+2*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 7&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(1+2)*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 9&amp;lt;br/&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}}&amp;amp;nbsp;+&amp;amp;nbsp;{{Ausdruck|}}&amp;lt;/tt&amp;gt; || Addition&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} - {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Subtraktion&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} * {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Multiplikation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} / {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Division&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} % {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Rest der Division (modulo)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;- {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Vorzeichenumkehr, Zweier-Komplement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Logische Operatoren und Vergleiche&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die logischen und die vergleichenden Operatoren liefern als Ergebnis den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (wahr) oder einen Wert ungleich&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (falsch, um genau zu sein den Wert &amp;lt;tt&amp;gt;!0&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Man kann das Ergebnis zwar einer Variablen zuweisen, in aller Regel wird man solche Ausdrücke jedoch in Bedingungen zu &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder in Abbruch-Bedingungen von Schleifen finden.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;&amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches AND: beides wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124;&amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches OR: mind. eines ist wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;! {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches NOT (0 &amp;amp;harr; ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} == {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} != {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist nicht gleich&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bitweise Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~ {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise NOT (Einser-Komplement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise AND&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise ODER&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} ^ {{Ausdruck|}}&amp;lt;/tt&amp;gt; ||bitweise XOR&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Shift-Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;lt;&amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Bits nach links schieben&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;gt;&amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Schieben nach rechts schieben&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Typen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Ein Cast in C kann dazu verwendet werden, den Typ eines Ausdruckes zu ändern oder den Ausdruck mit einer bestimmten Genauigkeit zu berechnen. Wird z.B. eine Berechnung standardmässig in 16 Bit ausgeführt, dann kann man mit einem Cast &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(long) &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
ausdrücken, daß die Berechnung in 32 Bit erfolgen soll. Des weiteren kann man Zeiger und ganze Zahlen und Gleitkommazahlen ineinander umwandeln.&lt;br /&gt;
&lt;br /&gt;
Casts können ''nicht'' dazu verwendet werden, um z.B. eine Zahl in einen String zu konvertieren, der diese Zahl darstellt! Dafür gibt es spezielle Funktionen wie &amp;lt;tt&amp;gt;itoa&amp;lt;/tt&amp;gt;!&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Type}}) {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Cast, Typwandlung&lt;br /&gt;
|-&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;| &amp;lt;tt&amp;gt;sizeof ({{Type}})&amp;lt;/tt&amp;gt; || Eine Konstante, deren Wert die Größe (in Bytes) des Typs ist. &amp;lt;tt&amp;gt;sizeof&amp;lt;/tt&amp;gt; ist auch auf Objekte anwendbar wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, Arrays bekannter Größe, Strukturen und Unions,  Array-, Struktur- und Union-Komponenten, Pointer, etc. Beispiel:&amp;lt;br/&amp;gt;&lt;br /&gt;
 int i, sum=0, array[] = { 1, -13, 4, 0, sizeof (int*) };&lt;br /&gt;
 &lt;br /&gt;
 for (i=0; i&amp;lt; sizeof (array) / sizeof (array[0]); i++)&lt;br /&gt;
    sum += array[i];&lt;br /&gt;
Alle Elemente des Arrays werden aufaddiert, ohne daß deren Anzahl explizit in der Schleife genannt ist.&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zeiger und Adressen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;* {{Adresse}}&amp;lt;/tt&amp;gt; || der Inhalt an Adresse&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp; {{Lvalue}}&amp;lt;/tt&amp;gt; || Adresse von&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Strukturen, Unions, Arrays&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Struct&amp;gt;}}.{{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Zeiger-auf-Struct&amp;gt;}} -&amp;gt; {{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union, deren Adresse man hat&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Adresse}}&amp;amp;#91;{{Ausdruck|}}&amp;amp;#93;&amp;lt;/tt&amp;gt; || Array-Element&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bedingte Auswertung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Bedingung}}) ? {{Ausdruck|}} : {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Auswahl des Wertes abhängig von der Bedingung&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zuweisung und Operatoren mit Nebeneffekt&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die Unterschiede der post- und pre-Varianten der Increment/Decrement kommen in Konstrukten wie &amp;lt;tt&amp;gt;x = *p++&amp;lt;/tt&amp;gt; zum tragen:&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *p++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; p = p+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *++p;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; p = p+1; x = *p;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = (*p)++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; *p = (*p)+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = ++(*p);&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; *p = (*p)+1; x = *p;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} = {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Zuweisung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++ {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-- {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Decrement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ++&amp;lt;/tt&amp;gt; || Post-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} --&amp;lt;/tt&amp;gt; || Post-Decrement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Kurzschreibweisen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Für ganz Faule gibt es anstatt&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a = a @ b&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
für viele Operatoren (hier dargestellt durch ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;@&amp;lt;/tt&amp;gt;) die abkürzende Schreibweise&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a @= b&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} += {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} -= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} *= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} /= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} %= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ^= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;lt;&amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;gt;&amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Autoren=&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
=Quellen=&lt;br /&gt;
* Kernighan und Ritchie&lt;br /&gt;
* Christian Wirth, C-Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
* W. Alex, Einführung in C/C++&lt;br /&gt;
* Peter Baeumle-Courth, ANSI-C im Überblick&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://wwwuser.gwdg.de/~kboehm/ebook/inhalt.html C-Programmieren unter Linux]&lt;br /&gt;
* [http://www.gdv.uni-hannover.de/documentation.php Skripte zum Selbststudium: C, C++, Java, etc]&lt;br /&gt;
* [http://info.baeumle.com/ansic.html Einführung in ANSI-C]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Quellcode C|!]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Inrfb2</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10405</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10405"/>
				<updated>2007-03-14T12:23:59Z</updated>
		
		<summary type="html">&lt;p&gt;Inrfb2: /* Strukturen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Programmiersprache C wurde 1971 als Gundlage für das Betriebssystem UNIX in den USA entwickelt (UNIX ist zu über 90% in C geschrieben). 1978 wurde von Brian Kernighan und Dennis Ritchie eine eindeutige Sprachdefinition entwickelt. Mittlerweile ist C von ANSI und ISO standardisiert.&lt;br /&gt;
&lt;br /&gt;
Heute sind C und ihr Nachfolger C++ die dominierenden Programmiersprachen. Sehr viele Anwendungen sind in C geschrieben, was inzwischen auch auf eingebettete Systeme zutrifft, die lange in Assembler programmiert werden mussten, da keine ausreichend leistungsfähigen Compiler zur Verfügung standen. &lt;br /&gt;
&lt;br /&gt;
Leider ist C nicht einfach zu lernen &amp;amp;ndash; es wurde weder von noch für Hobby-Programmierer entwickelt &amp;amp;ndash; und eignet sich daher nur bedingt für den Einsteiger. Mit etwas Übung und einem optimierenden Compiler kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
Vom Design her ist C eine Hardware-unabhängig Sprache. Das bedeutet, daß C-Programme mit vertretbarem Aufwand auf ein anderes System portiert werden können. Dazu benötigt man lediglich einen anderen Compiler, und Inline-Assembler-Anweisungen (Assembleranweisungen innerhalb eines C-Programmes) müssen der neuen Hardware (Prozessor) angepasst werden. &lt;br /&gt;
&lt;br /&gt;
==Geschichte==&lt;br /&gt;
;1971: C wird entwickelt&lt;br /&gt;
;1978: Kernighan und Ritchie definieren die Sprache.&lt;br /&gt;
;1983: ANSI und ISO standardisieren C.&lt;br /&gt;
;1992: Bjarne Stroustrup enwickelt die Nachfolgesprache C++.&lt;br /&gt;
&lt;br /&gt;
=Aufbau eines C-Programmes=&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
   C-Programme haben keinen fixen Aufbau wie z.B. Pascal. Es gibt zwar gewisse Regeln, aber sonst sind dem Programmierer alle Freiheiten überlassen. Der folgende &amp;quot;Beispiel-Aufbau&amp;quot; ist daher nicht zwingend und kann durchaus verändert werden.&lt;br /&gt;
&lt;br /&gt;
   Natürlich haben C-Programme einen fixen Aufbau! Ebenso wie Pascal-Programme auch unterliegen sie einer strikten Grammatik! &lt;br /&gt;
Auskommentiert --[[Benutzer:SprinterSB|SprinterSB]] 10:23, 17. Feb 2006 (CET)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Ein einfaches C-Programm könnte folgendermassen aussehen. Das Programm tut eigentlich nichts, aber das Beispiel zeigt den prinzipiellen Aufbau. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 int Zahl1;&lt;br /&gt;
 char Zeichen1;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int zahl2;&lt;br /&gt;
 &lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Beschreibung:'''&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndash; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
 {{comment|void-Definition von main ist nur beim Controller ueblich}}&lt;br /&gt;
 {{comment|spezielle Compilereinstellungen sind noetig, damit bei dieser Definition von main}}&lt;br /&gt;
 {{comment|kein Fehler/Warnung erzeugt wird.}}&lt;br /&gt;
 void main ()&lt;br /&gt;
 {&lt;br /&gt;
     ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
 int main (void)&lt;br /&gt;
 {  {{comment|der Block &amp;quot;main&amp;quot; beginnt}}&lt;br /&gt;
    int zahl;&lt;br /&gt;
    &lt;br /&gt;
    {   {{comment|ein Block beginnt}}&lt;br /&gt;
        {{comment|hier koennen Deklarationen und Anweisungen stehen}}&lt;br /&gt;
    }   {{comment|der Block endet}}&lt;br /&gt;
   &lt;br /&gt;
    return 0;&lt;br /&gt;
 }  {{comment|&amp;quot;main&amp;quot; endet}}&lt;br /&gt;
&lt;br /&gt;
=Datentypen=&lt;br /&gt;
==Elementare Datentypen==&lt;br /&gt;
Der Datentyp einer Variable gibt an, welche Werte eine Variable enthalten kann, welcher Art diese Daten sind und wie sie verarbeitet werden, etwa in arithmetischen Operationen wie einer Addition. So ist es zum Beispiel möglich, in eine Variable vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ganze Zahlen zwischen ca. -32000 und +32000 einzutragen. In einer char-Variable können ASCII-Zeichen gespeichert werden (alles, was Sie mit der Tastatur erzeugen können) oder ganze Zahlen von -128 bis 127.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da C plattformabhängig ist, hängt die Größe eines Datentypes zum Teil von der genutzten Hardware (z.B. 8, 16 oder 32 Bit-Controller) und dem Compiler und dessen Einstellungen ab!&lt;br /&gt;
&lt;br /&gt;
===int, char, short, long (ganze Zahlen)===&lt;br /&gt;
In Variable dieser Typen können Sie ganze Zahlen abspeichern, also z.B. 1, &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;2, 100, 12345. Jeden dieser Typen gibt es in zwei Ausprägungen: als &amp;quot;&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;quot;, also als vorzeichenbehafteten Typ, und als &amp;quot;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&amp;quot;, also ohne Vorzeichen, d.h. das Vorzeichen wird als 0 oder +1 genommen. &lt;br /&gt;
&lt;br /&gt;
Vorzeichenbehaftete Ganzzahl-Typen werden intern im &amp;lt;tt&amp;gt;n-1&amp;lt;/tt&amp;gt;-Komplement dargestellt, das Vorzeichen selbst findet sich also im höchstwertigen Bit. Werden zur Speicherung ''b'' Bits verwendet, dann reicht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;z.B. *zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==Enum==&lt;br /&gt;
&lt;br /&gt;
Über &amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt; können Aufzählungen definiert werden. Die Werte sind &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Werte und beginnen mit&amp;amp;nbsp;0. Der folgende enum hat einen um&amp;amp;nbsp;1 grösseren Wert. Mit einer Zuweisung können auch andere Werte zugeordnet werden. Klarer wird's im Beispiel:&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 enum Farben&lt;br /&gt;
 {&lt;br /&gt;
    ROT,&lt;br /&gt;
    GRUEN,&lt;br /&gt;
    BLAU,&lt;br /&gt;
    BRAUN = 5,&lt;br /&gt;
    SCHWARZ&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
Dies definiert die Konstanten &amp;lt;tt&amp;gt;ROT=0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;GRUEN=1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BLAU=2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BRAUN=5&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;SCHWARZ=6&amp;lt;/tt&amp;gt; und den Typ &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void foo (enum Farben farbe)&lt;br /&gt;
{&lt;br /&gt;
   switch (farbe)&lt;br /&gt;
   {&lt;br /&gt;
      case ROT:&lt;br /&gt;
         ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit kann man anstatt &amp;quot;magischer&amp;quot; Zahlen sprechende Namen im Code verwenden, etwa in Berechnungen und Zuweisungen, Vergleichen oder als Konstante hinter einem &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zusammengesetzte Datentypen==&lt;br /&gt;
===Arrays===&lt;br /&gt;
Oft muß man sehr viele Werte gleichzeitig abspeichern und betrachten, die alle der selben Aufgabe dienen. Man schreibt z.B. ein Programm, das 10 Zahlen einlesen und anschließend wieder ausgeben soll. Man könnte das natürlich mit 10 einzelnen Variablen bewerkstelligen, aber es ist sinnvoller, dabei Arrays &amp;amp;ndash; teilweise auch als ''Felder'' bezeichnet &amp;amp;ndash; zu verwenden.&lt;br /&gt;
&lt;br /&gt;
In einem Array werden mehrere Variablen gleichen Typs zusammengefasst und hintereinander im Speicher abgelegt. So kann man viele tausend Variablen anlegen mit nur einer Zeile Code. Doch es gibt noch größere Vorteile: Sie können das Array mit einer Schleife ganz einfach nach Werten durchsuchen. Stellen Sie sich vor, Sie müssten mit 100 verschiedenen Variablen &amp;lt;tt&amp;gt;Zahl_00&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;Zahl_99&amp;lt;/tt&amp;gt; arbeiten!&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}}&amp;amp;#91;{{Konstante}}&amp;amp;#93;;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 unsigned int werte[100];&lt;br /&gt;
&lt;br /&gt;
Der Name muß natürlich ein gültiger Bezeichner sein, als Datentyp kann jeder Typ genommen werden &amp;amp;ndash; sowohl elementare Datentypen als auch Zeiger, Strukturen, Unions oder selbst definierte Datentypen. In der eckigen Klammer wird die Anzahl der Elemente bekanntgegeben. Ein mit [3] definiertes Array hat Platz für drei Variablen. Da der Index immer bei 0 beginnt, greift man also mit &amp;lt;tt&amp;gt;[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;[1]&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;[2]&amp;lt;/tt&amp;gt; auf den jeweilige Inhalt zu. Um auf eine der im Array enthaltenen Variablen zugreifen zu können, müssen Sie den Variablennamen und in eckigen Klammern den Index (die &amp;quot;Nummer&amp;quot;) der Variablen angeben. Diese Variable verhält sich dann wie eine ganz normale Variable des jeweiligen Datentypes. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #define NZAHLEN 10&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int i;&lt;br /&gt;
    int zahlen[NZAHLEN];  {{comment|zahlen[0] ... zahlen[9]}}&lt;br /&gt;
  &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++)&lt;br /&gt;
    {&lt;br /&gt;
       printf (&amp;quot;Bitte Zahl %d eingeben: &amp;quot;, i);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; zahlen[i]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++) &lt;br /&gt;
       printf (&amp;quot;Zahl %d ist: %d\n&amp;quot;, i, zahlen[i]);&lt;br /&gt;
      &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 10 int-Variablen großes Array angelegt. &lt;br /&gt;
In dieses wird nun der Reihe nach 10 Zahlen eingelesen. &lt;br /&gt;
Anschließend werden alle 10 Zahlen ausgegeben. &lt;br /&gt;
&lt;br /&gt;
Dabei wird die Größe der Arrays und das Schleifenende über das Define &amp;quot;&amp;lt;tt&amp;gt;NZAHLEN&amp;lt;/tt&amp;gt;&amp;quot; angegeben. Dadurch muss nur ''eine Stelle'' im Code geändert werden, wenn die Größe des Arrays einmal einen anderer Wert als 10 haben soll &amp;amp;ndash; dies vermeidet Fehler die dadurch entstehen, wenn man beim Anpassen der Array-Größe eine Codestelle vergisst, zudem wird der Code lesbarer als wenn irgendwo die Zahl &amp;quot;10&amp;quot; auftaucht.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
:Wird ein ungültiger Index angeben (einer, der in der Deklaration nicht enthalten ist) können  undefinierte Dinge passieren, wenn dadurch andere Variableninhalte oder Programmcode überschrieben wird, der hinter oder vor dem Array im Speicher liegt. Schlimmstenfalls kann sogar der Computer/Controller abstürzen. Also darauf achten, daß keine ungültigen Werte als Index auftreten!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Strings (Zeichenketten)===&lt;br /&gt;
Ein String ist nichts anderes als ein Array, das aus einzelnen Zeichen (&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;) gebildet wird. Die Ausgabe auf dem Bildschirm funktioniert am einfachsten mittels Strings.&lt;br /&gt;
&lt;br /&gt;
Die Definition eines Strings erfolgt also genauso wie bei Arrays:&lt;br /&gt;
 char string[21];&lt;br /&gt;
&lt;br /&gt;
Nun haben Sie eine String, in dem Sie 21 Zeichen speichern können. Ganz richtig ist das jedoch nicht. C arbeitet mit &amp;quot;null-terminierten Strings&amp;quot;. Das beudeutet, dass die Länge des Strings nicht abgespeichert wird, sondern das Zeichen mit dem ASCII-Wert 0 das Stringende kennzeichnet. Daher auch die Bezeichnung  &amp;quot;null terminiert&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Das letzte Zeichen eines Strings muß daher immer das ASCII-Zeichen Nr. 0 sein. Ist es das nicht, hat der String kein definiertes Ende, und wenn Sie versuchen, ihn durch eine Standard-Funktion auszugeben zu lassen, könnte es eine Weile dauern, bis sich im Speicher zufällig irgendwo eine 0 befindet. Es stehen ihnen daher bei dem Beispiel nur 20 Zeichen zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
===Mehrdimensionale Arrays===&lt;br /&gt;
Manchmal benötigt man mehr als nur ein eindimensionales Array, wie Sie es bisher kennengelernt haben. Auch dies ist kein Problem. In der Deklaration geben Sie einfach mehrere eckige Klammern hintereinander an. Aber Vorsicht: der Speicherplatz ist begrenzt, ein &amp;quot;&amp;lt;tt&amp;gt;char feld[1024][1024]&amp;lt;/tt&amp;gt;&amp;quot; hat die Speicherplatzgrenzen vermutlich bereits weit überschritten, und der Compiler wird einen (bei gewissen Einstellung auch keinen) Fehler liefern.&lt;br /&gt;
Beim Zugriff auf mehrdimensionale Felder müssen auch mehrere Indizes angeben werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  int x,y;&lt;br /&gt;
  int feld[3][5];&lt;br /&gt;
 &lt;br /&gt;
  for (x=0; x&amp;lt;3; x++) &lt;br /&gt;
  {&lt;br /&gt;
     for (y=0; y&amp;lt;5; y++)&lt;br /&gt;
     {&lt;br /&gt;
       printf (&amp;quot;Feldwert x: %d,  y: %d &amp;quot;, x, y);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; feld[x][y]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  for(x=0; x&amp;lt;3; x++) &lt;br /&gt;
     for (y=0; y&amp;lt;5; y++) &lt;br /&gt;
        printf (&amp;quot;Wert: feld[%d][%d] = %d\n&amp;quot;, x, y, feld[x][y]);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 3 mal 5 &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array angelegt. &lt;br /&gt;
Dann werden die Werte eingegeben: zuerst &amp;lt;tt&amp;gt;feld[0][0]&amp;lt;/tt&amp;gt;, dann &amp;lt;tt&amp;gt;feld[0][1]&amp;lt;/tt&amp;gt;, usw. bis &amp;lt;tt&amp;gt;feld[2][4]&amp;lt;/tt&amp;gt;. &lt;br /&gt;
Zum Schluß werden alle Werte noch einmal ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===Strukturen===&lt;br /&gt;
In C können Sie sogenannte &amp;quot;Strukturen&amp;quot; definieren. Dabei handelt es sich um eine Zusammenfassung mehrerer Datentypen zu einem größeren. Im Unterschied zu Feldern können in Strukturen unterschiedliche Datentypen zusammengestellt und gespeichert werden: &lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 struct {{Bezeichner}}&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur 'Person'}}&lt;br /&gt;
 struct Person &lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;lt;tt&amp;gt;struct Person {&amp;lt;/tt&amp;gt;&amp;quot; leitet die Definition der Struktur mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;Person&amp;lt;/tt&amp;gt;&amp;quot; ein. &lt;br /&gt;
Dann werden in dieser Struktur fünf Komponenten definiert: drei Strings und zwei &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. &lt;br /&gt;
mit &amp;lt;tt&amp;gt;}&amp;lt;/tt&amp;gt; wird die Definition abgeschlossen. Sie haben damit einen Datentyp erstellt. Um eine Variable des Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach an&lt;br /&gt;
 struct Person {{Bezeichner}};&lt;br /&gt;
&lt;br /&gt;
Zum Zugriff auf eine Komponente der Struktur gibt man den Namen der Struktur-Variablen an (im folgenden Beispiel also &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;klaus&amp;lt;/tt&amp;gt;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
 {{comment|Definition zweier Struktur-Variablen}}&lt;br /&gt;
 struct Person hubert, klaus;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Zugriff auf Struktur-Komponenten}}&lt;br /&gt;
 hubert.alter = 32;&lt;br /&gt;
 klaus.alter = hubert.alter + 1;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis:'''&lt;br /&gt;
Der eventuell etwas lästige Gebrauch von &amp;lt;tt&amp;gt;struct&amp;lt;/tt&amp;gt; kann schon bei der Definition der Struktur vermieden werden.&lt;br /&gt;
Der Definition ist ein &amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt; voranzustellen. Der Definition folgt dann ein gültiger (und auch eindeutiger) C-Name.&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 typedef struct {{Bezeichner}}&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 } {{Bezeichner}} ;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur '_Mensch' bzw. 'Mensch'}}&lt;br /&gt;
 struct _Mensch&lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 } Mensch;&lt;br /&gt;
&lt;br /&gt;
Jetzt sind folgende Deklarationen identisch:&lt;br /&gt;
 struct _Mensch {{Bezeichner}};&lt;br /&gt;
 Mensch {{Bezeichner}};&lt;br /&gt;
&lt;br /&gt;
Ist der Struktuname nicht notwendig (im Beispiel oben &amp;lt;tt&amp;gt;_Mensch&amp;lt;/tt&amp;gt;), kann auch kürzer geschrieben werden:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 typedef struct &lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 } {{Bezeichner}} ;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur 'Mensch'}}&lt;br /&gt;
 struct &lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 } Mensch;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall ist lediglich die {{Deklaration}} &amp;lt;tt&amp;gt;Mensch {{Bezeichner}};&amp;lt;/tt&amp;gt; gültig.&lt;br /&gt;
&lt;br /&gt;
Der Hinweis gilt sinngemäß auch für die Definition &amp;lt;tt&amp;gt;union&amp;lt;/tt&amp;gt; im nachfolgenden Abschnitt.&lt;br /&gt;
&lt;br /&gt;
===Unions===&lt;br /&gt;
Eine Union wird ganz analog zu einer Struktur deklariert und verwendet. Sie unterscheidet sich von einer Struktur jedoch dadurch, daß ihre Elemente nicht nacheinander im Speicher abgelegt werden, sondern sich überlagern. Auf die in einer Union enthaltenen Daten gibt es also verschiedene Sichten: je nachdem, welche Sicht bzw. Interpretation der Daten man gerne hätte, wählt man den gewünschten Zugriff.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
union Daten &lt;br /&gt;
{&lt;br /&gt;
   int id;&lt;br /&gt;
&lt;br /&gt;
   struct Person u_person;&lt;br /&gt;
&lt;br /&gt;
   struct u_double&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      double wert;&lt;br /&gt;
   };&lt;br /&gt;
&lt;br /&gt;
   struct u_pointer&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      union Daten * p1;&lt;br /&gt;
      union Daten * p2;&lt;br /&gt;
   };&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
union Daten data;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies definiert eine Union mit den vier Zugriffsmöglichkeiten &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_double&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Größe der Union richtet sich dabei nach der grössten Komponente. In diesem Beispiel sind alle Komponenten so angelegt worden, daß sie an erster Stelle ein &amp;lt;tt&amp;gt;int id&amp;lt;/tt&amp;gt; enthalten. In &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; könnte man sich also merken, wie die Daten in der Union zu interpretieren sind. Würde &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; nicht dieses &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; enthalten, so würde sich &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; mit &amp;lt;tt&amp;gt;data.u_person.vname&amp;lt;/tt&amp;gt; überlagern. Ein Ändern der ersten Buchstaben von &amp;lt;tt&amp;gt;vname&amp;lt;/tt&amp;gt; hätte also ein Ändern von &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; zur Folge, und man könnte es nicht mehr als Merker verwenden. Mit diesem Feld überlagert das &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; die &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;-Felder der anderen Sichten, z.B. ist &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; der selbe Zugriff wie auf &amp;lt;tt&amp;gt;data.u_person.id&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein anderes Beispiel ist eine Union, die es ermöglicht, auf die einzelnen Bytes eines &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; zuzugreifen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef union&lt;br /&gt;
{&lt;br /&gt;
   unsigned long  as_long;&lt;br /&gt;
   unsignen short as_short[2];&lt;br /&gt;
   unsignen char  as_byte[4];&lt;br /&gt;
} data32_t;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies überlagert einen &amp;lt;tt&amp;gt;unsigned long&amp;lt;/tt&amp;gt; &amp;amp;ndash; also eine 32-Bit-Zahl &amp;amp;ndash; mit vier Bytes bzw. zwei Shorts.&lt;br /&gt;
 data32_t wert;&lt;br /&gt;
 &lt;br /&gt;
 wert.as_long = 0x12345678;&lt;br /&gt;
 wert.as_byte[0] = 0xab;&lt;br /&gt;
 {{comment|nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform)}}&lt;br /&gt;
&lt;br /&gt;
==Eigene Datentypen==&lt;br /&gt;
&lt;br /&gt;
=Variablen=&lt;br /&gt;
Eine Variable ist ein Synonym (=anderer Name) für eine Speicherstelle in einem Computer. Einfacher gesagt, eine Variable bietet Raum, um Daten wie Zahlen oder Zeichen zu speichern und wieder zu lesen.&lt;br /&gt;
&lt;br /&gt;
==Variablennamen==&lt;br /&gt;
Ein Variablenname kann zusammengesetzt werden aus den Buchstaben &amp;lt;tt&amp;gt;'''A'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''Z'''&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;'''a'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''z'''&amp;lt;/tt&amp;gt;, den Ziffern &amp;lt;tt&amp;gt;'''0'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''9'''&amp;lt;/tt&amp;gt;, sowie dem Sonderzeichen &amp;quot;Unterstrich&amp;quot; (underscore) &amp;lt;tt&amp;gt;'''_'''&amp;lt;/tt&amp;gt;. Dabei darf an erster Stelle keine Ziffer stehen. Die Bezeichner &amp;lt;tt&amp;gt;hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALLO&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALL0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;_123&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_HALLO&amp;lt;/tt&amp;gt; sind also alle gültige und unterschiedliche Variablennamen.&lt;br /&gt;
&lt;br /&gt;
==Anlegen von Variablen==&lt;br /&gt;
Um eine Variable verwenden zu können, muss sie zuerst vereinbart (&amp;quot;erzeugt&amp;quot;) werden. Dies wird auch als &amp;quot;''Definition der Variablen''&amp;quot; bezeichnet und geht so: Schreiben Sie zuerst den Datentyp, dann den Namen der Variablen. Zum Schluß kommt noch der Strichpunkt, wie nach jeder C-Anweisung oder Deklaration. Und nicht vergessen: C unterscheidet zwischen  Groß- und Kleinschreibung! &lt;br /&gt;
 int Zahl1, Zahl2;&lt;br /&gt;
 char Zeichen;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    float gleitZahl;&lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:'''&lt;br /&gt;
In einer Zeile können auch mehrere Variablen gleichen Types vereinbart werden, wenn man ein Komma dazwischen setzt. Variablen können in jedem Block vereinbart werden. Siehe [[#Gültigkeitsbereich|Gültigkeitsbereich]].&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen==&lt;br /&gt;
Man kann einer vereinbarten Variable Werte [[#Zuweisungen|zuweisen]]. Dazu schreibt man zuerst den Variablennamen, ein Gleichheitszeichen &amp;quot;&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;&amp;quot; und anschliessend den zuzuweisenden [[#Ausdrücke|Ausdruck]]. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, zahl2 = 12;&lt;br /&gt;
  char zeichen1 = 'A';&lt;br /&gt;
&lt;br /&gt;
  zahl1 = 52;&lt;br /&gt;
  zeichen1 = zeichen1 + 1; &lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Zuerst werden drei Variablen angelegt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;: wird gleich bei der Vereinbarung der Wert 12 zugewiesen. &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl1 = 52&amp;lt;/tt&amp;gt;: Hier wird der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; der Wert 52 zugewiesen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;: wird um 1 erhöht. Da in der Variablen &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; gespeichert ist, gibt sich ihr neuer Wert aus &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt;. Weil &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; dem Wert 65 entspricht, ist &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt; gleich 66, was dem Wert für &amp;lt;tt&amp;gt;'B'&amp;lt;/tt&amp;gt; entspricht.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei float==&lt;br /&gt;
Das funktioniert genau wie bei normale Zuweisungen. Nachkommastellen werden durch einen Punkt abgegrenzt: &lt;br /&gt;
 floatVariable = 3.14;&lt;br /&gt;
Zusätzlich kann eine Zehnerpotenz angegeben werden:&lt;br /&gt;
 floatVariable2 = -1.234E-6;&lt;br /&gt;
Dadurch wird der erst Wert mit 10&amp;lt;sup&amp;gt;&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;6&amp;lt;/sup&amp;gt; multipliziert, der Wert der Variablen ist also &lt;br /&gt;
:&amp;lt;math&amp;gt;-1{,}234\cdot10^{-6} = -0.000001234&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei logischen Variablen==&lt;br /&gt;
Wie bereits erwähnt, besitzt C keinen logischen Datentyp. Es müssen also &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; dafür genutzt werden. Die Zuweisung entpricht der Standard-Zuweisung. Wird der Wert 0 zugewiesen, dann ist die Variable &amp;quot;unwahr&amp;quot;, ansonsten ist sie &amp;quot;wahr&amp;quot;. &lt;br /&gt;
 intVariable = !0;   /* entspricht &amp;quot;wahr&amp;quot;   */&lt;br /&gt;
 intVariable = 0;    /* entspricht &amp;quot;unwahr&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
==Konstanten==&lt;br /&gt;
Konstanten können als Variable angesehen werden, die nicht beschrieben, sondern nur gelesen werden können. Ein typisches Beispiel dafür ist die Zahl &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; (rund 3,141592654). Niemand würde in der realen Welt versuchen, ihr einen anderen Wert zuzuweisen. Würde man &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; jedoch wie eine normale Variable anlegen, wäre dies ohne weiteres möglich. Um dies zu verhindern, gibt es das Schlüsselwort &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in C:&lt;br /&gt;
 const {{Type}} {{Bezeichner}} = {{Konstante}};  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Wichtig dabei ist, dass man Konstanten nur bei der Vereinbarung einen Wert zuweisen kann. &lt;br /&gt;
Da Konstanten gewöhnlich im gesamten Programm, zumindest einer Quelldatei genutzt werden, definiert man diese allerdings gewöhnlich außerhalb des main-Blockes entweder am Anfang eines Programmes, oder in einer sogenannten Header-Datei, die per &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; eingebunden wird.&lt;br /&gt;
 const float PI = 3.141592;  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Es sei jedoch erwähnt, daß auch einer Konstanten nachträglich ein anderer Wert zugewieden werden kann. Im obigen Beispiel könnte mit&lt;br /&gt;
 * ((float*) &amp;amp;PI) = 2;&lt;br /&gt;
der Wert von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; im Nachhinein verändert werden. Es wird die Adresse von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; genommen und diese Adresse durch den Cast in eine ganz normale &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;-Adresse umgewandelt, über welche der Wert geändert wird. Die sei der Vollständigkeit halber erwähnt.&lt;br /&gt;
&lt;br /&gt;
Je nachdem, an welcher Stelle sich das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; bei einer Pointer-Deklaration befindet, markiert es den Pointer als konstant oder das Objekt, auf das dieser Pointer zeigt. Eine häufige Parameterdeklaration in Ausgabe-Funktionen, die einen String erhalten, ist&lt;br /&gt;
 void foo (const char * str, ...);&lt;br /&gt;
Dadurch ist &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; der Zeiger auf eine Zeichenkette, die innerhalt der Funktion nicht verändert wird bzw. verändert werden darf. Eine Zuweisung wie &amp;lt;tt&amp;gt;*str = 'a'&amp;lt;/tt&amp;gt; ergibt also einen Fehler. &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; selbst kann aber sehr wohl verändert werden, etwa mit &amp;lt;tt&amp;gt;str++&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Soll ausgedrückt werden, daß &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; unveränderlich ist, dann so:&lt;br /&gt;
 void foo (char * const str, ...);&lt;br /&gt;
Jetzt wäre eine Änderung des Strings in Ordnung, etwa durch &amp;lt;tt&amp;gt;str[10] = 'a'&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Um sich zu merken, worauf das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; wirkt, trennt man die Deklaration in Gedanken beim&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf: Steht das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; links vom&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, dann gehört es zum &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, steht es rechts davon, dann gehört es zum Pointer. Natürlich ist es auch denkbar, beides &amp;amp;ndash; also den Zeiger und sein Ziel &amp;amp;ndash; als konstant zu markieren.&lt;br /&gt;
&lt;br /&gt;
==Gültigkeitsbereich==&lt;br /&gt;
In C können mehrere Variablen den gleichen Namen haben, solange eindeutig ist, welche in welchen Block gültig ist. Dabei gelten folgende Regeln: &lt;br /&gt;
&lt;br /&gt;
;Lokale Variablen: sind Variablen, die innerhalb eines Blockes definiert werden. Jede Variable ist nur in dem Block gültig, in dem sie vereinbart wurde, sowie in allen darin enthaltenen Blöcken; es sei denn, in einem Unter-Block wird eine Variable gleichen Namens definiert. Dann bezieht sich in diesem Unter-Block der Bezeichner auf die im Unter-Block angelegte Variable.&lt;br /&gt;
;Globale Variablen: werden ausserhalb jedes Blockes definiert und gelten ab der Stelle, an der sie deklariert werden, siehe auch [[#Deklaration und Definition|Deklaration und Definition]]. Wird jedoch in einem Block eine Variable gleichen Namens angelegt, gilt ab hier bis zum Ende des Blocks nicht mehr die globale Variable, sondern die im Block deklarierte. Das Spiel kann man weiterspielen: wird in einem Unter-Block wieder eine namensgleiche Variable angelegt, gilt diese in dem Unterblock.&lt;br /&gt;
&lt;br /&gt;
==Speicherklassen==&lt;br /&gt;
Jede Variable in C gehört zu einer bestimmten Speicherklasse&lt;br /&gt;
;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;: Lokale Variablen sind in aller Regal sogenannte ''automatische Variablen''. Das bedeutet, sie werden automatisch angelegt, wenn ein Block bzw. eine Funktion betreten wird und danach wieder entfernt. Das Schlüsselwort &amp;quot;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;&amp;quot; wird praktisch nie hingeschrieben, denn lokale Variablen ohne die ausdrückliche Angabe einer Speicherklasse, sind automatisch automatische Variablen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;: Eine externes Symbol ist im ganzen Programm bekannt bzw. in dem Block, in der die Deklaration steht. In unterschiedlichen Blöcken stehende Deklarationen beziehen sich auf das gleiche Symbol! Obgleich das Datum global zugreifbar ist, ist der Gültigkeitsbereich auf den deklarierenden Block begrenzt bzw. auf das deklarierende Quell-Modul, sofern das Symbol ausserhalb jedes Blocks des Moduls deklariert wird. Siehe auch [[#Deklaration und Definition|Deklaration und Definition]].&lt;br /&gt;
;&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;: Die Variable ist im Block gültig bzw. im Quell-Modul (also in der C-Datei, in der die angelegt wurde), wenn sie nicht innerhalb eines Blockes angelegt wurde. Statische Variablen werden nicht in Registern oder im Frame der Funktion angelegt, sondern im selben Speicherbereich, in dem auch die globalen Variablen liegen; Konstanten evtl. auch im Flash. Eine lokale Variable, die als &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; angelegt wird, &amp;quot;überlebt&amp;quot; also das Verlassen des Blocks und hat beim neuerlichen Betreten des Blockes ihren bisherigen Wert. In unterschiedlichen Blöcken angelegte lokale statische Variablen beziehen sich auf unterschiedliche Speicherstellen, genau wie bei lokalen Variablen auch.&lt;br /&gt;
;&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;: Durch diese Speicherklasse wird eine Variable &amp;amp;ndash; falls möglich &amp;amp;ndash; als Registervariable angelegt, also in einem Maschinenregister des Computer/Controllers gehalten. Dadurch kann auf solche Variablen besonders schnell zugegriffen werden. Dieses Schlüsselwort ist bei modernen Compilern weitgehend überflüssig, da die entsprechenden Optimierungen selbständig vorgenommen werden, wenn ausreichend Register vorhanden sind. Auch globale Variablen können als Register angelegt werden, davon ist dem Anfänger aber dringend abzuraten, weil leicht schwerauffindbare Fehler und Abstürze auftreten, wenn man nicht genau weiss, welche Implikationen in einer solchen Definition stecken!&lt;br /&gt;
;&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;: (FIXME: volatile ist ein Qualifier und keine Speicherklasse) Dies ist das genaue Gegenteil von &amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt; und bewirkt, dass die Variable auf keinen Fall in einem Register zwischengespeichert werden darf, sondern immer aus dem RAM gelesen und ins RAM geschrieben werden soll. &amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt; müssen alle ''globalen'' Variablen markiert werden, die in [[ISR | Interrupt-Handlern]] verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Ausdrücke=&lt;br /&gt;
Eine Variable oder eine Konstante in C stellen einfache Ausdrücke dar.&lt;br /&gt;
Diese elementaren Ausdrücke können durch Operatoren miteinander verknüpft werden und so zu neuen, komplexeren Ausdrücken zusammen gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Einfache Beispiele für Ausdrücke sind also z.B.:&lt;br /&gt;
 1&lt;br /&gt;
 a&lt;br /&gt;
 'a'&lt;br /&gt;
 1 + a&lt;br /&gt;
 a == 1&lt;br /&gt;
&lt;br /&gt;
Auch Funktionen können einen Wert zurückliefern und in Ausdrücken weiter benutzt werden.&lt;br /&gt;
In den folgenden Abschnitten wird gezeigt, welche Operatoren in C vorhanden sind,&lt;br /&gt;
und wei man damit neue Ausdrücke aufbauen kann.&lt;br /&gt;
&lt;br /&gt;
==Lvalues==&lt;br /&gt;
&lt;br /&gt;
Ein Lvalue in C ist ein Ausdruck, dem ein anderer Ausdruck zugewiesen werden kann, dessen Wert also durch eine Zuweisung verändert werden kann.&lt;br /&gt;
das 'L' leitet sich ab von 'left' bwz. 'links' und das 'value' bedeutet Wert: Ein Lvalue ist ein Ausdruck, der auf der linken Seite einer Zuweisung stehen darf. Ein Lvalue ist also immer auch ein gültiger Ausdruck, aber die Umkehrung gilt in alles Regel nicht.&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für einen Lvalue ist eine &amp;quot;normale&amp;quot; Variable, die nicht mit &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; als Konstante markiert ist:&lt;br /&gt;
 a = 1;&lt;br /&gt;
Hingegen ist der Ausdruck &amp;lt;tt&amp;gt;a+1&amp;lt;/tt&amp;gt; kein Lvalue, denn eine Zuweisung wie&lt;br /&gt;
 a+1 = 2;&lt;br /&gt;
die mathematisch durchaus sinnvoll ist, erzeugt einen Compilerfehler, der etwa lauten könnte &amp;quot;illegal lvalue in assignment&amp;quot;:&lt;br /&gt;
&amp;quot;ungültiger Wert in Zuweisung&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Andere Beipiele für Lvalues sind die Komponenten von (nicht-konstanten) [[#Strukturen|Strukturen]] und [[#Unions|Unions]], [[#Arrays|Array]]-Elemente und die Dereferenzierungen von Pointern: Die Konstante&amp;amp;nbsp;4 wird durch den Cast in eine Adresse umgewandelt. Über die Dereferenzierung&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; wird an die Adresse&amp;amp;nbsp;4 im Speicher eine&amp;amp;nbsp;3 geschrieben. Ob das erlaubt bzw. sinnvoll ist, ist abhängig von der jeweiligen Architektur.&lt;br /&gt;
 * ((unsigned int *) 4) = 3;&lt;br /&gt;
Hier ist der gesamte &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;-Ausdruck ein Lvalue&lt;br /&gt;
&lt;br /&gt;
==Logische (boolsche) Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp;amp;&amp;amp;amp; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr oder &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; || gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; || ungleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;= b&amp;lt;/tt&amp;gt; || kleiner oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt; b&amp;lt;/tt&amp;gt; || kleiner als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt;= b&amp;lt;/tt&amp;gt; || glösser oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt; b&amp;lt;/tt&amp;gt; || grösser als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; nicht wahr und vice versa&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine interessante Eigenschaft der Operatoren &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;amp;amp;&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; ist, dass&lt;br /&gt;
sie die Auswertung abbrechen, sobald das Ergebnis feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet. Ein oft anzutreffendes Codestück sieht so aus, dabei sei &amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
  if (p &amp;amp;&amp;amp; *p == 5)&lt;br /&gt;
  {&lt;br /&gt;
     {{comment|mach was}}&lt;br /&gt;
  }&lt;br /&gt;
Zuerst wird in der Bedinung geprüft, ob Zeiger&amp;amp;nbsp;&amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; einen Wert ungleich Null hat, also ob er überhaupt einen gültigen Wert enthält. Es ist weit verbreitete Konvention in C, daß Zeiger, die keinen gültigen Wert haben, die Adresse&amp;amp;nbsp;0 enthalten. '''Nur dann, wenn ein Zeiger nicht ein Null-Pointer ist, darf überhaupt ein Zugriff über ihn erfolgen!'''&lt;br /&gt;
&lt;br /&gt;
==Vergleich von Variablen==&lt;br /&gt;
Skalare Variablen (also ganze Zahlen, Gleitkommazahlen, Zeiger) können miteinander verglichen werden. Dazu gibt es die folgenden Operatoren in C: &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; || ist nicht gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;=&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;=&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das Ergebnis der Auswertung ist eine ganze Zahl. Ist die Bedingung erfüllt, dann ist der Wert ungleich&amp;amp;nbsp;0. Ist die Bedingung nicht erfüllt, dann ist ihr Wert gleich&amp;amp;nbsp;0.&lt;br /&gt;
Meistens wird man diese Operatoren in &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Konstrukten finden wie zum Beispiel&lt;br /&gt;
 if (x &amp;gt;= 10)&lt;br /&gt;
    x = 10;&lt;br /&gt;
oder in Abbruchbedingungen von Schleifen, wie sie weiter unten erklärt werden.&lt;br /&gt;
&lt;br /&gt;
Es ist auch möglich, das Ergebnis der Auswertung in einer &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Variablen zu speichern:&lt;br /&gt;
 int i;&lt;br /&gt;
 int z1, z2;&lt;br /&gt;
 &lt;br /&gt;
 z1 = 5;&lt;br /&gt;
 z2 = 100;&lt;br /&gt;
 i = z1 &amp;lt;= z2;  {{comment|Ein Vergleich. i wird &amp;quot;wahr&amp;quot;, da z1 kleinergleich z2 ist}}&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich&amp;amp;nbsp;0 (&amp;quot;wahr&amp;quot;), wenn &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; kleiner oder gleich &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt; ist. Ist &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; jedoch größer als &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt;, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich&amp;amp;nbsp;0 (&amp;quot;unwahr&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
==Arithmetische Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a + b&amp;lt;/tt&amp;gt; || Summe (Addition)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a - b&amp;lt;/tt&amp;gt; || Differenz (Subtraktion)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a * b&amp;lt;/tt&amp;gt; || Produkt (Multiplikation)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a / b&amp;lt;/tt&amp;gt; || Quotient (Division, evtl. mit Rest)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a % b&amp;lt;/tt&amp;gt; || Rest bei Division (Modulo)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;-a&amp;lt;/tt&amp;gt; || Vorzeichenumkehr (Zweierkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Bit-Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp; b&amp;lt;/tt&amp;gt; || bitweise und (and)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || bitweise oder (or)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a ^ b&amp;lt;/tt&amp;gt; || bitweise exclusiv-oder (xor, exor)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;~a&amp;lt;/tt&amp;gt; || jedes Bit in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; invertieren (not, Einerkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Index-Operator bei Arrays==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a[b]&amp;lt;/tt&amp;gt; || das (b+1)ste Element des Feldes a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Folgendes gilt es bei der Verwendung des Indexoperators zu beachten:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; muss ein [[C-Tutorial#Felder | Feld]] oder [[C-Tutorial#Zeiger | Zeiger]] sein&lt;br /&gt;
# &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; muss ein Integer sein oder ein Datentyp, der sich in einen int umwandeln läßt (z.B. char)&lt;br /&gt;
# Es wird nicht geprüft, ob der Index &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; im Feld &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gültig ist!&lt;br /&gt;
# Der erste Index eines Feldes ist immer 0. Daher ''(b+1)stes Element'' in der Beschreibung&lt;br /&gt;
&lt;br /&gt;
==Komponenten-Auswahl bei Structs und Unions==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a.b&amp;lt;/tt&amp;gt; || Element b der [[C-Tutorial#Strukturen | Struktur]] oder des Unions a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adress-Operator und Dereferenzierung==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&amp;amp;amp;a&amp;lt;/tt&amp;gt; || Speicheradresse der Variablen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;*a&amp;lt;/tt&amp;gt; || Wert, der an der Adresse &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a-&amp;amp;gt;b&amp;lt;/tt&amp;gt; || Wert des Elements &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; der Struktur, deren Adresse in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Adressoperator &amp;amp; kann auf Variablen angewendet werden und&lt;br /&gt;
gibt die Startadresse der Variablen im Speicher zurück.&lt;br /&gt;
&lt;br /&gt;
Handelt es sich bei einer Variable um einen [[C-Tutorial#Zeiger | Zeiger]], so enthält&lt;br /&gt;
sie eine Speicheradresse. Um an den '''Wert''' zu gelangen, der&lt;br /&gt;
an dieser Adresse steht, wird der Operator * vorangestellt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
&lt;br /&gt;
 {{comment|x ist eine Integervariable und hat den Wert 5}}&lt;br /&gt;
 int x = 5;&lt;br /&gt;
     &lt;br /&gt;
 {{comment|z ist ein Zeiger auf eine Integer-Variable und enthaelt somit}}&lt;br /&gt;
 {{comment|die Speicheradresse einer Integer-Variablen}}&lt;br /&gt;
 int *z;       &lt;br /&gt;
  &lt;br /&gt;
 {{comment|Verwendung des Adress-Operators: weist an z die Adresse von x zu}}&lt;br /&gt;
 z = &amp;amp;x;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Verwendung der Dereferenzierung}}&lt;br /&gt;
 {{comment|erhoehe den Wert, der bei Adresse z steht, um eins}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|da z auf x zeigt, hat x jetzt den Wert 6}}&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff auf Struktir- und Union-Elemente eine abkürzende Schreibweise möglich:&lt;br /&gt;
&lt;br /&gt;
Statt &lt;br /&gt;
  (*strukturZeiger).element&lt;br /&gt;
kann geschrieben werden&lt;br /&gt;
  strukturZeiger-&amp;gt;element&lt;br /&gt;
Beide Schreibweisen sind absolut gleichbedeutend, die Klammern bei der ersteren sind notwendig.&lt;br /&gt;
&lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
:Bei der Dereferenzierung durch &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; findet keine Prüfung statt, ob der Zeiger auch auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu einer Änderung '''irgendeiner''' Speicherstelle!&lt;br /&gt;
&lt;br /&gt;
 int *z; {{comment|z ist ein Zeiger auf einen int}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.}}&lt;br /&gt;
 {{comment|z enthaelt irgendeine ungueltige Adresse!!}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|&amp;quot;Erhoehe einen Integer _irgendwo_ im Speicher um 1&amp;quot; -&amp;gt; CRASH !!!}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
&lt;br /&gt;
==Cast-Operator==&lt;br /&gt;
&lt;br /&gt;
Der Cast Operator dient dazu, den Datentyp eines Wertes zu ändern. Dafür wird einfach der neue Datentyp in Klammern vor den Wert geschrieben.&lt;br /&gt;
&lt;br /&gt;
Um zum Beispiel aus einem Float ein Integer zu machen:&lt;br /&gt;
 var  = (int) 5.60;&lt;br /&gt;
Dabei wird der Wert aber auch gerundet, und es findet somit ein Informationsverlust statt.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Umwandeln einer ganzen Zahl in eine Adresse:&lt;br /&gt;
 int * addr;&lt;br /&gt;
 addr = (int*) 0x1234;&lt;br /&gt;
Damit ist &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; an Adresse 0x1234.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
Der Cast-Operator selbst führt ''keine Konvertierung'' von Darstellungen durch, etwa die Umwandlung der ganzen Zahl 123 ein den String &amp;lt;tt&amp;gt;&amp;quot;123&amp;quot;&amp;lt;/tt&amp;gt;, der diese Zahl darstellt! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
  int main(int argc, char ** argv)&lt;br /&gt;
  {&lt;br /&gt;
        char text[] = &amp;quot;5.6&amp;quot;;&lt;br /&gt;
        int zahl = (int) text;&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, zahl);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Anfangsadresse des Strings &amp;lt;tt&amp;gt;&amp;quot;5.6&amp;quot;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Komma-Operator==&lt;br /&gt;
Mit einem &amp;lt;tt&amp;gt;,&amp;lt;/tt&amp;gt; können mehrere Ausdrücke nacheinander ausgewertet werden.&lt;br /&gt;
Die Auswertung erfolgt von links nach rechts.&lt;br /&gt;
&lt;br /&gt;
Solche Konstrukte sieht man manchmal in Abfragen wie&lt;br /&gt;
 FILE  *file;&lt;br /&gt;
 if (file = fopen (&amp;quot;foo.exe&amp;quot;, &amp;quot;r&amp;quot;), file != NULL)&lt;br /&gt;
was erst an &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; einen Wert zuweist und den &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Block nur betritt,&lt;br /&gt;
wenn &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; nicht der Nullpointer ist.&lt;br /&gt;
&lt;br /&gt;
Bequem kann das auch in einer [[#for-Schleife|for-Schleife]] sein, wenn man zwei (oder mehr) Laufvariablen hat oder so:&lt;br /&gt;
 for (i=0, j=0; i &amp;lt; 10; i++, j += 2)&lt;br /&gt;
    &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Zuweisung===&lt;br /&gt;
=== ++ und -- ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; stellen einfachere Schreibweisen dar zum Addieren bzw. Subtrahieren von&amp;amp;nbsp;1.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; (Inkrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo++; &lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo + 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; 3}}&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; (Dekrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo--;&lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo - 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; -1}}&lt;br /&gt;
&lt;br /&gt;
Die beiden Operatoren können sowohl in der Präfix-Schreibweise (vor der Variablen) als auch als Postfix-Schreibweise (hinter der Variablen) notiert werden. &lt;br /&gt;
Der Unterschied liegt darin, dass beim Präfix der Wert zuerst neu berechnet wird und die Variable dann verwendet wird. Beim Postfix wird die Variable zuerst verwendet und erst nach Auswertung des Ausdrucks, in dem sie enthalten ist, neu berechnet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 int ausgabe1, ausgabe2, var1 = 10, var2 = 10;&lt;br /&gt;
 ausgabe1 = 3 * ++var1; {{comment|ausgabe1 &amp;amp;#61; 33; var1 &amp;amp;#61; 11;}}&lt;br /&gt;
 ausgabe2 = 3 * var2++; {{comment|ausgabe2 &amp;amp;#61; 30; var2 &amp;amp;#61; 11;}}&lt;br /&gt;
&lt;br /&gt;
Für Zeiger arbeiten diese Operatoren etwas anders, siehe dazu [[#Zeiger-Arithmetik|Zeiger-Arithmetik]].&lt;br /&gt;
&lt;br /&gt;
===Bedingter Ausdruck===&lt;br /&gt;
 ({{Bedingung}}) ? {{Ausdruck|1}} : {{Ausdruck|2}}&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; erfüllt ist, dann wertet dieser Ausdruck aus zu &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt;. Ist er nicht erfüllt, dann wertet er aus zu &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 x = (x &amp;gt;= 3) ? 0 : x+1;&lt;br /&gt;
Startet man &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; mit dem Wert 0, dann nimmt es bei mehrfacher Anwendung dieser Zeile (z.B. in einer Schleife) nacheinander die folgende Werte an:&lt;br /&gt;
:&amp;lt;tt&amp;gt;1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, ...&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&lt;br /&gt;
Wie auch in der Mathematik gibt es auch in C genaue Regeln über die Abarbeitungsreihenfolge (precedence)&lt;br /&gt;
der Operatoren. Dass sich alle C-Compiler genau an diesen ANSI-Vorschlag halten, ist leider nicht sicher.&lt;br /&gt;
Sicher jedoch ist, dass nicht jeder Programmierer diese Regel jederzeit im Kopf hat. &lt;br /&gt;
Daher ist es sinnvoll, Ausdrücke durch runde Klammern eindeutig zu kennzeichnen. &lt;br /&gt;
Nebenbei stören sich Compiler nicht an überflüssigen Klammerpaaren.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Priorität ||Operator||Assoziativität&lt;br /&gt;
|-&lt;br /&gt;
  &lt;br /&gt;
|&amp;lt;tt&amp;gt;15&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ( ) [ ] -&amp;gt; . &amp;lt;/tt&amp;gt;                      ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;14&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;! ~ ++ -- + - (TYP) * &amp;amp; sizeof &amp;lt;/tt&amp;gt;    ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;13&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; * / % (Rechenoperationen) &amp;lt;/tt&amp;gt;         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;12&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; + - (binär) &amp;lt;/tt&amp;gt;                       ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;11&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;&amp;lt; &amp;gt;&amp;gt; &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;10&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt; &amp;lt;= &amp;gt; &amp;gt;= &amp;lt;/tt&amp;gt;                         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 9&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; == != &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 8&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp; (bit-AND-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 7&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ^ (bit-XOR-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 6&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; (bit-OR-Operator)&amp;lt;/tt&amp;gt;   ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 5&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp;&amp;amp; &amp;lt;/tt&amp;gt;                                ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 4&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; &amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 3&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;? : &amp;lt;/tt&amp;gt;                               ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 2&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; = += -= /= *= %= &amp;gt;&amp;gt;= &amp;lt;&amp;lt;= &amp;amp;= &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;= ^= &amp;lt;/tt&amp;gt; ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 1&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; , (Sequenz-Operator) &amp;lt;/tt&amp;gt;              ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
&lt;br /&gt;
Peter Baeumle-Courth, ANSI-C im Überblick &amp;lt;p&amp;gt;&lt;br /&gt;
W. Alex, Einführung in C/C++&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
Eine Kontrollanweisung ist eine Anweisung, die Einfluss auf den Programmfluss hat. Normalerweise werden Anweisungen so ausgeführt, wie sie in der Quelldatei stehen: Von links nach rechts (falls mehrere Anweisungen in einer Zeile stehen sollten, wovon i.A. abzuraten ist) und von oben nach unten. Mit einer Kontrollanweisung kann dieser lineare Programmfluss durchbrochen werden: Die Codeausführung kann kann abhängig von einer Bedingung gemacht werden (&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;), kann wiederholt werden (Schleife) oder an einer anderen Stelle der Funktion fortgesetzt werden (&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==if-Anweisung==&lt;br /&gt;
Mit Hilfe des if-Befehls kann man Codeteile abhängig davon einer Bedingung ausführen lassen:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
oder mit else-Teil&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 if (x &amp;gt; 100)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;gt; 100 ist: Fehlerausgabe}}&lt;br /&gt;
    printf (&amp;quot;x = %d ist zu gross fuer die Berechnung!\n&amp;quot;, x);&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;lt;&amp;amp;#61; 100 ist: Berechne Summe der Zahlen 1...x}}&lt;br /&gt;
    {{comment|Die lokale Variable x2 lebt nur innerhalb dieses alse-Blocks}}&lt;br /&gt;
    int x2 = x;&lt;br /&gt;
 &lt;br /&gt;
    for (x = 0; x2 &amp;gt; 0; x2--)&lt;br /&gt;
       x += x2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Wenn die Bedingung wahr ist (&amp;lt;tt&amp;gt;x &amp;gt; 100&amp;lt;/tt&amp;gt;), dann wird eine Meldung ausgegeben; danach ist die if-Anweisung beendet. Der else-Block wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung nicht erfüllt (&amp;lt;tt&amp;gt;x &amp;amp;le; 100&amp;lt;/tt&amp;gt;), dann wird gleich zum else-Teil gesprungen, und nach dessen Ausführung der if-Befehl beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Ein häufiger Fehler ist es, statt &amp;lt;tt&amp;gt;if (a &amp;amp;#61;&amp;amp;#61; 23)&amp;lt;/tt&amp;gt; etwas wie &amp;lt;tt&amp;gt;if (a &amp;amp;#61; 23)&amp;lt;/tt&amp;gt; zu schreiben. &lt;br /&gt;
Dann wird allerdings nicht geprüft, ob die Variable&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gleich 23 ist, sondern der Variablen&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wird der Wert 23 zugewiesen. Der Ausdruck &amp;lt;tt&amp;gt;a &amp;amp;#61; 23&amp;lt;/tt&amp;gt; hat den Wert&amp;amp;nbsp;23 und ist damit immer &amp;quot;wahr&amp;quot;! Daher ist diese if-Bedingung immer erfüllt!&lt;br /&gt;
&lt;br /&gt;
Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken sondern bestenfalls eine Warnung. Damit ist dieser Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise &amp;lt;tt&amp;gt;if (23 &amp;amp;#61;&amp;amp;#61; a)&amp;lt;/tt&amp;gt;. Wenn man dort anstatt des Vergleichsoperators '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;amp;#61;&amp;lt;/tt&amp;gt;' den Zuweisungsoperator '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;lt;/tt&amp;gt;' verwendet, spuckt der Compiler sehr wohl einen Fehler aus! Ist die Zuweisung jedoch erwünscht und eine Compiler-Warnung lästig, dann wählt man eine Schreibweise wie &amp;lt;tt&amp;gt;if ((a &amp;amp;#61; b))&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;if (a &amp;amp;#61; b, a)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist zu schreiben &amp;lt;tt&amp;gt;if (Bedingung);&amp;lt;/tt&amp;gt; Richtig muss es heissen &amp;quot;&amp;lt;tt&amp;gt;if(Bedingung)&amp;lt;/tt&amp;gt;&amp;quot; Das Semikolon im ersten Fall ist eine leere Anweisung, die im if-Falle ausgeführt wird &amp;amp;ndash; sie bleibt also ohne Resultet. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt; ein auf das Semikolon folgende Anweisung die eigentlich zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören soll wird immer ausgeführt, die sie nicht mehr zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; dazu gehört.&lt;br /&gt;
}}&lt;br /&gt;
Bei verschachtelten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Konstrukten gehört ein &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zu letzten &amp;quot;freien&amp;quot; &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;. Soll in einer &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Folge das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zum ersten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören, dann ist das so zu hinzuschreiben:&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Ohne die geschweiften Klammern um das zweite &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehörte das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; dort hinzu.&lt;br /&gt;
&lt;br /&gt;
==switch-Anweisung==&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
&lt;br /&gt;
 switch ({{Ausdruck|}}) &lt;br /&gt;
 {&lt;br /&gt;
     case konstante1:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
    &lt;br /&gt;
     case konstante2:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 &lt;br /&gt;
     {{comment|weitere case-Marken}}&lt;br /&gt;
 &lt;br /&gt;
     default:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 } {{comment|Ende von switch}} &lt;br /&gt;
&lt;br /&gt;
Der Ausdruck muss ein skalarer Typ sein, er wird in die nächste ganze Zahl gewandelt und mit den Werten hinter den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Marken verglichen. Bei einer Übereinstimmung werden alle Befehle ab dem zutreffenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; ausgeführt. Stimmt der Ausdruck mit keinem der Werte überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt falls vorhanden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der nachfolgenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;- und des &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitts werden ausgeführt, wenn die Anweisungen des &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitts nicht mit dem Befehl &amp;lt;tt&amp;gt;break;&amp;lt;/tt&amp;gt; beendet werden!&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es dürfen beliebig viele &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitte angegeben werden, pro Vergleichswert jedoch nur einer.&lt;br /&gt;
Der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ist optional. Die Reihenfolge, in der &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt; angegeben werden, ist unerheblich.&lt;br /&gt;
&lt;br /&gt;
==Schleifen==&lt;br /&gt;
Um Anweisungen mehrmals hintereinander auszuführen, benötigt man Schleifen. Diese führen Anweisungen aus, bis oder solange Bedingungen erfüllt sind.&amp;lt;br&amp;gt; &lt;br /&gt;
Wichtig ist also, ob die Bedingung '''vor''' oder '''nach''' den Schleifen-Anweisungen geprüft wird. &lt;br /&gt;
&lt;br /&gt;
===while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 while ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Die while-Schleife wird solange durchlaufen, wie die Bedingung erfüllt ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Die Anweisung kann natürlich auch ein Block sein, der aus mehreren Deklarationen und Anweisungen besteht. &lt;br /&gt;
&lt;br /&gt;
 int zahl1 = 0;&lt;br /&gt;
 int zahl2 = 1;&lt;br /&gt;
 &lt;br /&gt;
 while (zahl1 &amp;lt; 3)&lt;br /&gt;
 {&lt;br /&gt;
    zahl1 = zahl1 + 1;&lt;br /&gt;
    zahl2 = zahl2 * 2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife drei mal durchlaufen. Zu Beginn des vierten Durchlaufs ist die Bedingung nicht mehr erfüllt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
&lt;br /&gt;
===do-while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
Die do-while-Schleife wird auf jeden Fall einmal durchlaufen und dann solange wiederholt, wie die Bedingung erfüllt ist.&lt;br /&gt;
 int i = 2;&lt;br /&gt;
 &lt;br /&gt;
 do &lt;br /&gt;
 {&lt;br /&gt;
     i = i*i;   {{comment|i quadrieren}}&lt;br /&gt;
     printf (&amp;quot;i = %d\n&amp;quot;, i);&lt;br /&gt;
 }&lt;br /&gt;
 while (i &amp;lt; 20);&lt;br /&gt;
&lt;br /&gt;
Die Schleife wird durchlaufen und wiederholt, solange &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; kleiner als 20 ist. Es werden also nacheinander die Werte 2, 4 und 16 ausgegeben. Nach der Schleife hat&amp;amp;nbsp;&amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; den Wert 256.&lt;br /&gt;
&lt;br /&gt;
===for-Schleife===&lt;br /&gt;
'''Syntax:''' &lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Bei den Ausdrücken wird es sich um einen Ausdrücke mit Nebeneffekt handeln wie etwa &amp;lt;tt&amp;gt;i=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;i=i+2&amp;lt;/tt&amp;gt;. Es werden folgende Aktionen ausgeführt:&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# falls die Bedingung wahr ist, dann führe &amp;lt;tt&amp;gt;Anweisung&amp;lt;/tt&amp;gt; aus.&lt;br /&gt;
# falls die Bedingung unwahr ist, dann sprinte zu 7 (Ende).&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# gehe zu 2&lt;br /&gt;
# nächste Anweisung nach der for-Schleife&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int lauf, summe;&lt;br /&gt;
 &lt;br /&gt;
 for (lauf=1, summe=0; lauf &amp;lt;= 10; lauf += 2) &lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel ist &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; ein [[#Komma-Operator|Komma-Ausdruck]], der zwei Anweisungen kombiniert und daher sogar zwei Nebeneffente hat: er setzt &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;1 und &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;0.&lt;br /&gt;
&lt;br /&gt;
Das Äquivalent als while-Schleife:&lt;br /&gt;
&lt;br /&gt;
 int lauf  = 1;                 {{comment|Anfangswerte}}&lt;br /&gt;
 int summe = 0;&lt;br /&gt;
 &lt;br /&gt;
 while (lauf &amp;lt;= 10)             {{comment|Bedingung}}&lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
    lauf  += 2;                 {{comment|Inkrement}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; in jedem Schleifendurchlauf um die Laufvariable &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; erhöht. Da &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nacheinander die ungeraden Werte von&amp;amp;nbsp;1 bis&amp;amp;nbsp;10 annimmt, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von&amp;amp;nbsp;1 bis kleinergleich 10 gespeichert, also der Wert&amp;amp;nbsp;25. &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; hat nach der Schleife den Wert&amp;amp;nbsp;11.&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf = 1&amp;lt;/tt&amp;gt; bedeutet, dass der Variablen &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; vor dem ersten Schleifendurchlauf der Wert&amp;amp;nbsp;1 zugewiesen wird. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf &amp;lt;= 10&amp;lt;/tt&amp;gt; ist die Schleifenbedingung; ist sie nicht erfüllt, wird die Schleife beendet. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf += 2&amp;lt;/tt&amp;gt; bedeutet, dass &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nach jedem Durchlauf um&amp;amp;nbsp;2 erhöht wird.&lt;br /&gt;
&lt;br /&gt;
===continue-Anweisung===&lt;br /&gt;
Innerhalb einer Schleife darf die &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die nachfolgenden Anweisungen übersprungen werden und mit dem nächsten Schleifendurchlauf fortgesetzt wird &amp;amp;ndash; vorausgesetzt die Schleifenbedingung ist noch erfüllt. Ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; etc. stehen, wenn dieses innerhalb einer Schleife steht.&lt;br /&gt;
&lt;br /&gt;
==break-Anweisung==&lt;br /&gt;
Innerhalb einer Schleife oder eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; darf die &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die Schleifen-/Switch-Anweisung sofort verlassen wird und das Programm dahinter weiter macht. Bei mehrfach geschachtelten Schleifen wird nur die innere verlassen. Ein &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; stehen, wenn dieses innerhalb einer Schleife/Switch-Anweisung steht.&lt;br /&gt;
&lt;br /&gt;
==goto-Anweisung==&lt;br /&gt;
&lt;br /&gt;
Innerhalb ein und derselben Funktion kann mit &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; an eine andere Stelle gesprungen werden. Dazu gibt man hinter dem &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einen Bezeichner an, der dadurch als Label fungiert:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 goto {{Bezeichner}};&lt;br /&gt;
Die Bezeichner selbst steht irgendwo in der Funktion und wird dadurch zur Sprungmarke (Label), daß er von einem Doppelpunkt (und mindestens einer C-Anweisung, die auch leer sein darf) gefolgt wird.&lt;br /&gt;
&lt;br /&gt;
Das Beispiel durchsucht das 2-dimensionale &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array &amp;lt;tt&amp;gt;feld&amp;lt;/tt&amp;gt; mit den &amp;lt;tt&amp;gt;SIZE_X &amp;amp;times; SIZE_Y&amp;lt;/tt&amp;gt; Werten nach dem Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;. Wird er gefunden, dann wird die 2-fach geschachtelte Suchschleife verlassen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int x, y;&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y; y++)&lt;br /&gt;
       if (feld[x][y] == 0)&lt;br /&gt;
          goto done;&lt;br /&gt;
 {{Label|done:}};&lt;br /&gt;
&lt;br /&gt;
Der folgende Code hat die gleiche Funktion, arbeitet jedoch ohne &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int x, y;&lt;br /&gt;
 int found = 0; {{comment|FALSE}}&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X &amp;amp;&amp;amp; !found; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y &amp;amp;&amp;amp; !found; y++)&lt;br /&gt;
       found = (0 == feld[x][y]);&lt;br /&gt;
Der Nachteil der &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-losen Variante ist, daß man eine Variable, die merkt, ob das Suchziel gefunden wurde, mitschleppen und in ''jedem'' Schleifendurchlauf abtesten muss. Dies bedeutet einen höheren Programmier- und Laufzeitaufwand und ist nicht so klar formuliert wie das &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-Beispiel.&lt;br /&gt;
&lt;br /&gt;
Gleichwohl sei angemerkt, daß die Verwendung von &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einem gewissen Dogmatismus unterliegt, der sich wie folgt subsummieren liesse:&lt;br /&gt;
:''goto ist böse und sollte keinesfalls verwendet werden! Wer es dennoch tut, offenbart dadurch seinen schlechten Geschmach sowie mangelhafte C-Kenntnis.'' &amp;lt;div align=&amp;quot;right&amp;quot;&amp;gt;http://www.roboternetz.de/phpBB2/images/smiles/icon_wink.gif&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Funktionen=&lt;br /&gt;
Stellen Dir vor, Du hast eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben &amp;amp;ndash; was Dich Zeit beim Erstellen des Programms und Speicherplatz im ausführbaren Programm kostet &amp;amp;ndash; kannst Du den Code-Abschnitt in eine Funktion schreiben und diese von jeder Stelle des Programms aus verwenden. Die Hauptgründe, um Funktionen zu verwenden, sind:&lt;br /&gt;
;Wiederverwendung von Code: Mehrfach verwendete Codestücke müssen nicht mehrfach implementiert werden. Oft unterscheiden sich die Codesequenzen nur in Kleinigkeiten, die man der Funktion über Parameter mitteilen kann.&lt;br /&gt;
;Übersichtlichkeit: Ein gut gegliedertes C-Programm implementiert klar umrissene Aufgaben in einer Funktion, auch wenn diese Funktion nur einmal im Code aufgerufen wird! Dadurch bleibt der Code um die Aufrufstelle besser verständlich, und man kann auf verschiedenen &amp;quot;Ebenen&amp;quot; denken. Eine Funktion wie &amp;quot;Datei öffnen&amp;quot; kann recht komplex sein. Auf höherer Ebene interessieren die Innereien nicht mehr, man möchte sich um andere Dinge kümmern und will den Code an der Stelle garnicht sehen...&lt;br /&gt;
;Rekursive Funktionen: Eine Funktion kann sich auch selbst aufrufen. In dem Falle nennt man die Funktion ''rekursiv''. Zwar lässt sich das, was eine rekursive Funktion tut, auch mit anderen Mitteln formulieren, die keine rekursiven Funktionen brauchen, aber oft ist der rekursive Weg knackiger und klarer formulierbar als eine nicht-rekursiven Ansatz, auch wenn es etwas mehr Resourcen verbraucht.&lt;br /&gt;
;Modulare Programmierung: Funktionen können anhand ihres Aufgabenbereichs auf verschiedene C-Quellen &amp;amp;ndash; sogenannte ''Module'' &amp;amp;ndash; verteilt werden. Funktionen, die etwas mit dem USB-Bus anstellen, werden in einem anderen Modul sein als mathematische Funktionen. Dies erhöht die Übersichtlichkeit und vereinfacht die Entwicklung im Team.&lt;br /&gt;
;Bibliotheken: Standard-Funktionen wie das hier oft auftauchende &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; sind in Bibliotheken gespeichert. Wenn das eigene Programm übersetzt wird, dann müssen nicht mehr alle Standard-Funktionen übersetzt werden, sondern werden nur noch aus der Bibliothek gelesen und ihr Code zum Programm dazugelinkt. Die Bibliotheks-Funktionen wurden schon zu einem früheren Zeitpunkt compiliert und liegen in dieser compilerten Form in der Bibliothek. Das spart mächtig Entwicklungszeit. Man kann auch selbst solche Bibliotheken erstellen und in diversen Projekten wiederverwenden.&lt;br /&gt;
;Generische Programmierung: In C ist es möglich, einer Funktion eine andere Funktion zu übergeben. (Damit ist nicht gemeint, ihr deren ''Rückgabewert'' zu übergeben (was auch ginge), sondern ''die Funktion selbst'' wird als Parameter übergeben und kann aufgerufen werden.) Ein typisches Beispiel dafür sind Sortieralgorithmen. Einem Sortieralgorithmus kann es egal sein, ''was'' er sortiert. Er muss lediglich wissen, ''wie'' er das Zeug zu sortieren hat: aufsteigend, absteigend, als Zahl, in lexikographischer Ordnung, nach der Quersumme, Körper nach Oberfläche, Durchmesser, Gewicht oder Volumen... Diese Vergleichsfunktion, die für zwei Objekte entscheidet, welches davon &amp;quot;kleiner&amp;quot; ist, kann man dem Sortierer übergeben. Will er zwei Werte vergleichen, dann muss er nur die Vergleichsfunktion aufrufen, ohne zu wissen, was diese tut. Damit kann der Sortieralgorithmus unanhängig von den Objekten gehalten werden, mit denen er hantieren soll.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Definition==&lt;br /&gt;
&lt;br /&gt;
In der ''Definition'' der Funktion wird gesagt, welche Werte sie liefern kann, wie sie heisst (Bezeichner) und wieviele und welche Parameter sie hat. Danach folgt ihre Implementierung:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}} ({{Parameterliste}})&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 &lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
Für Funktionen, die keinen Wert zurückliefern, gibt es den speziellen Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der besagt, daß die Funktion nichts zurückgibt. Die einfachste denkbare Funktion ist eine solch void-Funktion. Sie bekommt keine Parameter, gibt nicht zurück und ihr Body ist leer:&lt;br /&gt;
 void dummy()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==return-Anweisung==&lt;br /&gt;
An jeder Stelle des Programmflusses einer Funktion kann diese mit &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; beendet werden.&lt;br /&gt;
&lt;br /&gt;
'''bei void-Funktionen:'''&lt;br /&gt;
 return;&lt;br /&gt;
'''Funktionen mit Rückgabe-Wert:'''&lt;br /&gt;
 return {{Ausdruck|}};&lt;br /&gt;
Die zweite Variante gibt an, welcher Wert zurückgegeben wird.&lt;br /&gt;
 int main (int argc, char * argv[])&lt;br /&gt;
 {&lt;br /&gt;
    if (argc &amp;lt; 2)&lt;br /&gt;
       return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
Falls die letzte Anweisung einer void-Funktion ein &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; ist, kann es auch weggelassen werden wie oben bei der Funktion &amp;lt;tt&amp;gt;dummy&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Aufruf==&lt;br /&gt;
Um die Funktion aufzurufen gibt man ihren Namen an, gefolgt von den durch Komma getrennten Argumenten in runden Klammern wie im Beispiel unten das&lt;br /&gt;
 quadrat (5) &lt;br /&gt;
Da &amp;lt;tt&amp;gt;quadrat&amp;lt;/tt&amp;gt; einen Wert liefert, kann man damit weiter rechnen wie mit einem normalen Ausdruck:&lt;br /&gt;
 if (quadrat (a) + quadrat (b) == quadrat (c))&lt;br /&gt;
    c = quadrat (quadrat (a)); {{comment|c &amp;amp;#61; a hoch 4}}&lt;br /&gt;
&lt;br /&gt;
;Ein Hinweis am Rande: &lt;br /&gt;
Der Name einer Funktion ohne die beiden runden Klammern ist der Pointer/Zeiger auf ihren Anfang.&lt;br /&gt;
Damit kann ein Funktionsname überall dort verwendet werden, wo Pointer/Zeiger &lt;br /&gt;
zulässig sind. Insbesondere kann er als Argument einer weiteren Funktion dienen. &lt;br /&gt;
&lt;br /&gt;
'''Quelle:'''&lt;br /&gt;
W. Alex, Einführung in C/C++&lt;br /&gt;
&lt;br /&gt;
==Rekursive Funktionen==&lt;br /&gt;
Eine Funktion die sich selbst &amp;amp;ndash; möglicheweise auch über andere Zwischenfunktionen &amp;amp;ndash; wieder selbst aufruft, wird als ''rekursive Funktion'' bezeichnet. In der Definition ist nichts besonderes zu beachten. Ist die Verschachtelungstiefe im laufenden Programm zu tief, dann gibt das natürlich Probleme, aber das gilt bei tief verschachtelten 'normalen' Funktionen abenso...&lt;br /&gt;
&lt;br /&gt;
Das Beispiel berechnet den Größten Gemeinsamen Teiler zweier Zahlen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int ggT (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
     if (0 == a)&lt;br /&gt;
        return b;&lt;br /&gt;
 &lt;br /&gt;
    return ggT (b % a, a);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Ein komplettes kleines Programm:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int quadrat (int param1)&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  zahl = param1 * param1;&lt;br /&gt;
  return zahl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl, ergebnis;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Bitte Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = quadrat (zahl);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, zahl, ergebnis);&lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, 5, quadrat (5));&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur ausserhalb von Blöcken. Geschachtelte Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen beim Aufruf die Klammern angeben werden:&lt;br /&gt;
 dummy();&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Prototypen==&lt;br /&gt;
Wie oben erwähnt, kann ein Unterprogramm an jeder beliebigen Stelle im Programm stehen. Damit ist jedoch eine Bedingung verknüpft: Das Unterprogramm muß in der Datei oberhalb des ersten Aufrufes definiert worden sein. Wenn Sie ein Unterprogramm in Zeile 10 zum ersten mal aufrufen, müssen Sie die Deklaration davor erledigt haben. Verstanden?&lt;br /&gt;
Um dies zu erreichen, gibt es zwei Möglichkeiten: &lt;br /&gt;
&lt;br /&gt;
Entweder Sie schreiben alle Unterprogramme vor &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; in die Datei. Dies muß jedoch wiederum so geschehen, dass Funktionen zum Zeitpunkt ihres Aufrufes bereits bekannt sind! &lt;br /&gt;
Wo dies nicht möglich ist (z.B. sich gegenseitig aufrufende Unterprogramme), oder wenn Sie das stört, müssen Sie Prototypen verwenden. &lt;br /&gt;
Wie definiert man nun Prototypen? Sie kopieren einfach die erste Zeile des Unterprogrammes (z.B. &amp;quot;&amp;lt;tt&amp;gt;void ausgeben (int zahl)&amp;lt;/tt&amp;gt;&amp;quot;), fügen einen Strichpunkt&amp;amp;nbsp;&amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;an und fügen es an einer geeigneten Stelle ein (so, dass alle Aufrufe später in der Datei kommen). &lt;br /&gt;
Solche Definitionen stehen gewöhnlich am Anfang der Quelldatei oder in einer Header-Datei, die eingebunden wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl);  /* Der Prototyp */&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
   ausgeben (12);&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl)   /* Die eigentliche Prozedur */&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Ausgabe: %d\n&amp;quot;, zahl);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Parameterübergabe==&lt;br /&gt;
&lt;br /&gt;
Alle Werte, die an Prozeduren und Funktionen übergeben werden, werden grundsätzlich '''kopiert'''.&lt;br /&gt;
Das hat folgende Auswirkungen:&lt;br /&gt;
&lt;br /&gt;
# Änderungen an einem Parameter in einer Funktion erscheinen ''nicht'' beim Aufrufer!&lt;br /&gt;
# Möchte man, dass eine Funktion einen Wert trotzdem dauerhaft ändern soll, so muss die Adresse des Wertes via [[#Zeiger|Zeiger]] übergeben werden.&lt;br /&gt;
# Werden [[#Strukturen|Strukturen]] übergeben, so wird von ihnen eine Kopie erstellt, was bei großen Strukturen viel Zeit und Arbeitsspeicher kostet. Deshalb wird häufig nur die Adresse von Strukturen übergeben, da die Adresse viel schneller und platzsparender als die Struktur selbst kopiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele:'''&lt;br /&gt;
 void erhoehe (int x)&lt;br /&gt;
 {&lt;br /&gt;
    x = x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe(a);&lt;br /&gt;
    {{comment|a ist immer noch 0}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Beim Aufruf von &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; wird eine Kopie des Wertes von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; (im Beispiel also 0) erstellt und der Prozedur als Parameter &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; übergeben. Weil dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat dies keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|erhoehe den Wert an der Adresse x um eins}}&lt;br /&gt;
    *x = *x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe (&amp;amp;a);&lt;br /&gt;
    {{comment|a ist jetzt 1}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Jetzt wird im Hauptprogramm mittels [[#Adress-Operator und Dereferenzierung|Adress-Operator]] &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; die Speicheradresse von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; bestimmt. Dann wird eine ''Kopie der Adresse'' an das Unterprogramm &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; übergeben. Jetzt kennt das Unterprogramm die&lt;br /&gt;
Adresse des Originals &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und kann direkt mit dem Inhalts-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&lt;br /&gt;
'''Besonderheit bei Feldern'''&lt;br /&gt;
&lt;br /&gt;
Bei der Übergabe von [[#Felder|Feldern]] gibt es eine Besonderheit. Schreibt man nämlich den Namen eines Feldes, so ist das nichts anderes als die '''Speicheradresse des ersten Elements'''.&lt;br /&gt;
Bei der Übergabe eines Feldes wird also eine Kopie der Startadresse übergeben. Somit kann das Unterprogramm auf den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 void erhoehe (int x[])&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
   int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
   erhoehe (a);&lt;br /&gt;
   {{comment|a hat jetzt folgenden Inhalte: 11, 23, 35}}&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Dass die Übergabe einer Adresse erfolgt, sieht man an folgendem Beispiel, das von der Funktionsweise '''absolut identisch''' mit dem vorhergehenden ist:&lt;br /&gt;
&lt;br /&gt;
 {{comment|Bei Parametern gibt es keinen Unterschied zwischen Zeiger und Feld}}&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
    int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
    erhoehe (a);&lt;br /&gt;
 &lt;br /&gt;
    {{comment|a hat jetzt folgenden Inhalt: 11, 23, 35}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
Die Länge des Feldes wird nicht automatisch übergeben. Dafür ist ggf. ein zusätzlicher Parameter notwendig.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Variable Argumentanzahl==&lt;br /&gt;
== Funktionen indirekt aufrufen ==&lt;br /&gt;
Siehe [[#Zeiger auf Funktionen|Zeiger auf Funktionen]]&lt;br /&gt;
&lt;br /&gt;
=Zeiger II=&lt;br /&gt;
&lt;br /&gt;
Zeiger haben wir bereits weiter oben kennen gelernt. Zeiger sind ein zentrales Konzept in C und sollen hier etwas eingehender behandelt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger-Arithmetik==&lt;br /&gt;
In C kann man den Wert eines Zeigers verändern. Betrachten wir dazu die Funktion &amp;lt;tt&amp;gt;suche_0&amp;lt;/tt&amp;gt;, die einen Zeiger auf einen &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; erhält. Die Funktion soll ab der gegebenen Adresse nach dem ersten long-Wert suchen, der 0 ist, und dessen Adresse zurückgeben:&lt;br /&gt;
 long * suche_0 (long * addr)&lt;br /&gt;
 {&lt;br /&gt;
    while (*addr != 0)&lt;br /&gt;
       addr = addr + 1;&lt;br /&gt;
 &lt;br /&gt;
    return addr;&lt;br /&gt;
 }&lt;br /&gt;
In der Bedingung der while-Schleife wird der Inhalt an der Speicherstelle &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf 0 getestet. Ist der Wert 0, dann wird die Schleife beendet und die Adresse zurückgeliefert. Ist der Wert ungleich 0, dann wird &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf den nächste long gesetzt, &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; also um 4 Bytes weitergezählt. &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ist ja ein Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, und ein &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; ist 4 Bytes lang.&lt;br /&gt;
&lt;br /&gt;
Die Bedeutung von&lt;br /&gt;
 address + n&lt;br /&gt;
ist also, die Adresse um das &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;-fache der Größe des Typs, auf den &amp;lt;tt&amp;gt;address&amp;lt;/tt&amp;gt; zeigt, zu erhöhen. Dabei ist &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; eine ganze Zahl und darf auch negativ sein.&lt;br /&gt;
&lt;br /&gt;
Hier noch ein Beispiel einer Funktion, die nach einer Person mit einer bestimmten ID sucht (für die Definition von &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; siehe [[#Strukturen|Strukturen]]). Der Parameter &amp;lt;tt&amp;gt;person&amp;lt;/tt&amp;gt; ist dabei ein Array von Strukturen. Eine Person mit der gesuchten ID muss existieren, ansonsten hat die Suchfunktion kein definiertes Verhalten.&lt;br /&gt;
 {{comment|Sucht nach einer Person mit der ID person_id}}&lt;br /&gt;
 struct Person * &lt;br /&gt;
 suche_person_id (struct Person * person, int person_id)&lt;br /&gt;
 {&lt;br /&gt;
    while (person-&amp;gt;id != person_id)&lt;br /&gt;
       person++;&lt;br /&gt;
 &lt;br /&gt;
    return person;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:1em; padding:1em; border:solid 2px #FF0040;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- Vorlage:FarbigerRahmen funzt hier net --&amp;gt;&lt;br /&gt;
Beachte, daß es nicht sinnvoll ist, zwei Zeiger zu addieren oder zu multiplizieren. Ausserdem ist das &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt; der Zeiger-Arithmetik nicht kommutativ. Eine Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, der an Adresse 1 im Speicher zeigt, wird man schreiben als&lt;br /&gt;
 (long *) 1&lt;br /&gt;
Addiert man darauf eine ganze Zahl, dann haben die entstehenden Ausdrücke unterschiedliche Werte:&lt;br /&gt;
 (long *) 1 + 2    {{comment|zeigt zu Adresse 9}}&lt;br /&gt;
 (long *) 2 + 1    {{comment|zeigt zu Adresse 6}}&lt;br /&gt;
 (long *) (1 + 2)  {{comment|zeigt zu Adresse 3}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==void-Pointer==&lt;br /&gt;
Eine besondere Art von Zeiger ist der void-Pointer&lt;br /&gt;
 void * addr;&lt;br /&gt;
Ein void-Pointer ist ein &amp;quot;Zeiger auf irgendwas&amp;quot;, dementsprechend kann er nicht dereferenziert werden, Anwenden von &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf einen solchen Zeiger gibt also einen Fehler. Ausserdem ist es nicht möglich, mit einem void-Pointer Zeigerarithmetik zu machen, weil er nicht auf eine definierte Art von Objekt zeigt. Der Vorteil eines void-Pointers ist, daß er jede Art von Zeiger aufnehmen kann.&lt;br /&gt;
&lt;br /&gt;
Dazu betrachten wir die Funktion &amp;lt;tt&amp;gt;send_buf&amp;lt;/tt&amp;gt;, die eine Adresse erhält und ab dieser Adresse &amp;lt;tt&amp;gt;num&amp;lt;/tt&amp;gt; Bytes versenden soll. Wir könnten die Funktion so schreiben:&lt;br /&gt;
 void send_buf (unsigned char * buf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   ...&lt;br /&gt;
Das ist jedoch hässlich, wenn wir damit etwas anderes verschicken wollen als &amp;lt;tt&amp;gt; unsigned char&amp;lt;/tt&amp;gt;, etwa eine Struktur wie &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; (vom Typ &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;):&lt;br /&gt;
 send_buf ((unsigned char*) &amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
Ohne den Cast der Adresse von &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; zu einem Zeiger auf &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt; bekommt man eine Warnung oder gar einen Compilerfehler.&lt;br /&gt;
Dieses Zeiger gecaste ist mühsam und hässlich, es muss bei jedem Aufruf der Funktion explizit hingeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Besser ist es, den ersten Parameter der Funktion als void-Pointer zu definieren und den Cast in der Funktion zu machen:&lt;br /&gt;
 void send_buf (void * vbuf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   unsigned char *buf = (unsigned char*) vbuf;&lt;br /&gt;
   ...&lt;br /&gt;
Durch den Cast in der Funktion kann auf den Inhalt des Zeigers zugegriffen werden. Man muss nur festlegen, ''wie'' man zugreifen will, nämlich als &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Der Aufruf kann jetzt ohne Pointer-Cast erfolgen: &lt;br /&gt;
 send_buf (&amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
&lt;br /&gt;
==Null-Pointer==&lt;br /&gt;
==Zeiger als Parameter==&lt;br /&gt;
Wenn Sie ein Unterprogramm aufrufen, können Sie diesem Parameter übergeben, aber keine Werte zurückgekommen (außer den Funktionswert bei Funktionen). Dies hat einen guten Grund: beim Aufruf werden nicht die aufgerufenen Parameter benutzt, sondern es werden deren Werte in neue Variablen kopiert. Diese Variablen werden am Ende des Unterprogrammes &amp;quot;zerstört&amp;quot;, ohne ihre Werte an die aufrufenden Parameter zu übergeben. Jede Veränderung eines Parameters hat daher keine Auswirkung auf den Parameter.&lt;br /&gt;
&lt;br /&gt;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der C-Compiler legt dann immer noch Kopien an. In dieser Kopie steht aber kein Wert, sondern die Adresse einer Varaiblen. Und auf diese können Sie dann zugreifen. Denken Sie nur an &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; &amp;amp;ndash; da übergeben Sie ja auch die Adresse einer Variablen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void erhoehe (int *zeiger)&lt;br /&gt;
{&lt;br /&gt;
  *zeiger = 1 + *zeiger;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  erhoehe (&amp;amp;zahl);&lt;br /&gt;
  printf (&amp;quot;\nDie erhoehte Zahl lautet: %d\n&amp;quot;, zahl);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Zeiger auf Funktionen==&lt;br /&gt;
&lt;br /&gt;
Stell dir vor, du willst einen Sortieralgorithmus wie Bubble-Sort oder Quick-Sort oder wie sie alle heissen implementieren. Für den Sortieralgorithmus ist eigentlich egal, ''was'' er zu sortieren hat. Ihm ist es egal, ob er Zahlen aufwärts sortieren soll oder Strings in lexikographischer Reihenfolge, ob Objekte nach Größe oder Gewicht, Personen nach Alter oder Adressen nach Postleitzahl. Das einzige, was der Algorithmus wissen muss, ist ''wie'' er zwei Objekte zu vergleichen hat und wann eines davon &amp;quot;kleiner&amp;quot; (im Sinne der Ordnung, nach der sortiert werden soll) ist. &lt;br /&gt;
&lt;br /&gt;
Eine einfache Sortierfunktion, die nur zwei Zahlen sortiert, könnte man also so schreiben: &lt;br /&gt;
 {{comment|Sortiert ein Array von 2 int-Zeigern nach den Inhalten &lt;br /&gt;
  * an den Zeiger-Adressen}}&lt;br /&gt;
 void sort2_a (int * p[])&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Inhalte vergleichen...}}&lt;br /&gt;
    if (*p[0] &amp;gt; *p[1])&lt;br /&gt;
    {&lt;br /&gt;
       {{comment|... und ggf. Dreieckstausch der 2 Zeiger}}&lt;br /&gt;
       int * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Die Funktion bekommt ein Array der Länge&amp;amp;nbsp;2. In diesem Array stehen Zeiger auf die zu sortierenden Zahlen. Ein Array mit Zeigern zu verwenden und nicht ein Array von &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; scheint recht umständlich, und das ist es hier auch. Aber stell dir vor, du willst Strukturen wie &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; sortieren. Das Tauschen zweier Strukturen würde bedeuten, ihre kompletten Inhalte umzukopieren! Das wäre sehr aufwändig. Viel einfacher ist das Kopieren, wenn nur die Adressen zu kopieren sind.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; könnte dann so aussehen:&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void sortiere (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|p[] enthält 2 int-Zeiger: die Adressen von a und b}}&lt;br /&gt;
    int * p[2];&lt;br /&gt;
    p[0] = &amp;amp;a; &lt;br /&gt;
    p[1] = &amp;amp;b; &lt;br /&gt;
 &lt;br /&gt;
    {{comment|Sortiere die Zeiger}} &lt;br /&gt;
    sort2_a (p);&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Sortiert: %d, %d\n&amp;quot;, *p[0], *p[1]);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Für den nächsten Schritt überlegen wir uns, daß das Array in &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; ebensogut void-Pointer enthalten kann. Die einzige Stelle, an der wir auf die endgültigen int-Objekte zugreifen, ist der Vergleich. Diesen Vergleich lagern wir in die Funktion &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; aus:&lt;br /&gt;
 {{comment|Bekommt zwei void-Pointer und vergleicht die Inhalte.&lt;br /&gt;
  * Liefert 0 bei Gleichheit,&lt;br /&gt;
  * -1 wenn der erste Wert kleiner ist als der zweite und&lt;br /&gt;
  * 1  wenn der erste Wert größer ist als der zweite}}&lt;br /&gt;
 int compare_int (void * p0, void * p1)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Um über die Zeiger zugreifen zu können müssen wir diese&lt;br /&gt;
     * erst zu int-Zeigern casten}}&lt;br /&gt;
    int a0 = * (int*) p0;&lt;br /&gt;
    int a1 = * (int*) p1;&lt;br /&gt;
 &lt;br /&gt;
    if (a0 &amp;gt; a1)  return  1;&lt;br /&gt;
    if (a0 &amp;lt; a1)  return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void sort2_b (void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare_int (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Ein Aufruf von &amp;lt;tt&amp;gt;sort2_b&amp;lt;/tt&amp;gt; sieht dann genauso aus wie ein Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt definieren wir uns den neuen Datentyp &amp;lt;tt&amp;gt;comparator_t&amp;lt;/tt&amp;gt;. Dieser ist ein Zeiger auf eine Funktion, die zwei void-Pointer erhält und einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; zurückliefert, also analog arbeitet zu &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; von oben. &lt;br /&gt;
&lt;br /&gt;
Unsere Sortierfunktion bekommt nun neben dem zu sortierenden Zeiger-Array auch eine Vergleichsfunktion &amp;lt;tt&amp;gt;compare&amp;lt;/tt&amp;gt; mitgeliefert, die sie aufruft, wenn sie zwei Objekte vergleichen will&lt;br /&gt;
 {{comment|comparator_t sind Zeiger auf Funktionen, die 2 void-Pointer&lt;br /&gt;
  * erhalten und einen int zurückliefern}}&lt;br /&gt;
 typedef int (*comparator_t) (void*, void*);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Der Sortierer bekommt einen Funktionszeiger auf den Vergleicher.&lt;br /&gt;
  * Der Aufruf vom compare geht so als wäre es eine &amp;quot;normale&amp;quot; Funktion&lt;br /&gt;
  * (ist es im Endeffekt ja auch)}}&lt;br /&gt;
 void sort2_c (comparator_t compare, void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Bei einem Aufruf von &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; muss man dann einen Komparator mit angeben. In einem Beispiel analog zu &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; von oben ist das:&lt;br /&gt;
 sort2_c (compare_int, p);&lt;br /&gt;
Um zwei Strings lexikographisch zu sortieren nehmen wie die Standard-Funktion &amp;lt;tt&amp;gt;strcmp&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void foo()&lt;br /&gt;
 {&lt;br /&gt;
    char * worte[] = { &amp;quot;Wort1&amp;quot;, &amp;quot;Wort2&amp;quot; };&lt;br /&gt;
 &lt;br /&gt;
    sort2_c ((comparator_t) strcmp, (void**) worte);&lt;br /&gt;
 }&lt;br /&gt;
Die Casts sind hier erforderlich. Alternativ könnte man &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; mit reinen void-Pointern versorgen und diese dann dort umcasten.&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
&lt;br /&gt;
Die Syntax zur Definition/Deklaration von Funktionszeigern ist etwas verzwackt. Zur Verdeutlichung ein paar Beispiele. Dabei legt das linke &amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt; jeweils den Return-Typ fest.&lt;br /&gt;
 {{comment|definiert einen neuen Funktionszeiger-Typ}}&lt;br /&gt;
 typedef {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert einen Funktionszeiger}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert ein Array von Funktionszeigern (mit Initializer)}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}[]) ({{type}}, {{type}}, ...) = { wert1, wert2, ... };&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer}}&lt;br /&gt;
 ({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer und ruft die Funktion auf}}&lt;br /&gt;
 (({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}) (arg1, arg2, ...);&lt;br /&gt;
&lt;br /&gt;
=Standard-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==String-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===strcpy===&lt;br /&gt;
Bei vielen Compilern können sie einem String nicht direkt einen Wert (Text) zuweisen. Dazu müssen Sie dann die Prozedur strcpy() benutzen. Diese erwartet als ersten Parameter den Namen einer String-Variablen (ohne eckige Klammern) und als zweiten Parameter den eines (anderen) Strings. Letzterer kann auch ein in doppelten Hochkommas (&amp;quot;) eingeschlossener Text sein. Die Funktion fügt am Ende automatisch ein 0-Zeichen ein. Um diese Funktion nutzen zu können, müssen Sie die Datei string.h includieren! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri1[21], eingabe[21];&lt;br /&gt;
&lt;br /&gt;
  strcpy (stri1, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Der 1. String: %s\n&amp;quot;, stri1);&lt;br /&gt;
  printf (&amp;quot;Bitte geben Sie maximal 20 Zeichen ein: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%s&amp;quot;, eingabe);&lt;br /&gt;
  strcpy (stri1, eingabe);&lt;br /&gt;
  printf (&amp;quot;\n%s = %s&amp;quot;, stri1, eingabe);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis:''' &lt;br /&gt;
Da ein String, wie jedes Feld, eigentlich ein Zeiger ist, dürfen Sie kein &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; bei &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; angeben!&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
Es werden zwei gleich große Strings definiert: &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;eingabe&amp;lt;/tt&amp;gt;, mit je 20 &amp;quot;nutzbaren&amp;quot; Zeichen. &lt;br /&gt;
In &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; wird die Zeichenkette &amp;lt;tt&amp;gt;&amp;quot;hallo&amp;quot;&amp;lt;/tt&amp;gt; hineinkopiert. Das 0-Zeichen am Ende wird automatisch angefügt. &lt;br /&gt;
Der String wird ausgegeben. Als neues &amp;quot;Sonderzeichen&amp;quot; kommt &amp;lt;tt&amp;gt;%s&amp;lt;/tt&amp;gt; ins Spiel. Es hat die gleiche Aufgabe wie &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt;, nur für Strings. &lt;br /&gt;
Sie werden gebeten, eine String einzugeben. &lt;br /&gt;
Dieser String wird danach in die Variable &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; kopiert. &lt;br /&gt;
Beide Strings, die ja nun die gleiche Zeichenkette enthalten, werden ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===strlen===&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;strlen&amp;lt;/tt&amp;gt;, die als Parameter eine String-Variable erwartet, liefert die Länge diese Strings zurück. Sie werden jetzt vermutlich sagen: &amp;quot;Das ist doch klar, wie lang der String ist. Ich habe es ja bei der Deklaratin angegeben&amp;quot;. Das stimmt schon, aber denken Sie noch einmal an die null-terminierten Strings. Das 0-Zeichen steht am Ende des Strings (am Ende der gültigen Zeichenfolge), aber nicht unbedingt am Ende des reservierten Speicherplatzes. Haben Sie eine Variable &amp;quot;char Variable[21];&amp;quot;, und ihr den Wert &amp;quot;hallo&amp;quot; zugewiesen, dann steht das null-Zeichen in Variable[5]. Der &amp;quot;gültige&amp;quot; String ist also 5 Zeichen (0-4) lang. Und genau das (5) würde strlen zurück liefern. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri[21];&lt;br /&gt;
  &lt;br /&gt;
  strcpy (stri, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
  printf (&amp;quot;Der String ist %d Zeichen lang&amp;quot;, strlen (stri));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird vor allem gebraucht, wenn Sie direkt auf den String zugreifen, mittels &amp;lt;tt&amp;gt;stri[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;stri[1]&amp;lt;/tt&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
==Ein- und Ausgabe-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===Bildschirm-Ausgabe===&lt;br /&gt;
Bisher war das Tutorial trotz aller Beispiele reine Theorie. Sie konnten zwar Programme schreiben, aber die Funktion nicht testen. Hier lernen Sie nun, wie Sie etwas am Bildschirm ausgeben.&lt;br /&gt;
&lt;br /&gt;
Die dazu notwendige Funktione heisst &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (das '&amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt;' ist kein Fehler!). Diese Anweisung gibt die ihr übergebenen Parameter auf das Standard-Ausgabegerät aus, in der Regel also auf den Bildschirm. Sie kann beliebig viele Parameter übernehmen. Es müssen jedoch Standard-Datentypen (z.B. &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;...) sein! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
    int zahl1 = 12;&lt;br /&gt;
    char zeichen1 = 'A';&lt;br /&gt;
    &lt;br /&gt;
    printf (&amp;quot;Das ist Text, und er wird als solcher ausgegeben. \n&amp;quot;);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zahl1' ist: %d \n&amp;quot;, zahl1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %c \n&amp;quot;, zeichen1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %d \n&amp;quot;, zeichen1);&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt Text aus. Das Zeichen am Ende (&amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;) bedeutet &amp;quot;New Line&amp;quot;, es bewegt den Cursor an den Anfang der nächsten Zeile. &lt;br /&gt;
&lt;br /&gt;
Der zweite &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt auch Text aus, am Ende befindet sich wieder das &amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;, um einen Zeilenvorschub zu erreichen. Das &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; wird vom Compiler durch den ersten Parameter ersetzt, der nach dem Text angegeben wird. In diesem Fall wird &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; also durch den Wert der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ersetzt. Das &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; im &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; bedeutet &amp;quot;Dezimalzahl&amp;quot;, der Computer gibt also eine ganze Zahl aus. &lt;br /&gt;
&lt;br /&gt;
In der dritten Ausgabe wird ein Zeichen ausgegeben. Diesmal bedeutet &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; &amp;quot;char&amp;quot; (Zeichen). Es wird also &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; durch ein &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt; ersetzt, denn die Variable &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; wird als Character interpretiert. &lt;br /&gt;
&lt;br /&gt;
Die letzte Ausgabe interpretiert den Inhalt von &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; als Zahl, und gibt dager den ASCII-Wert von &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, also 65 aus. Das ist ein typisches Beispiel für das mögliche unterschiedliche Interpretieren einer  Variablen!&lt;br /&gt;
&lt;br /&gt;
===Tastatur-Eingabe===&lt;br /&gt;
&lt;br /&gt;
Um ein &amp;quot;gscheites&amp;quot; Programm schreiben zu können, muß man wissen, wie der Benutzer über die Tastatur Befehle eingeben kann. Die dafür notwendigen Funktionen stelle ich in diesem Kapitel vor.&lt;br /&gt;
Die wichtigste Funktion ist &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt;. Er liest Daten von der Tastatur. Die Syntax entspricht derer von &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int  zahl1;&lt;br /&gt;
char zeichen1;&lt;br /&gt;
&lt;br /&gt;
printf (&amp;quot;Bitte geben Sie eine Zahl ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl1);&lt;br /&gt;
printf (&amp;quot;Geben Sie einen Zeichen ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%c&amp;quot;, &amp;amp;zeichen1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Programm gibt eine Eingabeaufforderung aus. Dann erwartet es vom Benutzer, daß er eine Zahl eingibt, die mit [ENTER] bestätigt wird. Dieser Wert wird in &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; abgespeichert. Danach erfolgt wiederum eine Aufforderung zur Eingabe, diesmal eines einzelnen Zeichens. Dieses kann man nun eingeben und ebenfalls mit [ENTER] bestätigen.&lt;br /&gt;
&lt;br /&gt;
Macht man keine dem Datentyp der erwarteten Variable entsprechende Eingabe, dann bricht das Programm mit einer Fehlermeldung ab (wenn man z.B. &amp;quot;1_T2&amp;quot; eingibt, wenn eine Zahl erwartet wird)!&lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; vor den Parametern ist notwendig. Warum, das erfahren Sie im Kapitel &amp;quot;Unterprogramme&amp;quot;. Für die Profis eine Kurz-Erklärung: Das Unterprogramm &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; bekommt zwar einen Wert übergeben, kann aber keinen zurückliefern (&amp;quot;call by value&amp;quot;). Daher wird kein Wert, sondern ein Zeiger auf eine Variable übergeben. Mit dem &amp;amp; Zeichen bekommen Sie die Adresse einer Variablen (&amp;quot;call by reference&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=Parameter von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;=&lt;br /&gt;
Das Unterprogramm &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; kann, wie jede andere Funktion, Parameter besitzen. Doch keine selbst gewählten, sondern nur bestimmte. Doch warum braucht main Parameter? Denken Sie einmal an alle Betriebssystembefehle:&lt;br /&gt;
&amp;lt;tt&amp;gt;dir *.exe &amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;copy *.* a:&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;ls -la &amp;lt;/tt&amp;gt;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen!&lt;br /&gt;
&lt;br /&gt;
=Kurzreferenz=&lt;br /&gt;
==Syntax-Bausteine==&lt;br /&gt;
&lt;br /&gt;
Die Erklärung des Aufbaus von C-Befehlen erfolgt neben einfachen Beispielen auch durch ihren prinzipellen Aufbau. In diesen Syntax-Beschreibungen finden sich immer wieder die gleichen Bausteine, die hier näher erklärt werden sollen. Falls Dir solch ein Syntax-Baustein begegnet, kannst Du ihn anklicken und kommst dann zu seiner Erläuterung. &lt;br /&gt;
&lt;br /&gt;
In den Beispielen selbst gehören auch die spitzen Klammern zu dem Baustein (was daran zu erkennen ist, daß auch die Klammern eingefärbt sind). Die Klammern dürfen in einem konkreten C-Programm daher nicht eingetippt werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bezeichner&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Bezeichner in C dienen dazu, Variablen zu identifizieren und ihnen sprechende Namen zu geben, um die Quelle lesbarer zu machen. Man braucht Bezeichner auch, um selbstdefinierte Datentypen zu benennen und zum Benennen von Struct- und Union-Komponenten sowie als Namen für Funktionen und Sprungmarken (Labels).&lt;br /&gt;
&lt;br /&gt;
Bezeichner dürfen aus den Kleinbuchstaben &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;z&amp;lt;/tt&amp;gt;, den Großbuchstaben &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;Z&amp;lt;/tt&amp;gt;, dem Unterstrich&amp;amp;nbsp;&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt; und den Ziffern &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;9&amp;lt;/tt&amp;gt; aufgebaut werden, wobei an erster Stelle jedoch keine Ziffer stehen darf.&lt;br /&gt;
&lt;br /&gt;
Es wird zwischen Groß- und Kleinschreibung unterschieden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Ausdruck in C ist ein Konstrukt, das einen Wert hat. Ob dieser Wert eine ganze Zahl ist, eine Kommazahl oder ein Zeiger, etc. ist dabei egal. Die einfachsten Ausdrücke sind Konstanten wie&lt;br /&gt;
 2&lt;br /&gt;
oder Variablen wie&lt;br /&gt;
 ein_zahl&lt;br /&gt;
Mehrere Ausdrücke können durch [[#Liste der Operatoren|Operatoren]] zu komplexeren Ausdrücken kombiniert werden, etwa&lt;br /&gt;
 eine_zahl + andere_zahl == 2&lt;br /&gt;
oder &lt;br /&gt;
 eine_zahl = 2&lt;br /&gt;
Letzterer hat den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; und den Nebeneffekt, daß er diesen Wert an &amp;lt;tt&amp;gt;eine_zahl&amp;lt;/tt&amp;gt; zuweist.&lt;br /&gt;
&lt;br /&gt;
Auch der Aufruf einer Funktion, die einen Rückgabewert liefert, ist ein Ausdruck:&lt;br /&gt;
 sin (1.2)&lt;br /&gt;
und kann zum Aufbau komplexerer Ausdrüche verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bedingung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Bedingung ist ein Ausdruck, bei der nur interessiert, ob dieser zu&amp;amp;nbsp;0 (unwahr) auswertet oder zu ungleich&amp;amp;nbsp;0 (wahr). Solche Ausdrücke findet man in if-Anweisungen, in Schleifenbedingungen und bedingten Zuweisungen&lt;br /&gt;
 (ein_wert &amp;lt; 2) || (ein_wert &amp;gt; 40)&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Lvalue ist ein Ausdruck, dem etwas zugewiesen werden kann. Der Name ''Lvalue'' kommt aus dem Englischen. Das ''L'' steht abkürzend für left. Ein Lvalue ist damit ein Ausdruck, der auf der linken Seite eine Zuweisung in C stehen darf. Das &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; in den folgenden Beispiel-Ausdrücken muss ein Lvalue sein:&lt;br /&gt;
 x = y-1&lt;br /&gt;
&lt;br /&gt;
 x++&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Konstante&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Konstante ist ein Ausdruck, dessen Wert dem Compiler bekannt ist. Beispiele für Konstanten sind etwa&lt;br /&gt;
 7&lt;br /&gt;
 'B'&lt;br /&gt;
 -13.98e12&lt;br /&gt;
 1+(2*3)&lt;br /&gt;
und die Werte von [[#Enum|Enum]]s. &lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; aus dem folgenden Codestück definiert jedoch keine Konstante in diesem Sinne&lt;br /&gt;
 const double Pi = 3.14159256;&lt;br /&gt;
denn in einem anderen Quellmodul könnte durch die Deklaration&lt;br /&gt;
 extern const double Pi;&lt;br /&gt;
das Symbol &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; bekannt sein, ohne daß sein Wert bekannt ist!&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Adresse&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Adresse ist ein Ausdruck, der einen Speicherort (physikalisch oder virtuell) halten kann. Adressen erhält man dadurch, daß man einem Bezeichner den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt;voranstellt, Adressen durch Arithmetik berechnet oder Zahlen zu Adressen castet. Folgende Ausdrücke sind Adressen (eine sinnvolle Deklaration der auftretenden Variablen vorausgesetzt)&lt;br /&gt;
 &amp;amp; eine_zahl&lt;br /&gt;
 &amp;amp; ein_array[10]&lt;br /&gt;
 &amp;amp; ein_struct&lt;br /&gt;
 &amp;amp; ein_struct.komponente&lt;br /&gt;
 (int *) 0x1234&lt;br /&gt;
 (int *) eine_zahl&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Deklaration&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Anweisungen sind gewissermassen die Atome (oder Moleküle?), aus denen ein C-Programm besteht. Jedes C-Programm ist eine Abfolge von Deklarationen und Anweisungen. Einfache Anweisungen erhält man, in dem man einen Ausdruck nimmt und einen Strichpunkt dahinter schreibt:&lt;br /&gt;
 {{Ausdruck|}};&lt;br /&gt;
wie in&lt;br /&gt;
 x = x+1;&lt;br /&gt;
&lt;br /&gt;
Andere Anweisungen sind die unten aufgeführten Schleifen und die if- sowie die switch-Anweisung.&lt;br /&gt;
&lt;br /&gt;
Mehrere Deklarationen und Anweisungen können zu einem Block zusammengefasst werden. Dieser Block stellt dann wieder eine einzelne Anweisung dar und kann genau so gehandhabt werden!&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
In diesem Sinne ist auch z.B. die Syntax der if-Anweisung zu verstehen&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
besagt, daß der abhängig ausgeführte Code eine einzelne Anweisung sein darf oder eben ein kompletter Block oder die Verschachtelung mehrerer Blöcke etc.&lt;br /&gt;
&lt;br /&gt;
Eine Anweisung kann auch &amp;quot;leer&amp;quot; sein, also nichts tun. Diese Anweisungen sind der leere Block&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
und der Strichpunkt&lt;br /&gt;
 ;&lt;br /&gt;
die man gelegentlich in Schleifen findet:&lt;br /&gt;
 while (!timeout())&lt;br /&gt;
    {}&lt;br /&gt;
oder hinter Sprungmarken, die sonst direkt vor einer schliessenden Blockklammer stünden:&lt;br /&gt;
 {&lt;br /&gt;
    ...&lt;br /&gt;
    goto ein_label;&lt;br /&gt;
    ...&lt;br /&gt;
    {{Label|ein_label}}:;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Nicht jede Anweisung ist an jeder Stelle eines C-Programms erlaubt, so darf ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; nut innerhalb einer Schleife stehen. Gleiches gilt für &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;, das aber auch innerhalb eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; vorkommen darf.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Dies steht für einen Datentyp. Es kann ein elementarer Typ sein wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;, ein Zeiger darauf wie &amp;lt;tt&amp;gt;char*&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;void*&amp;lt;/tt&amp;gt;, und auch Qualifier enthalten wie das &amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt; im Typ &amp;lt;tt&amp;gt;unsigned long long&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Zu den Typen gehören auch zusammengesetzte Datentypen wie Strukturen und Unions, mit &amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt; selbst definierte Typen und natürlich Zeiger darauf, wie aus dem Abschnitt [[#Datentypen|Datentypen]]:&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person *&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;data32_t&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;&lt;br /&gt;
und Zeiger auf Funktionen.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Parameterliste&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
Die Parameterliste bei einer Funktionsdefinition gibt an, wieviel Übergabeparameter sie bekommt, wie diese heissen und welchen Typs diese sind. Der prinzipielle Aufbau ist&lt;br /&gt;
 {{Type}} {{Bezeichner}}, {{Type}} {{Bezeichner}}, ...&lt;br /&gt;
Falls die Funktion keine Parameter hat, dann ist die Parameterliste leer.&lt;br /&gt;
&lt;br /&gt;
Hier als Beispiel die zweiparametrige Funktion &amp;lt;tt&amp;gt;produkt&amp;lt;/tt&amp;gt;. Der erste Parameter heisst&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und ist ein &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;. Der zweite namens&amp;amp;nbsp;&amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; ist vom Typ &amp;quot;Zeiger auf double&amp;quot;, der Inhalt &amp;lt;tt&amp;gt;*b&amp;lt;/tt&amp;gt; ist also auch ein double.&lt;br /&gt;
&lt;br /&gt;
'''Definition der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b)&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
In älteren C-Quellen findet man noch eine andere Syntax für die Deklaration der Parameter, die aber heute praktisch nicht mehr verwendet wird:&lt;br /&gt;
'''alte Definition der Funktion:'''&lt;br /&gt;
 double produkt (a, b)&lt;br /&gt;
 double a, *b;&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Um die Funktion bekannt zu machen, werdendet man eine Deklaration bzw. den Prototypen, der dem Compiler nur mitteilt, welche Parameter die Funktion bekommt und was sie zurückliefert. Für den Aufruf der Funktion muss der Compiler nur diesen Prototyp kennen, ''was'' die Funktion im Endeffekt macht und wie sie implementiert wurde ist egal, sie wird als BlackBox angesehen.&lt;br /&gt;
&lt;br /&gt;
'''Prototyp der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b);&lt;br /&gt;
Hier dürfen die Bezeichner auch fehlen:&lt;br /&gt;
 double produkt (double, double*);&lt;br /&gt;
&lt;br /&gt;
==if==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==if-else==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==for==&lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Eine for-Schleife entspricht folgendem Konstrukt. Dabei sind die drei Ausdrücke optional. Fehlt die Bedingung, dann wird diese als &amp;quot;wahr&amp;quot; angenommen. Die beiden anderen Ausdrücke wird man als Ausdrücke mit Nebeneffekt wählen wie z.B. &amp;lt;tt&amp;gt;x=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;x=x-2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
 {&lt;br /&gt;
    {{Ausdruck|1}};&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_loop}}:&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
    else&lt;br /&gt;
       goto _break;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_continue}}:&lt;br /&gt;
    {{Ausdruck|2}};&lt;br /&gt;
    goto _loop;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_break}}:;&lt;br /&gt;
 }&lt;br /&gt;
Die Labels &amp;lt;tt&amp;gt;_break&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_continue&amp;lt;/tt&amp;gt; entsprechen den Sprungzielen einer &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Anweisung innerhalb von &amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==do-while==&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while  ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
==while==&lt;br /&gt;
 while  ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==switch==&lt;br /&gt;
 switch  ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    ...&lt;br /&gt;
  &lt;br /&gt;
    default:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#break-Anweisung|&amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Konstanten|&amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#continue-Anweisung|&amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#do-while-Schleife|&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Enum|&amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#for-Schleife|&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#goto-Anweisung|&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#return-Anweisung|&amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Liste der Operatoren|sizeof]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Strukturen|&amp;lt;tt&amp;gt;struct&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Eigene Datentypen|&amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Unions|&amp;lt;tt&amp;gt;union&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#while-Schleife|&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund2}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Arithmetische Operatoren&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Dies sind die &amp;quot;normalen&amp;quot; arithmetischen Operationen, wie man sie aus der Schule kennt. Man kann damit und allen anderen Operatoren auch komplexere Ausdrücke aufbauen. Die Prioritäten sind so, wie man sie kennt, also &amp;quot;Punktrechnung vor Strichrechnung&amp;quot;. Will man dies ändern, dann mit den runden Klammern:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;1+2*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 7&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(1+2)*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 9&amp;lt;br/&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}}&amp;amp;nbsp;+&amp;amp;nbsp;{{Ausdruck|}}&amp;lt;/tt&amp;gt; || Addition&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} - {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Subtraktion&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} * {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Multiplikation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} / {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Division&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} % {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Rest der Division (modulo)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;- {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Vorzeichenumkehr, Zweier-Komplement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Logische Operatoren und Vergleiche&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die logischen und die vergleichenden Operatoren liefern als Ergebnis den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (wahr) oder einen Wert ungleich&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (falsch, um genau zu sein den Wert &amp;lt;tt&amp;gt;!0&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Man kann das Ergebnis zwar einer Variablen zuweisen, in aller Regel wird man solche Ausdrücke jedoch in Bedingungen zu &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder in Abbruch-Bedingungen von Schleifen finden.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;&amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches AND: beides wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124;&amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches OR: mind. eines ist wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;! {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches NOT (0 &amp;amp;harr; ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} == {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} != {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist nicht gleich&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bitweise Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~ {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise NOT (Einser-Komplement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise AND&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise ODER&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} ^ {{Ausdruck|}}&amp;lt;/tt&amp;gt; ||bitweise XOR&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Shift-Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;lt;&amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Bits nach links schieben&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;gt;&amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Schieben nach rechts schieben&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Typen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Ein Cast in C kann dazu verwendet werden, den Typ eines Ausdruckes zu ändern oder den Ausdruck mit einer bestimmten Genauigkeit zu berechnen. Wird z.B. eine Berechnung standardmässig in 16 Bit ausgeführt, dann kann man mit einem Cast &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(long) &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
ausdrücken, daß die Berechnung in 32 Bit erfolgen soll. Des weiteren kann man Zeiger und ganze Zahlen und Gleitkommazahlen ineinander umwandeln.&lt;br /&gt;
&lt;br /&gt;
Casts können ''nicht'' dazu verwendet werden, um z.B. eine Zahl in einen String zu konvertieren, der diese Zahl darstellt! Dafür gibt es spezielle Funktionen wie &amp;lt;tt&amp;gt;itoa&amp;lt;/tt&amp;gt;!&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Type}}) {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Cast, Typwandlung&lt;br /&gt;
|-&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;| &amp;lt;tt&amp;gt;sizeof ({{Type}})&amp;lt;/tt&amp;gt; || Eine Konstante, deren Wert die Größe (in Bytes) des Typs ist. &amp;lt;tt&amp;gt;sizeof&amp;lt;/tt&amp;gt; ist auch auf Objekte anwendbar wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, Arrays bekannter Größe, Strukturen und Unions,  Array-, Struktur- und Union-Komponenten, Pointer, etc. Beispiel:&amp;lt;br/&amp;gt;&lt;br /&gt;
 int i, sum=0, array[] = { 1, -13, 4, 0, sizeof (int*) };&lt;br /&gt;
 &lt;br /&gt;
 for (i=0; i&amp;lt; sizeof (array) / sizeof (array[0]); i++)&lt;br /&gt;
    sum += array[i];&lt;br /&gt;
Alle Elemente des Arrays werden aufaddiert, ohne daß deren Anzahl explizit in der Schleife genannt ist.&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zeiger und Adressen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;* {{Adresse}}&amp;lt;/tt&amp;gt; || der Inhalt an Adresse&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp; {{Lvalue}}&amp;lt;/tt&amp;gt; || Adresse von&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Strukturen, Unions, Arrays&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Struct&amp;gt;}}.{{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Zeiger-auf-Struct&amp;gt;}} -&amp;gt; {{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union, deren Adresse man hat&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Adresse}}&amp;amp;#91;{{Ausdruck|}}&amp;amp;#93;&amp;lt;/tt&amp;gt; || Array-Element&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bedingte Auswertung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Bedingung}}) ? {{Ausdruck|}} : {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Auswahl des Wertes abhängig von der Bedingung&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zuweisung und Operatoren mit Nebeneffekt&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die Unterschiede der post- und pre-Varianten der Increment/Decrement kommen in Konstrukten wie &amp;lt;tt&amp;gt;x = *p++&amp;lt;/tt&amp;gt; zum tragen:&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *p++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; p = p+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *++p;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; p = p+1; x = *p;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = (*p)++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; *p = (*p)+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = ++(*p);&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; *p = (*p)+1; x = *p;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} = {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Zuweisung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++ {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-- {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Decrement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ++&amp;lt;/tt&amp;gt; || Post-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} --&amp;lt;/tt&amp;gt; || Post-Decrement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Kurzschreibweisen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Für ganz Faule gibt es anstatt&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a = a @ b&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
für viele Operatoren (hier dargestellt durch ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;@&amp;lt;/tt&amp;gt;) die abkürzende Schreibweise&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a @= b&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} += {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} -= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} *= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} /= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} %= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ^= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;lt;&amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;gt;&amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Autoren'''&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
* Kernighan und Ritchie - Buch&lt;br /&gt;
* Christian Wirth , C Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://wwwuser.gwdg.de/~kboehm/ebook/inhalt.html C-Programmieren unter Linux]&lt;br /&gt;
* [http://www.gdv.uni-hannover.de/documentation.php Skripte zum Selbststudium: C, C++, Java, etc]&lt;br /&gt;
* [http://info.baeumle.com/ansic.html Einführung in ANSI-C]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Quellcode C|!]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Inrfb2</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10404</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10404"/>
				<updated>2007-03-14T12:22:18Z</updated>
		
		<summary type="html">&lt;p&gt;Inrfb2: /* Strukturen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Programmiersprache C wurde 1971 als Gundlage für das Betriebssystem UNIX in den USA entwickelt (UNIX ist zu über 90% in C geschrieben). 1978 wurde von Brian Kernighan und Dennis Ritchie eine eindeutige Sprachdefinition entwickelt. Mittlerweile ist C von ANSI und ISO standardisiert.&lt;br /&gt;
&lt;br /&gt;
Heute sind C und ihr Nachfolger C++ die dominierenden Programmiersprachen. Sehr viele Anwendungen sind in C geschrieben, was inzwischen auch auf eingebettete Systeme zutrifft, die lange in Assembler programmiert werden mussten, da keine ausreichend leistungsfähigen Compiler zur Verfügung standen. &lt;br /&gt;
&lt;br /&gt;
Leider ist C nicht einfach zu lernen &amp;amp;ndash; es wurde weder von noch für Hobby-Programmierer entwickelt &amp;amp;ndash; und eignet sich daher nur bedingt für den Einsteiger. Mit etwas Übung und einem optimierenden Compiler kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
Vom Design her ist C eine Hardware-unabhängig Sprache. Das bedeutet, daß C-Programme mit vertretbarem Aufwand auf ein anderes System portiert werden können. Dazu benötigt man lediglich einen anderen Compiler, und Inline-Assembler-Anweisungen (Assembleranweisungen innerhalb eines C-Programmes) müssen der neuen Hardware (Prozessor) angepasst werden. &lt;br /&gt;
&lt;br /&gt;
==Geschichte==&lt;br /&gt;
;1971: C wird entwickelt&lt;br /&gt;
;1978: Kernighan und Ritchie definieren die Sprache.&lt;br /&gt;
;1983: ANSI und ISO standardisieren C.&lt;br /&gt;
;1992: Bjarne Stroustrup enwickelt die Nachfolgesprache C++.&lt;br /&gt;
&lt;br /&gt;
=Aufbau eines C-Programmes=&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
   C-Programme haben keinen fixen Aufbau wie z.B. Pascal. Es gibt zwar gewisse Regeln, aber sonst sind dem Programmierer alle Freiheiten überlassen. Der folgende &amp;quot;Beispiel-Aufbau&amp;quot; ist daher nicht zwingend und kann durchaus verändert werden.&lt;br /&gt;
&lt;br /&gt;
   Natürlich haben C-Programme einen fixen Aufbau! Ebenso wie Pascal-Programme auch unterliegen sie einer strikten Grammatik! &lt;br /&gt;
Auskommentiert --[[Benutzer:SprinterSB|SprinterSB]] 10:23, 17. Feb 2006 (CET)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Ein einfaches C-Programm könnte folgendermassen aussehen. Das Programm tut eigentlich nichts, aber das Beispiel zeigt den prinzipiellen Aufbau. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 int Zahl1;&lt;br /&gt;
 char Zeichen1;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int zahl2;&lt;br /&gt;
 &lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Beschreibung:'''&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndash; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
 {{comment|void-Definition von main ist nur beim Controller ueblich}}&lt;br /&gt;
 {{comment|spezielle Compilereinstellungen sind noetig, damit bei dieser Definition von main}}&lt;br /&gt;
 {{comment|kein Fehler/Warnung erzeugt wird.}}&lt;br /&gt;
 void main ()&lt;br /&gt;
 {&lt;br /&gt;
     ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
 int main (void)&lt;br /&gt;
 {  {{comment|der Block &amp;quot;main&amp;quot; beginnt}}&lt;br /&gt;
    int zahl;&lt;br /&gt;
    &lt;br /&gt;
    {   {{comment|ein Block beginnt}}&lt;br /&gt;
        {{comment|hier koennen Deklarationen und Anweisungen stehen}}&lt;br /&gt;
    }   {{comment|der Block endet}}&lt;br /&gt;
   &lt;br /&gt;
    return 0;&lt;br /&gt;
 }  {{comment|&amp;quot;main&amp;quot; endet}}&lt;br /&gt;
&lt;br /&gt;
=Datentypen=&lt;br /&gt;
==Elementare Datentypen==&lt;br /&gt;
Der Datentyp einer Variable gibt an, welche Werte eine Variable enthalten kann, welcher Art diese Daten sind und wie sie verarbeitet werden, etwa in arithmetischen Operationen wie einer Addition. So ist es zum Beispiel möglich, in eine Variable vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ganze Zahlen zwischen ca. -32000 und +32000 einzutragen. In einer char-Variable können ASCII-Zeichen gespeichert werden (alles, was Sie mit der Tastatur erzeugen können) oder ganze Zahlen von -128 bis 127.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da C plattformabhängig ist, hängt die Größe eines Datentypes zum Teil von der genutzten Hardware (z.B. 8, 16 oder 32 Bit-Controller) und dem Compiler und dessen Einstellungen ab!&lt;br /&gt;
&lt;br /&gt;
===int, char, short, long (ganze Zahlen)===&lt;br /&gt;
In Variable dieser Typen können Sie ganze Zahlen abspeichern, also z.B. 1, &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;2, 100, 12345. Jeden dieser Typen gibt es in zwei Ausprägungen: als &amp;quot;&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;quot;, also als vorzeichenbehafteten Typ, und als &amp;quot;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&amp;quot;, also ohne Vorzeichen, d.h. das Vorzeichen wird als 0 oder +1 genommen. &lt;br /&gt;
&lt;br /&gt;
Vorzeichenbehaftete Ganzzahl-Typen werden intern im &amp;lt;tt&amp;gt;n-1&amp;lt;/tt&amp;gt;-Komplement dargestellt, das Vorzeichen selbst findet sich also im höchstwertigen Bit. Werden zur Speicherung ''b'' Bits verwendet, dann reicht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;z.B. *zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==Enum==&lt;br /&gt;
&lt;br /&gt;
Über &amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt; können Aufzählungen definiert werden. Die Werte sind &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Werte und beginnen mit&amp;amp;nbsp;0. Der folgende enum hat einen um&amp;amp;nbsp;1 grösseren Wert. Mit einer Zuweisung können auch andere Werte zugeordnet werden. Klarer wird's im Beispiel:&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 enum Farben&lt;br /&gt;
 {&lt;br /&gt;
    ROT,&lt;br /&gt;
    GRUEN,&lt;br /&gt;
    BLAU,&lt;br /&gt;
    BRAUN = 5,&lt;br /&gt;
    SCHWARZ&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
Dies definiert die Konstanten &amp;lt;tt&amp;gt;ROT=0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;GRUEN=1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BLAU=2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BRAUN=5&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;SCHWARZ=6&amp;lt;/tt&amp;gt; und den Typ &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void foo (enum Farben farbe)&lt;br /&gt;
{&lt;br /&gt;
   switch (farbe)&lt;br /&gt;
   {&lt;br /&gt;
      case ROT:&lt;br /&gt;
         ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit kann man anstatt &amp;quot;magischer&amp;quot; Zahlen sprechende Namen im Code verwenden, etwa in Berechnungen und Zuweisungen, Vergleichen oder als Konstante hinter einem &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zusammengesetzte Datentypen==&lt;br /&gt;
===Arrays===&lt;br /&gt;
Oft muß man sehr viele Werte gleichzeitig abspeichern und betrachten, die alle der selben Aufgabe dienen. Man schreibt z.B. ein Programm, das 10 Zahlen einlesen und anschließend wieder ausgeben soll. Man könnte das natürlich mit 10 einzelnen Variablen bewerkstelligen, aber es ist sinnvoller, dabei Arrays &amp;amp;ndash; teilweise auch als ''Felder'' bezeichnet &amp;amp;ndash; zu verwenden.&lt;br /&gt;
&lt;br /&gt;
In einem Array werden mehrere Variablen gleichen Typs zusammengefasst und hintereinander im Speicher abgelegt. So kann man viele tausend Variablen anlegen mit nur einer Zeile Code. Doch es gibt noch größere Vorteile: Sie können das Array mit einer Schleife ganz einfach nach Werten durchsuchen. Stellen Sie sich vor, Sie müssten mit 100 verschiedenen Variablen &amp;lt;tt&amp;gt;Zahl_00&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;Zahl_99&amp;lt;/tt&amp;gt; arbeiten!&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}}&amp;amp;#91;{{Konstante}}&amp;amp;#93;;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 unsigned int werte[100];&lt;br /&gt;
&lt;br /&gt;
Der Name muß natürlich ein gültiger Bezeichner sein, als Datentyp kann jeder Typ genommen werden &amp;amp;ndash; sowohl elementare Datentypen als auch Zeiger, Strukturen, Unions oder selbst definierte Datentypen. In der eckigen Klammer wird die Anzahl der Elemente bekanntgegeben. Ein mit [3] definiertes Array hat Platz für drei Variablen. Da der Index immer bei 0 beginnt, greift man also mit &amp;lt;tt&amp;gt;[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;[1]&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;[2]&amp;lt;/tt&amp;gt; auf den jeweilige Inhalt zu. Um auf eine der im Array enthaltenen Variablen zugreifen zu können, müssen Sie den Variablennamen und in eckigen Klammern den Index (die &amp;quot;Nummer&amp;quot;) der Variablen angeben. Diese Variable verhält sich dann wie eine ganz normale Variable des jeweiligen Datentypes. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #define NZAHLEN 10&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int i;&lt;br /&gt;
    int zahlen[NZAHLEN];  {{comment|zahlen[0] ... zahlen[9]}}&lt;br /&gt;
  &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++)&lt;br /&gt;
    {&lt;br /&gt;
       printf (&amp;quot;Bitte Zahl %d eingeben: &amp;quot;, i);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; zahlen[i]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++) &lt;br /&gt;
       printf (&amp;quot;Zahl %d ist: %d\n&amp;quot;, i, zahlen[i]);&lt;br /&gt;
      &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 10 int-Variablen großes Array angelegt. &lt;br /&gt;
In dieses wird nun der Reihe nach 10 Zahlen eingelesen. &lt;br /&gt;
Anschließend werden alle 10 Zahlen ausgegeben. &lt;br /&gt;
&lt;br /&gt;
Dabei wird die Größe der Arrays und das Schleifenende über das Define &amp;quot;&amp;lt;tt&amp;gt;NZAHLEN&amp;lt;/tt&amp;gt;&amp;quot; angegeben. Dadurch muss nur ''eine Stelle'' im Code geändert werden, wenn die Größe des Arrays einmal einen anderer Wert als 10 haben soll &amp;amp;ndash; dies vermeidet Fehler die dadurch entstehen, wenn man beim Anpassen der Array-Größe eine Codestelle vergisst, zudem wird der Code lesbarer als wenn irgendwo die Zahl &amp;quot;10&amp;quot; auftaucht.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
:Wird ein ungültiger Index angeben (einer, der in der Deklaration nicht enthalten ist) können  undefinierte Dinge passieren, wenn dadurch andere Variableninhalte oder Programmcode überschrieben wird, der hinter oder vor dem Array im Speicher liegt. Schlimmstenfalls kann sogar der Computer/Controller abstürzen. Also darauf achten, daß keine ungültigen Werte als Index auftreten!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Strings (Zeichenketten)===&lt;br /&gt;
Ein String ist nichts anderes als ein Array, das aus einzelnen Zeichen (&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;) gebildet wird. Die Ausgabe auf dem Bildschirm funktioniert am einfachsten mittels Strings.&lt;br /&gt;
&lt;br /&gt;
Die Definition eines Strings erfolgt also genauso wie bei Arrays:&lt;br /&gt;
 char string[21];&lt;br /&gt;
&lt;br /&gt;
Nun haben Sie eine String, in dem Sie 21 Zeichen speichern können. Ganz richtig ist das jedoch nicht. C arbeitet mit &amp;quot;null-terminierten Strings&amp;quot;. Das beudeutet, dass die Länge des Strings nicht abgespeichert wird, sondern das Zeichen mit dem ASCII-Wert 0 das Stringende kennzeichnet. Daher auch die Bezeichnung  &amp;quot;null terminiert&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Das letzte Zeichen eines Strings muß daher immer das ASCII-Zeichen Nr. 0 sein. Ist es das nicht, hat der String kein definiertes Ende, und wenn Sie versuchen, ihn durch eine Standard-Funktion auszugeben zu lassen, könnte es eine Weile dauern, bis sich im Speicher zufällig irgendwo eine 0 befindet. Es stehen ihnen daher bei dem Beispiel nur 20 Zeichen zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
===Mehrdimensionale Arrays===&lt;br /&gt;
Manchmal benötigt man mehr als nur ein eindimensionales Array, wie Sie es bisher kennengelernt haben. Auch dies ist kein Problem. In der Deklaration geben Sie einfach mehrere eckige Klammern hintereinander an. Aber Vorsicht: der Speicherplatz ist begrenzt, ein &amp;quot;&amp;lt;tt&amp;gt;char feld[1024][1024]&amp;lt;/tt&amp;gt;&amp;quot; hat die Speicherplatzgrenzen vermutlich bereits weit überschritten, und der Compiler wird einen (bei gewissen Einstellung auch keinen) Fehler liefern.&lt;br /&gt;
Beim Zugriff auf mehrdimensionale Felder müssen auch mehrere Indizes angeben werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  int x,y;&lt;br /&gt;
  int feld[3][5];&lt;br /&gt;
 &lt;br /&gt;
  for (x=0; x&amp;lt;3; x++) &lt;br /&gt;
  {&lt;br /&gt;
     for (y=0; y&amp;lt;5; y++)&lt;br /&gt;
     {&lt;br /&gt;
       printf (&amp;quot;Feldwert x: %d,  y: %d &amp;quot;, x, y);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; feld[x][y]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  for(x=0; x&amp;lt;3; x++) &lt;br /&gt;
     for (y=0; y&amp;lt;5; y++) &lt;br /&gt;
        printf (&amp;quot;Wert: feld[%d][%d] = %d\n&amp;quot;, x, y, feld[x][y]);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 3 mal 5 &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array angelegt. &lt;br /&gt;
Dann werden die Werte eingegeben: zuerst &amp;lt;tt&amp;gt;feld[0][0]&amp;lt;/tt&amp;gt;, dann &amp;lt;tt&amp;gt;feld[0][1]&amp;lt;/tt&amp;gt;, usw. bis &amp;lt;tt&amp;gt;feld[2][4]&amp;lt;/tt&amp;gt;. &lt;br /&gt;
Zum Schluß werden alle Werte noch einmal ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===Strukturen===&lt;br /&gt;
In C können Sie sogenannte &amp;quot;Strukturen&amp;quot; definieren. Dabei handelt es sich um eine Zusammenfassung mehrerer Datentypen zu einem größeren. Im Unterschied zu Feldern können in Strukturen unterschiedliche Datentypen zusammengestellt und gespeichert werden: &lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 struct {{Bezeichner}}&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur 'Person'}}&lt;br /&gt;
 struct Person &lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;lt;tt&amp;gt;struct Person {&amp;lt;/tt&amp;gt;&amp;quot; leitet die Definition der Struktur mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;Person&amp;lt;/tt&amp;gt;&amp;quot; ein. &lt;br /&gt;
Dann werden in dieser Struktur fünf Komponenten definiert: drei Strings und zwei &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. &lt;br /&gt;
mit &amp;lt;tt&amp;gt;}&amp;lt;/tt&amp;gt; wird die Definition abgeschlossen. Sie haben damit einen Datentyp erstellt. Um eine Variable des Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach an&lt;br /&gt;
 struct Person {{Bezeichner}};&lt;br /&gt;
&lt;br /&gt;
Zum Zugriff auf eine Komponente der Struktur gibt man den Namen der Struktur-Variablen an (im folgenden Beispiel also &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;klaus&amp;lt;/tt&amp;gt;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
 {{comment|Definition zweier Struktur-Variablen}}&lt;br /&gt;
 struct Person hubert, klaus;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Zugriff auf Struktur-Komponenten}}&lt;br /&gt;
 hubert.alter = 32;&lt;br /&gt;
 klaus.alter = hubert.alter + 1;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis:'''&lt;br /&gt;
Der eventuell etwas lästige Gebrauch von &amp;lt;tt&amp;gt;struct&amp;lt;/tt&amp;gt; kann schon bei der Definition der Struktur vermieden werden.&lt;br /&gt;
Der Definition ist ein &amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt; voranzustellen. Der Definition folgt dann ein gültiger (und auch eindeutiger) C-Name.&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 typedef struct {{Bezeichner}}&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 } {{Bezeichner}} ;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur '_Mensch' bzw. 'Mensch'}}&lt;br /&gt;
 struct _Mensch&lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 } Mensch;&lt;br /&gt;
&lt;br /&gt;
Jetzt sind folgende Deklarationen identisch:&lt;br /&gt;
 struct _Mensch {{Bezeichner}};&lt;br /&gt;
 Mensch {{Bezeichner}};&lt;br /&gt;
&lt;br /&gt;
Ist der Struktuname nicht notwendig (im Beispiel oben &amp;lt;tt&amp;gt;_Mensch&amp;lt;/tt&amp;gt;), kann auch kürzer geschrieben werden:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 typedef struct &lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 } {{Bezeichner}} ;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur 'Mensch'}}&lt;br /&gt;
 struct &lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 } Mensch;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall ist lediglich die {{Deklaration}} &amp;lt;tt&amp;gt;Mensch {{Bezeichner}};&amp;lt;/tt&amp;gt; gültig.&lt;br /&gt;
&lt;br /&gt;
===Unions===&lt;br /&gt;
Eine Union wird ganz analog zu einer Struktur deklariert und verwendet. Sie unterscheidet sich von einer Struktur jedoch dadurch, daß ihre Elemente nicht nacheinander im Speicher abgelegt werden, sondern sich überlagern. Auf die in einer Union enthaltenen Daten gibt es also verschiedene Sichten: je nachdem, welche Sicht bzw. Interpretation der Daten man gerne hätte, wählt man den gewünschten Zugriff.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
union Daten &lt;br /&gt;
{&lt;br /&gt;
   int id;&lt;br /&gt;
&lt;br /&gt;
   struct Person u_person;&lt;br /&gt;
&lt;br /&gt;
   struct u_double&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      double wert;&lt;br /&gt;
   };&lt;br /&gt;
&lt;br /&gt;
   struct u_pointer&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      union Daten * p1;&lt;br /&gt;
      union Daten * p2;&lt;br /&gt;
   };&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
union Daten data;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies definiert eine Union mit den vier Zugriffsmöglichkeiten &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_double&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Größe der Union richtet sich dabei nach der grössten Komponente. In diesem Beispiel sind alle Komponenten so angelegt worden, daß sie an erster Stelle ein &amp;lt;tt&amp;gt;int id&amp;lt;/tt&amp;gt; enthalten. In &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; könnte man sich also merken, wie die Daten in der Union zu interpretieren sind. Würde &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; nicht dieses &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; enthalten, so würde sich &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; mit &amp;lt;tt&amp;gt;data.u_person.vname&amp;lt;/tt&amp;gt; überlagern. Ein Ändern der ersten Buchstaben von &amp;lt;tt&amp;gt;vname&amp;lt;/tt&amp;gt; hätte also ein Ändern von &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; zur Folge, und man könnte es nicht mehr als Merker verwenden. Mit diesem Feld überlagert das &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; die &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;-Felder der anderen Sichten, z.B. ist &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; der selbe Zugriff wie auf &amp;lt;tt&amp;gt;data.u_person.id&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein anderes Beispiel ist eine Union, die es ermöglicht, auf die einzelnen Bytes eines &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; zuzugreifen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef union&lt;br /&gt;
{&lt;br /&gt;
   unsigned long  as_long;&lt;br /&gt;
   unsignen short as_short[2];&lt;br /&gt;
   unsignen char  as_byte[4];&lt;br /&gt;
} data32_t;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies überlagert einen &amp;lt;tt&amp;gt;unsigned long&amp;lt;/tt&amp;gt; &amp;amp;ndash; also eine 32-Bit-Zahl &amp;amp;ndash; mit vier Bytes bzw. zwei Shorts.&lt;br /&gt;
 data32_t wert;&lt;br /&gt;
 &lt;br /&gt;
 wert.as_long = 0x12345678;&lt;br /&gt;
 wert.as_byte[0] = 0xab;&lt;br /&gt;
 {{comment|nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform)}}&lt;br /&gt;
&lt;br /&gt;
==Eigene Datentypen==&lt;br /&gt;
&lt;br /&gt;
=Variablen=&lt;br /&gt;
Eine Variable ist ein Synonym (=anderer Name) für eine Speicherstelle in einem Computer. Einfacher gesagt, eine Variable bietet Raum, um Daten wie Zahlen oder Zeichen zu speichern und wieder zu lesen.&lt;br /&gt;
&lt;br /&gt;
==Variablennamen==&lt;br /&gt;
Ein Variablenname kann zusammengesetzt werden aus den Buchstaben &amp;lt;tt&amp;gt;'''A'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''Z'''&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;'''a'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''z'''&amp;lt;/tt&amp;gt;, den Ziffern &amp;lt;tt&amp;gt;'''0'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''9'''&amp;lt;/tt&amp;gt;, sowie dem Sonderzeichen &amp;quot;Unterstrich&amp;quot; (underscore) &amp;lt;tt&amp;gt;'''_'''&amp;lt;/tt&amp;gt;. Dabei darf an erster Stelle keine Ziffer stehen. Die Bezeichner &amp;lt;tt&amp;gt;hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALLO&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALL0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;_123&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_HALLO&amp;lt;/tt&amp;gt; sind also alle gültige und unterschiedliche Variablennamen.&lt;br /&gt;
&lt;br /&gt;
==Anlegen von Variablen==&lt;br /&gt;
Um eine Variable verwenden zu können, muss sie zuerst vereinbart (&amp;quot;erzeugt&amp;quot;) werden. Dies wird auch als &amp;quot;''Definition der Variablen''&amp;quot; bezeichnet und geht so: Schreiben Sie zuerst den Datentyp, dann den Namen der Variablen. Zum Schluß kommt noch der Strichpunkt, wie nach jeder C-Anweisung oder Deklaration. Und nicht vergessen: C unterscheidet zwischen  Groß- und Kleinschreibung! &lt;br /&gt;
 int Zahl1, Zahl2;&lt;br /&gt;
 char Zeichen;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    float gleitZahl;&lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:'''&lt;br /&gt;
In einer Zeile können auch mehrere Variablen gleichen Types vereinbart werden, wenn man ein Komma dazwischen setzt. Variablen können in jedem Block vereinbart werden. Siehe [[#Gültigkeitsbereich|Gültigkeitsbereich]].&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen==&lt;br /&gt;
Man kann einer vereinbarten Variable Werte [[#Zuweisungen|zuweisen]]. Dazu schreibt man zuerst den Variablennamen, ein Gleichheitszeichen &amp;quot;&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;&amp;quot; und anschliessend den zuzuweisenden [[#Ausdrücke|Ausdruck]]. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, zahl2 = 12;&lt;br /&gt;
  char zeichen1 = 'A';&lt;br /&gt;
&lt;br /&gt;
  zahl1 = 52;&lt;br /&gt;
  zeichen1 = zeichen1 + 1; &lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Zuerst werden drei Variablen angelegt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;: wird gleich bei der Vereinbarung der Wert 12 zugewiesen. &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl1 = 52&amp;lt;/tt&amp;gt;: Hier wird der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; der Wert 52 zugewiesen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;: wird um 1 erhöht. Da in der Variablen &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; gespeichert ist, gibt sich ihr neuer Wert aus &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt;. Weil &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; dem Wert 65 entspricht, ist &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt; gleich 66, was dem Wert für &amp;lt;tt&amp;gt;'B'&amp;lt;/tt&amp;gt; entspricht.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei float==&lt;br /&gt;
Das funktioniert genau wie bei normale Zuweisungen. Nachkommastellen werden durch einen Punkt abgegrenzt: &lt;br /&gt;
 floatVariable = 3.14;&lt;br /&gt;
Zusätzlich kann eine Zehnerpotenz angegeben werden:&lt;br /&gt;
 floatVariable2 = -1.234E-6;&lt;br /&gt;
Dadurch wird der erst Wert mit 10&amp;lt;sup&amp;gt;&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;6&amp;lt;/sup&amp;gt; multipliziert, der Wert der Variablen ist also &lt;br /&gt;
:&amp;lt;math&amp;gt;-1{,}234\cdot10^{-6} = -0.000001234&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei logischen Variablen==&lt;br /&gt;
Wie bereits erwähnt, besitzt C keinen logischen Datentyp. Es müssen also &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; dafür genutzt werden. Die Zuweisung entpricht der Standard-Zuweisung. Wird der Wert 0 zugewiesen, dann ist die Variable &amp;quot;unwahr&amp;quot;, ansonsten ist sie &amp;quot;wahr&amp;quot;. &lt;br /&gt;
 intVariable = !0;   /* entspricht &amp;quot;wahr&amp;quot;   */&lt;br /&gt;
 intVariable = 0;    /* entspricht &amp;quot;unwahr&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
==Konstanten==&lt;br /&gt;
Konstanten können als Variable angesehen werden, die nicht beschrieben, sondern nur gelesen werden können. Ein typisches Beispiel dafür ist die Zahl &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; (rund 3,141592654). Niemand würde in der realen Welt versuchen, ihr einen anderen Wert zuzuweisen. Würde man &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; jedoch wie eine normale Variable anlegen, wäre dies ohne weiteres möglich. Um dies zu verhindern, gibt es das Schlüsselwort &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in C:&lt;br /&gt;
 const {{Type}} {{Bezeichner}} = {{Konstante}};  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Wichtig dabei ist, dass man Konstanten nur bei der Vereinbarung einen Wert zuweisen kann. &lt;br /&gt;
Da Konstanten gewöhnlich im gesamten Programm, zumindest einer Quelldatei genutzt werden, definiert man diese allerdings gewöhnlich außerhalb des main-Blockes entweder am Anfang eines Programmes, oder in einer sogenannten Header-Datei, die per &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; eingebunden wird.&lt;br /&gt;
 const float PI = 3.141592;  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Es sei jedoch erwähnt, daß auch einer Konstanten nachträglich ein anderer Wert zugewieden werden kann. Im obigen Beispiel könnte mit&lt;br /&gt;
 * ((float*) &amp;amp;PI) = 2;&lt;br /&gt;
der Wert von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; im Nachhinein verändert werden. Es wird die Adresse von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; genommen und diese Adresse durch den Cast in eine ganz normale &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;-Adresse umgewandelt, über welche der Wert geändert wird. Die sei der Vollständigkeit halber erwähnt.&lt;br /&gt;
&lt;br /&gt;
Je nachdem, an welcher Stelle sich das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; bei einer Pointer-Deklaration befindet, markiert es den Pointer als konstant oder das Objekt, auf das dieser Pointer zeigt. Eine häufige Parameterdeklaration in Ausgabe-Funktionen, die einen String erhalten, ist&lt;br /&gt;
 void foo (const char * str, ...);&lt;br /&gt;
Dadurch ist &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; der Zeiger auf eine Zeichenkette, die innerhalt der Funktion nicht verändert wird bzw. verändert werden darf. Eine Zuweisung wie &amp;lt;tt&amp;gt;*str = 'a'&amp;lt;/tt&amp;gt; ergibt also einen Fehler. &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; selbst kann aber sehr wohl verändert werden, etwa mit &amp;lt;tt&amp;gt;str++&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Soll ausgedrückt werden, daß &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; unveränderlich ist, dann so:&lt;br /&gt;
 void foo (char * const str, ...);&lt;br /&gt;
Jetzt wäre eine Änderung des Strings in Ordnung, etwa durch &amp;lt;tt&amp;gt;str[10] = 'a'&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Um sich zu merken, worauf das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; wirkt, trennt man die Deklaration in Gedanken beim&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf: Steht das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; links vom&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, dann gehört es zum &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, steht es rechts davon, dann gehört es zum Pointer. Natürlich ist es auch denkbar, beides &amp;amp;ndash; also den Zeiger und sein Ziel &amp;amp;ndash; als konstant zu markieren.&lt;br /&gt;
&lt;br /&gt;
==Gültigkeitsbereich==&lt;br /&gt;
In C können mehrere Variablen den gleichen Namen haben, solange eindeutig ist, welche in welchen Block gültig ist. Dabei gelten folgende Regeln: &lt;br /&gt;
&lt;br /&gt;
;Lokale Variablen: sind Variablen, die innerhalb eines Blockes definiert werden. Jede Variable ist nur in dem Block gültig, in dem sie vereinbart wurde, sowie in allen darin enthaltenen Blöcken; es sei denn, in einem Unter-Block wird eine Variable gleichen Namens definiert. Dann bezieht sich in diesem Unter-Block der Bezeichner auf die im Unter-Block angelegte Variable.&lt;br /&gt;
;Globale Variablen: werden ausserhalb jedes Blockes definiert und gelten ab der Stelle, an der sie deklariert werden, siehe auch [[#Deklaration und Definition|Deklaration und Definition]]. Wird jedoch in einem Block eine Variable gleichen Namens angelegt, gilt ab hier bis zum Ende des Blocks nicht mehr die globale Variable, sondern die im Block deklarierte. Das Spiel kann man weiterspielen: wird in einem Unter-Block wieder eine namensgleiche Variable angelegt, gilt diese in dem Unterblock.&lt;br /&gt;
&lt;br /&gt;
==Speicherklassen==&lt;br /&gt;
Jede Variable in C gehört zu einer bestimmten Speicherklasse&lt;br /&gt;
;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;: Lokale Variablen sind in aller Regal sogenannte ''automatische Variablen''. Das bedeutet, sie werden automatisch angelegt, wenn ein Block bzw. eine Funktion betreten wird und danach wieder entfernt. Das Schlüsselwort &amp;quot;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;&amp;quot; wird praktisch nie hingeschrieben, denn lokale Variablen ohne die ausdrückliche Angabe einer Speicherklasse, sind automatisch automatische Variablen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;: Eine externes Symbol ist im ganzen Programm bekannt bzw. in dem Block, in der die Deklaration steht. In unterschiedlichen Blöcken stehende Deklarationen beziehen sich auf das gleiche Symbol! Obgleich das Datum global zugreifbar ist, ist der Gültigkeitsbereich auf den deklarierenden Block begrenzt bzw. auf das deklarierende Quell-Modul, sofern das Symbol ausserhalb jedes Blocks des Moduls deklariert wird. Siehe auch [[#Deklaration und Definition|Deklaration und Definition]].&lt;br /&gt;
;&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;: Die Variable ist im Block gültig bzw. im Quell-Modul (also in der C-Datei, in der die angelegt wurde), wenn sie nicht innerhalb eines Blockes angelegt wurde. Statische Variablen werden nicht in Registern oder im Frame der Funktion angelegt, sondern im selben Speicherbereich, in dem auch die globalen Variablen liegen; Konstanten evtl. auch im Flash. Eine lokale Variable, die als &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; angelegt wird, &amp;quot;überlebt&amp;quot; also das Verlassen des Blocks und hat beim neuerlichen Betreten des Blockes ihren bisherigen Wert. In unterschiedlichen Blöcken angelegte lokale statische Variablen beziehen sich auf unterschiedliche Speicherstellen, genau wie bei lokalen Variablen auch.&lt;br /&gt;
;&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;: Durch diese Speicherklasse wird eine Variable &amp;amp;ndash; falls möglich &amp;amp;ndash; als Registervariable angelegt, also in einem Maschinenregister des Computer/Controllers gehalten. Dadurch kann auf solche Variablen besonders schnell zugegriffen werden. Dieses Schlüsselwort ist bei modernen Compilern weitgehend überflüssig, da die entsprechenden Optimierungen selbständig vorgenommen werden, wenn ausreichend Register vorhanden sind. Auch globale Variablen können als Register angelegt werden, davon ist dem Anfänger aber dringend abzuraten, weil leicht schwerauffindbare Fehler und Abstürze auftreten, wenn man nicht genau weiss, welche Implikationen in einer solchen Definition stecken!&lt;br /&gt;
;&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;: (FIXME: volatile ist ein Qualifier und keine Speicherklasse) Dies ist das genaue Gegenteil von &amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt; und bewirkt, dass die Variable auf keinen Fall in einem Register zwischengespeichert werden darf, sondern immer aus dem RAM gelesen und ins RAM geschrieben werden soll. &amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt; müssen alle ''globalen'' Variablen markiert werden, die in [[ISR | Interrupt-Handlern]] verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Ausdrücke=&lt;br /&gt;
Eine Variable oder eine Konstante in C stellen einfache Ausdrücke dar.&lt;br /&gt;
Diese elementaren Ausdrücke können durch Operatoren miteinander verknüpft werden und so zu neuen, komplexeren Ausdrücken zusammen gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Einfache Beispiele für Ausdrücke sind also z.B.:&lt;br /&gt;
 1&lt;br /&gt;
 a&lt;br /&gt;
 'a'&lt;br /&gt;
 1 + a&lt;br /&gt;
 a == 1&lt;br /&gt;
&lt;br /&gt;
Auch Funktionen können einen Wert zurückliefern und in Ausdrücken weiter benutzt werden.&lt;br /&gt;
In den folgenden Abschnitten wird gezeigt, welche Operatoren in C vorhanden sind,&lt;br /&gt;
und wei man damit neue Ausdrücke aufbauen kann.&lt;br /&gt;
&lt;br /&gt;
==Lvalues==&lt;br /&gt;
&lt;br /&gt;
Ein Lvalue in C ist ein Ausdruck, dem ein anderer Ausdruck zugewiesen werden kann, dessen Wert also durch eine Zuweisung verändert werden kann.&lt;br /&gt;
das 'L' leitet sich ab von 'left' bwz. 'links' und das 'value' bedeutet Wert: Ein Lvalue ist ein Ausdruck, der auf der linken Seite einer Zuweisung stehen darf. Ein Lvalue ist also immer auch ein gültiger Ausdruck, aber die Umkehrung gilt in alles Regel nicht.&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für einen Lvalue ist eine &amp;quot;normale&amp;quot; Variable, die nicht mit &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; als Konstante markiert ist:&lt;br /&gt;
 a = 1;&lt;br /&gt;
Hingegen ist der Ausdruck &amp;lt;tt&amp;gt;a+1&amp;lt;/tt&amp;gt; kein Lvalue, denn eine Zuweisung wie&lt;br /&gt;
 a+1 = 2;&lt;br /&gt;
die mathematisch durchaus sinnvoll ist, erzeugt einen Compilerfehler, der etwa lauten könnte &amp;quot;illegal lvalue in assignment&amp;quot;:&lt;br /&gt;
&amp;quot;ungültiger Wert in Zuweisung&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Andere Beipiele für Lvalues sind die Komponenten von (nicht-konstanten) [[#Strukturen|Strukturen]] und [[#Unions|Unions]], [[#Arrays|Array]]-Elemente und die Dereferenzierungen von Pointern: Die Konstante&amp;amp;nbsp;4 wird durch den Cast in eine Adresse umgewandelt. Über die Dereferenzierung&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; wird an die Adresse&amp;amp;nbsp;4 im Speicher eine&amp;amp;nbsp;3 geschrieben. Ob das erlaubt bzw. sinnvoll ist, ist abhängig von der jeweiligen Architektur.&lt;br /&gt;
 * ((unsigned int *) 4) = 3;&lt;br /&gt;
Hier ist der gesamte &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;-Ausdruck ein Lvalue&lt;br /&gt;
&lt;br /&gt;
==Logische (boolsche) Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp;amp;&amp;amp;amp; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr oder &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; || gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; || ungleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;= b&amp;lt;/tt&amp;gt; || kleiner oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt; b&amp;lt;/tt&amp;gt; || kleiner als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt;= b&amp;lt;/tt&amp;gt; || glösser oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt; b&amp;lt;/tt&amp;gt; || grösser als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; nicht wahr und vice versa&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine interessante Eigenschaft der Operatoren &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;amp;amp;&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; ist, dass&lt;br /&gt;
sie die Auswertung abbrechen, sobald das Ergebnis feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet. Ein oft anzutreffendes Codestück sieht so aus, dabei sei &amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
  if (p &amp;amp;&amp;amp; *p == 5)&lt;br /&gt;
  {&lt;br /&gt;
     {{comment|mach was}}&lt;br /&gt;
  }&lt;br /&gt;
Zuerst wird in der Bedinung geprüft, ob Zeiger&amp;amp;nbsp;&amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; einen Wert ungleich Null hat, also ob er überhaupt einen gültigen Wert enthält. Es ist weit verbreitete Konvention in C, daß Zeiger, die keinen gültigen Wert haben, die Adresse&amp;amp;nbsp;0 enthalten. '''Nur dann, wenn ein Zeiger nicht ein Null-Pointer ist, darf überhaupt ein Zugriff über ihn erfolgen!'''&lt;br /&gt;
&lt;br /&gt;
==Vergleich von Variablen==&lt;br /&gt;
Skalare Variablen (also ganze Zahlen, Gleitkommazahlen, Zeiger) können miteinander verglichen werden. Dazu gibt es die folgenden Operatoren in C: &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; || ist nicht gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;=&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;=&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das Ergebnis der Auswertung ist eine ganze Zahl. Ist die Bedingung erfüllt, dann ist der Wert ungleich&amp;amp;nbsp;0. Ist die Bedingung nicht erfüllt, dann ist ihr Wert gleich&amp;amp;nbsp;0.&lt;br /&gt;
Meistens wird man diese Operatoren in &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Konstrukten finden wie zum Beispiel&lt;br /&gt;
 if (x &amp;gt;= 10)&lt;br /&gt;
    x = 10;&lt;br /&gt;
oder in Abbruchbedingungen von Schleifen, wie sie weiter unten erklärt werden.&lt;br /&gt;
&lt;br /&gt;
Es ist auch möglich, das Ergebnis der Auswertung in einer &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Variablen zu speichern:&lt;br /&gt;
 int i;&lt;br /&gt;
 int z1, z2;&lt;br /&gt;
 &lt;br /&gt;
 z1 = 5;&lt;br /&gt;
 z2 = 100;&lt;br /&gt;
 i = z1 &amp;lt;= z2;  {{comment|Ein Vergleich. i wird &amp;quot;wahr&amp;quot;, da z1 kleinergleich z2 ist}}&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich&amp;amp;nbsp;0 (&amp;quot;wahr&amp;quot;), wenn &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; kleiner oder gleich &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt; ist. Ist &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; jedoch größer als &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt;, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich&amp;amp;nbsp;0 (&amp;quot;unwahr&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
==Arithmetische Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a + b&amp;lt;/tt&amp;gt; || Summe (Addition)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a - b&amp;lt;/tt&amp;gt; || Differenz (Subtraktion)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a * b&amp;lt;/tt&amp;gt; || Produkt (Multiplikation)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a / b&amp;lt;/tt&amp;gt; || Quotient (Division, evtl. mit Rest)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a % b&amp;lt;/tt&amp;gt; || Rest bei Division (Modulo)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;-a&amp;lt;/tt&amp;gt; || Vorzeichenumkehr (Zweierkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Bit-Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp; b&amp;lt;/tt&amp;gt; || bitweise und (and)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || bitweise oder (or)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a ^ b&amp;lt;/tt&amp;gt; || bitweise exclusiv-oder (xor, exor)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;~a&amp;lt;/tt&amp;gt; || jedes Bit in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; invertieren (not, Einerkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Index-Operator bei Arrays==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a[b]&amp;lt;/tt&amp;gt; || das (b+1)ste Element des Feldes a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Folgendes gilt es bei der Verwendung des Indexoperators zu beachten:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; muss ein [[C-Tutorial#Felder | Feld]] oder [[C-Tutorial#Zeiger | Zeiger]] sein&lt;br /&gt;
# &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; muss ein Integer sein oder ein Datentyp, der sich in einen int umwandeln läßt (z.B. char)&lt;br /&gt;
# Es wird nicht geprüft, ob der Index &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; im Feld &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gültig ist!&lt;br /&gt;
# Der erste Index eines Feldes ist immer 0. Daher ''(b+1)stes Element'' in der Beschreibung&lt;br /&gt;
&lt;br /&gt;
==Komponenten-Auswahl bei Structs und Unions==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a.b&amp;lt;/tt&amp;gt; || Element b der [[C-Tutorial#Strukturen | Struktur]] oder des Unions a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adress-Operator und Dereferenzierung==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&amp;amp;amp;a&amp;lt;/tt&amp;gt; || Speicheradresse der Variablen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;*a&amp;lt;/tt&amp;gt; || Wert, der an der Adresse &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a-&amp;amp;gt;b&amp;lt;/tt&amp;gt; || Wert des Elements &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; der Struktur, deren Adresse in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Adressoperator &amp;amp; kann auf Variablen angewendet werden und&lt;br /&gt;
gibt die Startadresse der Variablen im Speicher zurück.&lt;br /&gt;
&lt;br /&gt;
Handelt es sich bei einer Variable um einen [[C-Tutorial#Zeiger | Zeiger]], so enthält&lt;br /&gt;
sie eine Speicheradresse. Um an den '''Wert''' zu gelangen, der&lt;br /&gt;
an dieser Adresse steht, wird der Operator * vorangestellt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
&lt;br /&gt;
 {{comment|x ist eine Integervariable und hat den Wert 5}}&lt;br /&gt;
 int x = 5;&lt;br /&gt;
     &lt;br /&gt;
 {{comment|z ist ein Zeiger auf eine Integer-Variable und enthaelt somit}}&lt;br /&gt;
 {{comment|die Speicheradresse einer Integer-Variablen}}&lt;br /&gt;
 int *z;       &lt;br /&gt;
  &lt;br /&gt;
 {{comment|Verwendung des Adress-Operators: weist an z die Adresse von x zu}}&lt;br /&gt;
 z = &amp;amp;x;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Verwendung der Dereferenzierung}}&lt;br /&gt;
 {{comment|erhoehe den Wert, der bei Adresse z steht, um eins}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|da z auf x zeigt, hat x jetzt den Wert 6}}&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff auf Struktir- und Union-Elemente eine abkürzende Schreibweise möglich:&lt;br /&gt;
&lt;br /&gt;
Statt &lt;br /&gt;
  (*strukturZeiger).element&lt;br /&gt;
kann geschrieben werden&lt;br /&gt;
  strukturZeiger-&amp;gt;element&lt;br /&gt;
Beide Schreibweisen sind absolut gleichbedeutend, die Klammern bei der ersteren sind notwendig.&lt;br /&gt;
&lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
:Bei der Dereferenzierung durch &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; findet keine Prüfung statt, ob der Zeiger auch auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu einer Änderung '''irgendeiner''' Speicherstelle!&lt;br /&gt;
&lt;br /&gt;
 int *z; {{comment|z ist ein Zeiger auf einen int}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.}}&lt;br /&gt;
 {{comment|z enthaelt irgendeine ungueltige Adresse!!}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|&amp;quot;Erhoehe einen Integer _irgendwo_ im Speicher um 1&amp;quot; -&amp;gt; CRASH !!!}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
&lt;br /&gt;
==Cast-Operator==&lt;br /&gt;
&lt;br /&gt;
Der Cast Operator dient dazu, den Datentyp eines Wertes zu ändern. Dafür wird einfach der neue Datentyp in Klammern vor den Wert geschrieben.&lt;br /&gt;
&lt;br /&gt;
Um zum Beispiel aus einem Float ein Integer zu machen:&lt;br /&gt;
 var  = (int) 5.60;&lt;br /&gt;
Dabei wird der Wert aber auch gerundet, und es findet somit ein Informationsverlust statt.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Umwandeln einer ganzen Zahl in eine Adresse:&lt;br /&gt;
 int * addr;&lt;br /&gt;
 addr = (int*) 0x1234;&lt;br /&gt;
Damit ist &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; an Adresse 0x1234.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
Der Cast-Operator selbst führt ''keine Konvertierung'' von Darstellungen durch, etwa die Umwandlung der ganzen Zahl 123 ein den String &amp;lt;tt&amp;gt;&amp;quot;123&amp;quot;&amp;lt;/tt&amp;gt;, der diese Zahl darstellt! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
  int main(int argc, char ** argv)&lt;br /&gt;
  {&lt;br /&gt;
        char text[] = &amp;quot;5.6&amp;quot;;&lt;br /&gt;
        int zahl = (int) text;&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, zahl);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Anfangsadresse des Strings &amp;lt;tt&amp;gt;&amp;quot;5.6&amp;quot;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Komma-Operator==&lt;br /&gt;
Mit einem &amp;lt;tt&amp;gt;,&amp;lt;/tt&amp;gt; können mehrere Ausdrücke nacheinander ausgewertet werden.&lt;br /&gt;
Die Auswertung erfolgt von links nach rechts.&lt;br /&gt;
&lt;br /&gt;
Solche Konstrukte sieht man manchmal in Abfragen wie&lt;br /&gt;
 FILE  *file;&lt;br /&gt;
 if (file = fopen (&amp;quot;foo.exe&amp;quot;, &amp;quot;r&amp;quot;), file != NULL)&lt;br /&gt;
was erst an &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; einen Wert zuweist und den &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Block nur betritt,&lt;br /&gt;
wenn &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; nicht der Nullpointer ist.&lt;br /&gt;
&lt;br /&gt;
Bequem kann das auch in einer [[#for-Schleife|for-Schleife]] sein, wenn man zwei (oder mehr) Laufvariablen hat oder so:&lt;br /&gt;
 for (i=0, j=0; i &amp;lt; 10; i++, j += 2)&lt;br /&gt;
    &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Zuweisung===&lt;br /&gt;
=== ++ und -- ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; stellen einfachere Schreibweisen dar zum Addieren bzw. Subtrahieren von&amp;amp;nbsp;1.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; (Inkrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo++; &lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo + 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; 3}}&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; (Dekrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo--;&lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo - 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; -1}}&lt;br /&gt;
&lt;br /&gt;
Die beiden Operatoren können sowohl in der Präfix-Schreibweise (vor der Variablen) als auch als Postfix-Schreibweise (hinter der Variablen) notiert werden. &lt;br /&gt;
Der Unterschied liegt darin, dass beim Präfix der Wert zuerst neu berechnet wird und die Variable dann verwendet wird. Beim Postfix wird die Variable zuerst verwendet und erst nach Auswertung des Ausdrucks, in dem sie enthalten ist, neu berechnet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 int ausgabe1, ausgabe2, var1 = 10, var2 = 10;&lt;br /&gt;
 ausgabe1 = 3 * ++var1; {{comment|ausgabe1 &amp;amp;#61; 33; var1 &amp;amp;#61; 11;}}&lt;br /&gt;
 ausgabe2 = 3 * var2++; {{comment|ausgabe2 &amp;amp;#61; 30; var2 &amp;amp;#61; 11;}}&lt;br /&gt;
&lt;br /&gt;
Für Zeiger arbeiten diese Operatoren etwas anders, siehe dazu [[#Zeiger-Arithmetik|Zeiger-Arithmetik]].&lt;br /&gt;
&lt;br /&gt;
===Bedingter Ausdruck===&lt;br /&gt;
 ({{Bedingung}}) ? {{Ausdruck|1}} : {{Ausdruck|2}}&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; erfüllt ist, dann wertet dieser Ausdruck aus zu &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt;. Ist er nicht erfüllt, dann wertet er aus zu &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 x = (x &amp;gt;= 3) ? 0 : x+1;&lt;br /&gt;
Startet man &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; mit dem Wert 0, dann nimmt es bei mehrfacher Anwendung dieser Zeile (z.B. in einer Schleife) nacheinander die folgende Werte an:&lt;br /&gt;
:&amp;lt;tt&amp;gt;1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, ...&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&lt;br /&gt;
Wie auch in der Mathematik gibt es auch in C genaue Regeln über die Abarbeitungsreihenfolge (precedence)&lt;br /&gt;
der Operatoren. Dass sich alle C-Compiler genau an diesen ANSI-Vorschlag halten, ist leider nicht sicher.&lt;br /&gt;
Sicher jedoch ist, dass nicht jeder Programmierer diese Regel jederzeit im Kopf hat. &lt;br /&gt;
Daher ist es sinnvoll, Ausdrücke durch runde Klammern eindeutig zu kennzeichnen. &lt;br /&gt;
Nebenbei stören sich Compiler nicht an überflüssigen Klammerpaaren.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Priorität ||Operator||Assoziativität&lt;br /&gt;
|-&lt;br /&gt;
  &lt;br /&gt;
|&amp;lt;tt&amp;gt;15&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ( ) [ ] -&amp;gt; . &amp;lt;/tt&amp;gt;                      ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;14&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;! ~ ++ -- + - (TYP) * &amp;amp; sizeof &amp;lt;/tt&amp;gt;    ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;13&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; * / % (Rechenoperationen) &amp;lt;/tt&amp;gt;         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;12&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; + - (binär) &amp;lt;/tt&amp;gt;                       ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;11&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;&amp;lt; &amp;gt;&amp;gt; &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;10&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt; &amp;lt;= &amp;gt; &amp;gt;= &amp;lt;/tt&amp;gt;                         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 9&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; == != &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 8&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp; (bit-AND-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 7&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ^ (bit-XOR-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 6&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; (bit-OR-Operator)&amp;lt;/tt&amp;gt;   ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 5&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp;&amp;amp; &amp;lt;/tt&amp;gt;                                ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 4&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; &amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 3&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;? : &amp;lt;/tt&amp;gt;                               ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 2&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; = += -= /= *= %= &amp;gt;&amp;gt;= &amp;lt;&amp;lt;= &amp;amp;= &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;= ^= &amp;lt;/tt&amp;gt; ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 1&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; , (Sequenz-Operator) &amp;lt;/tt&amp;gt;              ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
&lt;br /&gt;
Peter Baeumle-Courth, ANSI-C im Überblick &amp;lt;p&amp;gt;&lt;br /&gt;
W. Alex, Einführung in C/C++&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
Eine Kontrollanweisung ist eine Anweisung, die Einfluss auf den Programmfluss hat. Normalerweise werden Anweisungen so ausgeführt, wie sie in der Quelldatei stehen: Von links nach rechts (falls mehrere Anweisungen in einer Zeile stehen sollten, wovon i.A. abzuraten ist) und von oben nach unten. Mit einer Kontrollanweisung kann dieser lineare Programmfluss durchbrochen werden: Die Codeausführung kann kann abhängig von einer Bedingung gemacht werden (&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;), kann wiederholt werden (Schleife) oder an einer anderen Stelle der Funktion fortgesetzt werden (&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==if-Anweisung==&lt;br /&gt;
Mit Hilfe des if-Befehls kann man Codeteile abhängig davon einer Bedingung ausführen lassen:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
oder mit else-Teil&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 if (x &amp;gt; 100)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;gt; 100 ist: Fehlerausgabe}}&lt;br /&gt;
    printf (&amp;quot;x = %d ist zu gross fuer die Berechnung!\n&amp;quot;, x);&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;lt;&amp;amp;#61; 100 ist: Berechne Summe der Zahlen 1...x}}&lt;br /&gt;
    {{comment|Die lokale Variable x2 lebt nur innerhalb dieses alse-Blocks}}&lt;br /&gt;
    int x2 = x;&lt;br /&gt;
 &lt;br /&gt;
    for (x = 0; x2 &amp;gt; 0; x2--)&lt;br /&gt;
       x += x2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Wenn die Bedingung wahr ist (&amp;lt;tt&amp;gt;x &amp;gt; 100&amp;lt;/tt&amp;gt;), dann wird eine Meldung ausgegeben; danach ist die if-Anweisung beendet. Der else-Block wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung nicht erfüllt (&amp;lt;tt&amp;gt;x &amp;amp;le; 100&amp;lt;/tt&amp;gt;), dann wird gleich zum else-Teil gesprungen, und nach dessen Ausführung der if-Befehl beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Ein häufiger Fehler ist es, statt &amp;lt;tt&amp;gt;if (a &amp;amp;#61;&amp;amp;#61; 23)&amp;lt;/tt&amp;gt; etwas wie &amp;lt;tt&amp;gt;if (a &amp;amp;#61; 23)&amp;lt;/tt&amp;gt; zu schreiben. &lt;br /&gt;
Dann wird allerdings nicht geprüft, ob die Variable&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gleich 23 ist, sondern der Variablen&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wird der Wert 23 zugewiesen. Der Ausdruck &amp;lt;tt&amp;gt;a &amp;amp;#61; 23&amp;lt;/tt&amp;gt; hat den Wert&amp;amp;nbsp;23 und ist damit immer &amp;quot;wahr&amp;quot;! Daher ist diese if-Bedingung immer erfüllt!&lt;br /&gt;
&lt;br /&gt;
Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken sondern bestenfalls eine Warnung. Damit ist dieser Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise &amp;lt;tt&amp;gt;if (23 &amp;amp;#61;&amp;amp;#61; a)&amp;lt;/tt&amp;gt;. Wenn man dort anstatt des Vergleichsoperators '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;amp;#61;&amp;lt;/tt&amp;gt;' den Zuweisungsoperator '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;lt;/tt&amp;gt;' verwendet, spuckt der Compiler sehr wohl einen Fehler aus! Ist die Zuweisung jedoch erwünscht und eine Compiler-Warnung lästig, dann wählt man eine Schreibweise wie &amp;lt;tt&amp;gt;if ((a &amp;amp;#61; b))&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;if (a &amp;amp;#61; b, a)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist zu schreiben &amp;lt;tt&amp;gt;if (Bedingung);&amp;lt;/tt&amp;gt; Richtig muss es heissen &amp;quot;&amp;lt;tt&amp;gt;if(Bedingung)&amp;lt;/tt&amp;gt;&amp;quot; Das Semikolon im ersten Fall ist eine leere Anweisung, die im if-Falle ausgeführt wird &amp;amp;ndash; sie bleibt also ohne Resultet. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt; ein auf das Semikolon folgende Anweisung die eigentlich zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören soll wird immer ausgeführt, die sie nicht mehr zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; dazu gehört.&lt;br /&gt;
}}&lt;br /&gt;
Bei verschachtelten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Konstrukten gehört ein &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zu letzten &amp;quot;freien&amp;quot; &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;. Soll in einer &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Folge das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zum ersten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören, dann ist das so zu hinzuschreiben:&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Ohne die geschweiften Klammern um das zweite &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehörte das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; dort hinzu.&lt;br /&gt;
&lt;br /&gt;
==switch-Anweisung==&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
&lt;br /&gt;
 switch ({{Ausdruck|}}) &lt;br /&gt;
 {&lt;br /&gt;
     case konstante1:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
    &lt;br /&gt;
     case konstante2:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 &lt;br /&gt;
     {{comment|weitere case-Marken}}&lt;br /&gt;
 &lt;br /&gt;
     default:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 } {{comment|Ende von switch}} &lt;br /&gt;
&lt;br /&gt;
Der Ausdruck muss ein skalarer Typ sein, er wird in die nächste ganze Zahl gewandelt und mit den Werten hinter den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Marken verglichen. Bei einer Übereinstimmung werden alle Befehle ab dem zutreffenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; ausgeführt. Stimmt der Ausdruck mit keinem der Werte überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt falls vorhanden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der nachfolgenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;- und des &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitts werden ausgeführt, wenn die Anweisungen des &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitts nicht mit dem Befehl &amp;lt;tt&amp;gt;break;&amp;lt;/tt&amp;gt; beendet werden!&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es dürfen beliebig viele &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitte angegeben werden, pro Vergleichswert jedoch nur einer.&lt;br /&gt;
Der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ist optional. Die Reihenfolge, in der &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt; angegeben werden, ist unerheblich.&lt;br /&gt;
&lt;br /&gt;
==Schleifen==&lt;br /&gt;
Um Anweisungen mehrmals hintereinander auszuführen, benötigt man Schleifen. Diese führen Anweisungen aus, bis oder solange Bedingungen erfüllt sind.&amp;lt;br&amp;gt; &lt;br /&gt;
Wichtig ist also, ob die Bedingung '''vor''' oder '''nach''' den Schleifen-Anweisungen geprüft wird. &lt;br /&gt;
&lt;br /&gt;
===while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 while ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Die while-Schleife wird solange durchlaufen, wie die Bedingung erfüllt ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Die Anweisung kann natürlich auch ein Block sein, der aus mehreren Deklarationen und Anweisungen besteht. &lt;br /&gt;
&lt;br /&gt;
 int zahl1 = 0;&lt;br /&gt;
 int zahl2 = 1;&lt;br /&gt;
 &lt;br /&gt;
 while (zahl1 &amp;lt; 3)&lt;br /&gt;
 {&lt;br /&gt;
    zahl1 = zahl1 + 1;&lt;br /&gt;
    zahl2 = zahl2 * 2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife drei mal durchlaufen. Zu Beginn des vierten Durchlaufs ist die Bedingung nicht mehr erfüllt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
&lt;br /&gt;
===do-while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
Die do-while-Schleife wird auf jeden Fall einmal durchlaufen und dann solange wiederholt, wie die Bedingung erfüllt ist.&lt;br /&gt;
 int i = 2;&lt;br /&gt;
 &lt;br /&gt;
 do &lt;br /&gt;
 {&lt;br /&gt;
     i = i*i;   {{comment|i quadrieren}}&lt;br /&gt;
     printf (&amp;quot;i = %d\n&amp;quot;, i);&lt;br /&gt;
 }&lt;br /&gt;
 while (i &amp;lt; 20);&lt;br /&gt;
&lt;br /&gt;
Die Schleife wird durchlaufen und wiederholt, solange &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; kleiner als 20 ist. Es werden also nacheinander die Werte 2, 4 und 16 ausgegeben. Nach der Schleife hat&amp;amp;nbsp;&amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; den Wert 256.&lt;br /&gt;
&lt;br /&gt;
===for-Schleife===&lt;br /&gt;
'''Syntax:''' &lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Bei den Ausdrücken wird es sich um einen Ausdrücke mit Nebeneffekt handeln wie etwa &amp;lt;tt&amp;gt;i=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;i=i+2&amp;lt;/tt&amp;gt;. Es werden folgende Aktionen ausgeführt:&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# falls die Bedingung wahr ist, dann führe &amp;lt;tt&amp;gt;Anweisung&amp;lt;/tt&amp;gt; aus.&lt;br /&gt;
# falls die Bedingung unwahr ist, dann sprinte zu 7 (Ende).&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# gehe zu 2&lt;br /&gt;
# nächste Anweisung nach der for-Schleife&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int lauf, summe;&lt;br /&gt;
 &lt;br /&gt;
 for (lauf=1, summe=0; lauf &amp;lt;= 10; lauf += 2) &lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel ist &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; ein [[#Komma-Operator|Komma-Ausdruck]], der zwei Anweisungen kombiniert und daher sogar zwei Nebeneffente hat: er setzt &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;1 und &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;0.&lt;br /&gt;
&lt;br /&gt;
Das Äquivalent als while-Schleife:&lt;br /&gt;
&lt;br /&gt;
 int lauf  = 1;                 {{comment|Anfangswerte}}&lt;br /&gt;
 int summe = 0;&lt;br /&gt;
 &lt;br /&gt;
 while (lauf &amp;lt;= 10)             {{comment|Bedingung}}&lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
    lauf  += 2;                 {{comment|Inkrement}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; in jedem Schleifendurchlauf um die Laufvariable &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; erhöht. Da &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nacheinander die ungeraden Werte von&amp;amp;nbsp;1 bis&amp;amp;nbsp;10 annimmt, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von&amp;amp;nbsp;1 bis kleinergleich 10 gespeichert, also der Wert&amp;amp;nbsp;25. &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; hat nach der Schleife den Wert&amp;amp;nbsp;11.&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf = 1&amp;lt;/tt&amp;gt; bedeutet, dass der Variablen &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; vor dem ersten Schleifendurchlauf der Wert&amp;amp;nbsp;1 zugewiesen wird. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf &amp;lt;= 10&amp;lt;/tt&amp;gt; ist die Schleifenbedingung; ist sie nicht erfüllt, wird die Schleife beendet. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf += 2&amp;lt;/tt&amp;gt; bedeutet, dass &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nach jedem Durchlauf um&amp;amp;nbsp;2 erhöht wird.&lt;br /&gt;
&lt;br /&gt;
===continue-Anweisung===&lt;br /&gt;
Innerhalb einer Schleife darf die &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die nachfolgenden Anweisungen übersprungen werden und mit dem nächsten Schleifendurchlauf fortgesetzt wird &amp;amp;ndash; vorausgesetzt die Schleifenbedingung ist noch erfüllt. Ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; etc. stehen, wenn dieses innerhalb einer Schleife steht.&lt;br /&gt;
&lt;br /&gt;
==break-Anweisung==&lt;br /&gt;
Innerhalb einer Schleife oder eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; darf die &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die Schleifen-/Switch-Anweisung sofort verlassen wird und das Programm dahinter weiter macht. Bei mehrfach geschachtelten Schleifen wird nur die innere verlassen. Ein &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; stehen, wenn dieses innerhalb einer Schleife/Switch-Anweisung steht.&lt;br /&gt;
&lt;br /&gt;
==goto-Anweisung==&lt;br /&gt;
&lt;br /&gt;
Innerhalb ein und derselben Funktion kann mit &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; an eine andere Stelle gesprungen werden. Dazu gibt man hinter dem &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einen Bezeichner an, der dadurch als Label fungiert:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 goto {{Bezeichner}};&lt;br /&gt;
Die Bezeichner selbst steht irgendwo in der Funktion und wird dadurch zur Sprungmarke (Label), daß er von einem Doppelpunkt (und mindestens einer C-Anweisung, die auch leer sein darf) gefolgt wird.&lt;br /&gt;
&lt;br /&gt;
Das Beispiel durchsucht das 2-dimensionale &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array &amp;lt;tt&amp;gt;feld&amp;lt;/tt&amp;gt; mit den &amp;lt;tt&amp;gt;SIZE_X &amp;amp;times; SIZE_Y&amp;lt;/tt&amp;gt; Werten nach dem Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;. Wird er gefunden, dann wird die 2-fach geschachtelte Suchschleife verlassen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int x, y;&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y; y++)&lt;br /&gt;
       if (feld[x][y] == 0)&lt;br /&gt;
          goto done;&lt;br /&gt;
 {{Label|done:}};&lt;br /&gt;
&lt;br /&gt;
Der folgende Code hat die gleiche Funktion, arbeitet jedoch ohne &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int x, y;&lt;br /&gt;
 int found = 0; {{comment|FALSE}}&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X &amp;amp;&amp;amp; !found; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y &amp;amp;&amp;amp; !found; y++)&lt;br /&gt;
       found = (0 == feld[x][y]);&lt;br /&gt;
Der Nachteil der &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-losen Variante ist, daß man eine Variable, die merkt, ob das Suchziel gefunden wurde, mitschleppen und in ''jedem'' Schleifendurchlauf abtesten muss. Dies bedeutet einen höheren Programmier- und Laufzeitaufwand und ist nicht so klar formuliert wie das &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-Beispiel.&lt;br /&gt;
&lt;br /&gt;
Gleichwohl sei angemerkt, daß die Verwendung von &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einem gewissen Dogmatismus unterliegt, der sich wie folgt subsummieren liesse:&lt;br /&gt;
:''goto ist böse und sollte keinesfalls verwendet werden! Wer es dennoch tut, offenbart dadurch seinen schlechten Geschmach sowie mangelhafte C-Kenntnis.'' &amp;lt;div align=&amp;quot;right&amp;quot;&amp;gt;http://www.roboternetz.de/phpBB2/images/smiles/icon_wink.gif&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Funktionen=&lt;br /&gt;
Stellen Dir vor, Du hast eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben &amp;amp;ndash; was Dich Zeit beim Erstellen des Programms und Speicherplatz im ausführbaren Programm kostet &amp;amp;ndash; kannst Du den Code-Abschnitt in eine Funktion schreiben und diese von jeder Stelle des Programms aus verwenden. Die Hauptgründe, um Funktionen zu verwenden, sind:&lt;br /&gt;
;Wiederverwendung von Code: Mehrfach verwendete Codestücke müssen nicht mehrfach implementiert werden. Oft unterscheiden sich die Codesequenzen nur in Kleinigkeiten, die man der Funktion über Parameter mitteilen kann.&lt;br /&gt;
;Übersichtlichkeit: Ein gut gegliedertes C-Programm implementiert klar umrissene Aufgaben in einer Funktion, auch wenn diese Funktion nur einmal im Code aufgerufen wird! Dadurch bleibt der Code um die Aufrufstelle besser verständlich, und man kann auf verschiedenen &amp;quot;Ebenen&amp;quot; denken. Eine Funktion wie &amp;quot;Datei öffnen&amp;quot; kann recht komplex sein. Auf höherer Ebene interessieren die Innereien nicht mehr, man möchte sich um andere Dinge kümmern und will den Code an der Stelle garnicht sehen...&lt;br /&gt;
;Rekursive Funktionen: Eine Funktion kann sich auch selbst aufrufen. In dem Falle nennt man die Funktion ''rekursiv''. Zwar lässt sich das, was eine rekursive Funktion tut, auch mit anderen Mitteln formulieren, die keine rekursiven Funktionen brauchen, aber oft ist der rekursive Weg knackiger und klarer formulierbar als eine nicht-rekursiven Ansatz, auch wenn es etwas mehr Resourcen verbraucht.&lt;br /&gt;
;Modulare Programmierung: Funktionen können anhand ihres Aufgabenbereichs auf verschiedene C-Quellen &amp;amp;ndash; sogenannte ''Module'' &amp;amp;ndash; verteilt werden. Funktionen, die etwas mit dem USB-Bus anstellen, werden in einem anderen Modul sein als mathematische Funktionen. Dies erhöht die Übersichtlichkeit und vereinfacht die Entwicklung im Team.&lt;br /&gt;
;Bibliotheken: Standard-Funktionen wie das hier oft auftauchende &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; sind in Bibliotheken gespeichert. Wenn das eigene Programm übersetzt wird, dann müssen nicht mehr alle Standard-Funktionen übersetzt werden, sondern werden nur noch aus der Bibliothek gelesen und ihr Code zum Programm dazugelinkt. Die Bibliotheks-Funktionen wurden schon zu einem früheren Zeitpunkt compiliert und liegen in dieser compilerten Form in der Bibliothek. Das spart mächtig Entwicklungszeit. Man kann auch selbst solche Bibliotheken erstellen und in diversen Projekten wiederverwenden.&lt;br /&gt;
;Generische Programmierung: In C ist es möglich, einer Funktion eine andere Funktion zu übergeben. (Damit ist nicht gemeint, ihr deren ''Rückgabewert'' zu übergeben (was auch ginge), sondern ''die Funktion selbst'' wird als Parameter übergeben und kann aufgerufen werden.) Ein typisches Beispiel dafür sind Sortieralgorithmen. Einem Sortieralgorithmus kann es egal sein, ''was'' er sortiert. Er muss lediglich wissen, ''wie'' er das Zeug zu sortieren hat: aufsteigend, absteigend, als Zahl, in lexikographischer Ordnung, nach der Quersumme, Körper nach Oberfläche, Durchmesser, Gewicht oder Volumen... Diese Vergleichsfunktion, die für zwei Objekte entscheidet, welches davon &amp;quot;kleiner&amp;quot; ist, kann man dem Sortierer übergeben. Will er zwei Werte vergleichen, dann muss er nur die Vergleichsfunktion aufrufen, ohne zu wissen, was diese tut. Damit kann der Sortieralgorithmus unanhängig von den Objekten gehalten werden, mit denen er hantieren soll.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Definition==&lt;br /&gt;
&lt;br /&gt;
In der ''Definition'' der Funktion wird gesagt, welche Werte sie liefern kann, wie sie heisst (Bezeichner) und wieviele und welche Parameter sie hat. Danach folgt ihre Implementierung:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}} ({{Parameterliste}})&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 &lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
Für Funktionen, die keinen Wert zurückliefern, gibt es den speziellen Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der besagt, daß die Funktion nichts zurückgibt. Die einfachste denkbare Funktion ist eine solch void-Funktion. Sie bekommt keine Parameter, gibt nicht zurück und ihr Body ist leer:&lt;br /&gt;
 void dummy()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==return-Anweisung==&lt;br /&gt;
An jeder Stelle des Programmflusses einer Funktion kann diese mit &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; beendet werden.&lt;br /&gt;
&lt;br /&gt;
'''bei void-Funktionen:'''&lt;br /&gt;
 return;&lt;br /&gt;
'''Funktionen mit Rückgabe-Wert:'''&lt;br /&gt;
 return {{Ausdruck|}};&lt;br /&gt;
Die zweite Variante gibt an, welcher Wert zurückgegeben wird.&lt;br /&gt;
 int main (int argc, char * argv[])&lt;br /&gt;
 {&lt;br /&gt;
    if (argc &amp;lt; 2)&lt;br /&gt;
       return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
Falls die letzte Anweisung einer void-Funktion ein &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; ist, kann es auch weggelassen werden wie oben bei der Funktion &amp;lt;tt&amp;gt;dummy&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Aufruf==&lt;br /&gt;
Um die Funktion aufzurufen gibt man ihren Namen an, gefolgt von den durch Komma getrennten Argumenten in runden Klammern wie im Beispiel unten das&lt;br /&gt;
 quadrat (5) &lt;br /&gt;
Da &amp;lt;tt&amp;gt;quadrat&amp;lt;/tt&amp;gt; einen Wert liefert, kann man damit weiter rechnen wie mit einem normalen Ausdruck:&lt;br /&gt;
 if (quadrat (a) + quadrat (b) == quadrat (c))&lt;br /&gt;
    c = quadrat (quadrat (a)); {{comment|c &amp;amp;#61; a hoch 4}}&lt;br /&gt;
&lt;br /&gt;
;Ein Hinweis am Rande: &lt;br /&gt;
Der Name einer Funktion ohne die beiden runden Klammern ist der Pointer/Zeiger auf ihren Anfang.&lt;br /&gt;
Damit kann ein Funktionsname überall dort verwendet werden, wo Pointer/Zeiger &lt;br /&gt;
zulässig sind. Insbesondere kann er als Argument einer weiteren Funktion dienen. &lt;br /&gt;
&lt;br /&gt;
'''Quelle:'''&lt;br /&gt;
W. Alex, Einführung in C/C++&lt;br /&gt;
&lt;br /&gt;
==Rekursive Funktionen==&lt;br /&gt;
Eine Funktion die sich selbst &amp;amp;ndash; möglicheweise auch über andere Zwischenfunktionen &amp;amp;ndash; wieder selbst aufruft, wird als ''rekursive Funktion'' bezeichnet. In der Definition ist nichts besonderes zu beachten. Ist die Verschachtelungstiefe im laufenden Programm zu tief, dann gibt das natürlich Probleme, aber das gilt bei tief verschachtelten 'normalen' Funktionen abenso...&lt;br /&gt;
&lt;br /&gt;
Das Beispiel berechnet den Größten Gemeinsamen Teiler zweier Zahlen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int ggT (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
     if (0 == a)&lt;br /&gt;
        return b;&lt;br /&gt;
 &lt;br /&gt;
    return ggT (b % a, a);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Ein komplettes kleines Programm:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int quadrat (int param1)&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  zahl = param1 * param1;&lt;br /&gt;
  return zahl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl, ergebnis;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Bitte Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = quadrat (zahl);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, zahl, ergebnis);&lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, 5, quadrat (5));&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur ausserhalb von Blöcken. Geschachtelte Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen beim Aufruf die Klammern angeben werden:&lt;br /&gt;
 dummy();&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Prototypen==&lt;br /&gt;
Wie oben erwähnt, kann ein Unterprogramm an jeder beliebigen Stelle im Programm stehen. Damit ist jedoch eine Bedingung verknüpft: Das Unterprogramm muß in der Datei oberhalb des ersten Aufrufes definiert worden sein. Wenn Sie ein Unterprogramm in Zeile 10 zum ersten mal aufrufen, müssen Sie die Deklaration davor erledigt haben. Verstanden?&lt;br /&gt;
Um dies zu erreichen, gibt es zwei Möglichkeiten: &lt;br /&gt;
&lt;br /&gt;
Entweder Sie schreiben alle Unterprogramme vor &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; in die Datei. Dies muß jedoch wiederum so geschehen, dass Funktionen zum Zeitpunkt ihres Aufrufes bereits bekannt sind! &lt;br /&gt;
Wo dies nicht möglich ist (z.B. sich gegenseitig aufrufende Unterprogramme), oder wenn Sie das stört, müssen Sie Prototypen verwenden. &lt;br /&gt;
Wie definiert man nun Prototypen? Sie kopieren einfach die erste Zeile des Unterprogrammes (z.B. &amp;quot;&amp;lt;tt&amp;gt;void ausgeben (int zahl)&amp;lt;/tt&amp;gt;&amp;quot;), fügen einen Strichpunkt&amp;amp;nbsp;&amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;an und fügen es an einer geeigneten Stelle ein (so, dass alle Aufrufe später in der Datei kommen). &lt;br /&gt;
Solche Definitionen stehen gewöhnlich am Anfang der Quelldatei oder in einer Header-Datei, die eingebunden wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl);  /* Der Prototyp */&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
   ausgeben (12);&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl)   /* Die eigentliche Prozedur */&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Ausgabe: %d\n&amp;quot;, zahl);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Parameterübergabe==&lt;br /&gt;
&lt;br /&gt;
Alle Werte, die an Prozeduren und Funktionen übergeben werden, werden grundsätzlich '''kopiert'''.&lt;br /&gt;
Das hat folgende Auswirkungen:&lt;br /&gt;
&lt;br /&gt;
# Änderungen an einem Parameter in einer Funktion erscheinen ''nicht'' beim Aufrufer!&lt;br /&gt;
# Möchte man, dass eine Funktion einen Wert trotzdem dauerhaft ändern soll, so muss die Adresse des Wertes via [[#Zeiger|Zeiger]] übergeben werden.&lt;br /&gt;
# Werden [[#Strukturen|Strukturen]] übergeben, so wird von ihnen eine Kopie erstellt, was bei großen Strukturen viel Zeit und Arbeitsspeicher kostet. Deshalb wird häufig nur die Adresse von Strukturen übergeben, da die Adresse viel schneller und platzsparender als die Struktur selbst kopiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele:'''&lt;br /&gt;
 void erhoehe (int x)&lt;br /&gt;
 {&lt;br /&gt;
    x = x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe(a);&lt;br /&gt;
    {{comment|a ist immer noch 0}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Beim Aufruf von &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; wird eine Kopie des Wertes von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; (im Beispiel also 0) erstellt und der Prozedur als Parameter &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; übergeben. Weil dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat dies keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|erhoehe den Wert an der Adresse x um eins}}&lt;br /&gt;
    *x = *x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe (&amp;amp;a);&lt;br /&gt;
    {{comment|a ist jetzt 1}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Jetzt wird im Hauptprogramm mittels [[#Adress-Operator und Dereferenzierung|Adress-Operator]] &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; die Speicheradresse von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; bestimmt. Dann wird eine ''Kopie der Adresse'' an das Unterprogramm &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; übergeben. Jetzt kennt das Unterprogramm die&lt;br /&gt;
Adresse des Originals &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und kann direkt mit dem Inhalts-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&lt;br /&gt;
'''Besonderheit bei Feldern'''&lt;br /&gt;
&lt;br /&gt;
Bei der Übergabe von [[#Felder|Feldern]] gibt es eine Besonderheit. Schreibt man nämlich den Namen eines Feldes, so ist das nichts anderes als die '''Speicheradresse des ersten Elements'''.&lt;br /&gt;
Bei der Übergabe eines Feldes wird also eine Kopie der Startadresse übergeben. Somit kann das Unterprogramm auf den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 void erhoehe (int x[])&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
   int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
   erhoehe (a);&lt;br /&gt;
   {{comment|a hat jetzt folgenden Inhalte: 11, 23, 35}}&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Dass die Übergabe einer Adresse erfolgt, sieht man an folgendem Beispiel, das von der Funktionsweise '''absolut identisch''' mit dem vorhergehenden ist:&lt;br /&gt;
&lt;br /&gt;
 {{comment|Bei Parametern gibt es keinen Unterschied zwischen Zeiger und Feld}}&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
    int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
    erhoehe (a);&lt;br /&gt;
 &lt;br /&gt;
    {{comment|a hat jetzt folgenden Inhalt: 11, 23, 35}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
Die Länge des Feldes wird nicht automatisch übergeben. Dafür ist ggf. ein zusätzlicher Parameter notwendig.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Variable Argumentanzahl==&lt;br /&gt;
== Funktionen indirekt aufrufen ==&lt;br /&gt;
Siehe [[#Zeiger auf Funktionen|Zeiger auf Funktionen]]&lt;br /&gt;
&lt;br /&gt;
=Zeiger II=&lt;br /&gt;
&lt;br /&gt;
Zeiger haben wir bereits weiter oben kennen gelernt. Zeiger sind ein zentrales Konzept in C und sollen hier etwas eingehender behandelt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger-Arithmetik==&lt;br /&gt;
In C kann man den Wert eines Zeigers verändern. Betrachten wir dazu die Funktion &amp;lt;tt&amp;gt;suche_0&amp;lt;/tt&amp;gt;, die einen Zeiger auf einen &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; erhält. Die Funktion soll ab der gegebenen Adresse nach dem ersten long-Wert suchen, der 0 ist, und dessen Adresse zurückgeben:&lt;br /&gt;
 long * suche_0 (long * addr)&lt;br /&gt;
 {&lt;br /&gt;
    while (*addr != 0)&lt;br /&gt;
       addr = addr + 1;&lt;br /&gt;
 &lt;br /&gt;
    return addr;&lt;br /&gt;
 }&lt;br /&gt;
In der Bedingung der while-Schleife wird der Inhalt an der Speicherstelle &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf 0 getestet. Ist der Wert 0, dann wird die Schleife beendet und die Adresse zurückgeliefert. Ist der Wert ungleich 0, dann wird &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf den nächste long gesetzt, &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; also um 4 Bytes weitergezählt. &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ist ja ein Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, und ein &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; ist 4 Bytes lang.&lt;br /&gt;
&lt;br /&gt;
Die Bedeutung von&lt;br /&gt;
 address + n&lt;br /&gt;
ist also, die Adresse um das &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;-fache der Größe des Typs, auf den &amp;lt;tt&amp;gt;address&amp;lt;/tt&amp;gt; zeigt, zu erhöhen. Dabei ist &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; eine ganze Zahl und darf auch negativ sein.&lt;br /&gt;
&lt;br /&gt;
Hier noch ein Beispiel einer Funktion, die nach einer Person mit einer bestimmten ID sucht (für die Definition von &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; siehe [[#Strukturen|Strukturen]]). Der Parameter &amp;lt;tt&amp;gt;person&amp;lt;/tt&amp;gt; ist dabei ein Array von Strukturen. Eine Person mit der gesuchten ID muss existieren, ansonsten hat die Suchfunktion kein definiertes Verhalten.&lt;br /&gt;
 {{comment|Sucht nach einer Person mit der ID person_id}}&lt;br /&gt;
 struct Person * &lt;br /&gt;
 suche_person_id (struct Person * person, int person_id)&lt;br /&gt;
 {&lt;br /&gt;
    while (person-&amp;gt;id != person_id)&lt;br /&gt;
       person++;&lt;br /&gt;
 &lt;br /&gt;
    return person;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:1em; padding:1em; border:solid 2px #FF0040;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- Vorlage:FarbigerRahmen funzt hier net --&amp;gt;&lt;br /&gt;
Beachte, daß es nicht sinnvoll ist, zwei Zeiger zu addieren oder zu multiplizieren. Ausserdem ist das &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt; der Zeiger-Arithmetik nicht kommutativ. Eine Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, der an Adresse 1 im Speicher zeigt, wird man schreiben als&lt;br /&gt;
 (long *) 1&lt;br /&gt;
Addiert man darauf eine ganze Zahl, dann haben die entstehenden Ausdrücke unterschiedliche Werte:&lt;br /&gt;
 (long *) 1 + 2    {{comment|zeigt zu Adresse 9}}&lt;br /&gt;
 (long *) 2 + 1    {{comment|zeigt zu Adresse 6}}&lt;br /&gt;
 (long *) (1 + 2)  {{comment|zeigt zu Adresse 3}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==void-Pointer==&lt;br /&gt;
Eine besondere Art von Zeiger ist der void-Pointer&lt;br /&gt;
 void * addr;&lt;br /&gt;
Ein void-Pointer ist ein &amp;quot;Zeiger auf irgendwas&amp;quot;, dementsprechend kann er nicht dereferenziert werden, Anwenden von &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf einen solchen Zeiger gibt also einen Fehler. Ausserdem ist es nicht möglich, mit einem void-Pointer Zeigerarithmetik zu machen, weil er nicht auf eine definierte Art von Objekt zeigt. Der Vorteil eines void-Pointers ist, daß er jede Art von Zeiger aufnehmen kann.&lt;br /&gt;
&lt;br /&gt;
Dazu betrachten wir die Funktion &amp;lt;tt&amp;gt;send_buf&amp;lt;/tt&amp;gt;, die eine Adresse erhält und ab dieser Adresse &amp;lt;tt&amp;gt;num&amp;lt;/tt&amp;gt; Bytes versenden soll. Wir könnten die Funktion so schreiben:&lt;br /&gt;
 void send_buf (unsigned char * buf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   ...&lt;br /&gt;
Das ist jedoch hässlich, wenn wir damit etwas anderes verschicken wollen als &amp;lt;tt&amp;gt; unsigned char&amp;lt;/tt&amp;gt;, etwa eine Struktur wie &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; (vom Typ &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;):&lt;br /&gt;
 send_buf ((unsigned char*) &amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
Ohne den Cast der Adresse von &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; zu einem Zeiger auf &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt; bekommt man eine Warnung oder gar einen Compilerfehler.&lt;br /&gt;
Dieses Zeiger gecaste ist mühsam und hässlich, es muss bei jedem Aufruf der Funktion explizit hingeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Besser ist es, den ersten Parameter der Funktion als void-Pointer zu definieren und den Cast in der Funktion zu machen:&lt;br /&gt;
 void send_buf (void * vbuf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   unsigned char *buf = (unsigned char*) vbuf;&lt;br /&gt;
   ...&lt;br /&gt;
Durch den Cast in der Funktion kann auf den Inhalt des Zeigers zugegriffen werden. Man muss nur festlegen, ''wie'' man zugreifen will, nämlich als &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Der Aufruf kann jetzt ohne Pointer-Cast erfolgen: &lt;br /&gt;
 send_buf (&amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
&lt;br /&gt;
==Null-Pointer==&lt;br /&gt;
==Zeiger als Parameter==&lt;br /&gt;
Wenn Sie ein Unterprogramm aufrufen, können Sie diesem Parameter übergeben, aber keine Werte zurückgekommen (außer den Funktionswert bei Funktionen). Dies hat einen guten Grund: beim Aufruf werden nicht die aufgerufenen Parameter benutzt, sondern es werden deren Werte in neue Variablen kopiert. Diese Variablen werden am Ende des Unterprogrammes &amp;quot;zerstört&amp;quot;, ohne ihre Werte an die aufrufenden Parameter zu übergeben. Jede Veränderung eines Parameters hat daher keine Auswirkung auf den Parameter.&lt;br /&gt;
&lt;br /&gt;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der C-Compiler legt dann immer noch Kopien an. In dieser Kopie steht aber kein Wert, sondern die Adresse einer Varaiblen. Und auf diese können Sie dann zugreifen. Denken Sie nur an &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; &amp;amp;ndash; da übergeben Sie ja auch die Adresse einer Variablen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void erhoehe (int *zeiger)&lt;br /&gt;
{&lt;br /&gt;
  *zeiger = 1 + *zeiger;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  erhoehe (&amp;amp;zahl);&lt;br /&gt;
  printf (&amp;quot;\nDie erhoehte Zahl lautet: %d\n&amp;quot;, zahl);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Zeiger auf Funktionen==&lt;br /&gt;
&lt;br /&gt;
Stell dir vor, du willst einen Sortieralgorithmus wie Bubble-Sort oder Quick-Sort oder wie sie alle heissen implementieren. Für den Sortieralgorithmus ist eigentlich egal, ''was'' er zu sortieren hat. Ihm ist es egal, ob er Zahlen aufwärts sortieren soll oder Strings in lexikographischer Reihenfolge, ob Objekte nach Größe oder Gewicht, Personen nach Alter oder Adressen nach Postleitzahl. Das einzige, was der Algorithmus wissen muss, ist ''wie'' er zwei Objekte zu vergleichen hat und wann eines davon &amp;quot;kleiner&amp;quot; (im Sinne der Ordnung, nach der sortiert werden soll) ist. &lt;br /&gt;
&lt;br /&gt;
Eine einfache Sortierfunktion, die nur zwei Zahlen sortiert, könnte man also so schreiben: &lt;br /&gt;
 {{comment|Sortiert ein Array von 2 int-Zeigern nach den Inhalten &lt;br /&gt;
  * an den Zeiger-Adressen}}&lt;br /&gt;
 void sort2_a (int * p[])&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Inhalte vergleichen...}}&lt;br /&gt;
    if (*p[0] &amp;gt; *p[1])&lt;br /&gt;
    {&lt;br /&gt;
       {{comment|... und ggf. Dreieckstausch der 2 Zeiger}}&lt;br /&gt;
       int * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Die Funktion bekommt ein Array der Länge&amp;amp;nbsp;2. In diesem Array stehen Zeiger auf die zu sortierenden Zahlen. Ein Array mit Zeigern zu verwenden und nicht ein Array von &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; scheint recht umständlich, und das ist es hier auch. Aber stell dir vor, du willst Strukturen wie &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; sortieren. Das Tauschen zweier Strukturen würde bedeuten, ihre kompletten Inhalte umzukopieren! Das wäre sehr aufwändig. Viel einfacher ist das Kopieren, wenn nur die Adressen zu kopieren sind.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; könnte dann so aussehen:&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void sortiere (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|p[] enthält 2 int-Zeiger: die Adressen von a und b}}&lt;br /&gt;
    int * p[2];&lt;br /&gt;
    p[0] = &amp;amp;a; &lt;br /&gt;
    p[1] = &amp;amp;b; &lt;br /&gt;
 &lt;br /&gt;
    {{comment|Sortiere die Zeiger}} &lt;br /&gt;
    sort2_a (p);&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Sortiert: %d, %d\n&amp;quot;, *p[0], *p[1]);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Für den nächsten Schritt überlegen wir uns, daß das Array in &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; ebensogut void-Pointer enthalten kann. Die einzige Stelle, an der wir auf die endgültigen int-Objekte zugreifen, ist der Vergleich. Diesen Vergleich lagern wir in die Funktion &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; aus:&lt;br /&gt;
 {{comment|Bekommt zwei void-Pointer und vergleicht die Inhalte.&lt;br /&gt;
  * Liefert 0 bei Gleichheit,&lt;br /&gt;
  * -1 wenn der erste Wert kleiner ist als der zweite und&lt;br /&gt;
  * 1  wenn der erste Wert größer ist als der zweite}}&lt;br /&gt;
 int compare_int (void * p0, void * p1)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Um über die Zeiger zugreifen zu können müssen wir diese&lt;br /&gt;
     * erst zu int-Zeigern casten}}&lt;br /&gt;
    int a0 = * (int*) p0;&lt;br /&gt;
    int a1 = * (int*) p1;&lt;br /&gt;
 &lt;br /&gt;
    if (a0 &amp;gt; a1)  return  1;&lt;br /&gt;
    if (a0 &amp;lt; a1)  return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void sort2_b (void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare_int (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Ein Aufruf von &amp;lt;tt&amp;gt;sort2_b&amp;lt;/tt&amp;gt; sieht dann genauso aus wie ein Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt definieren wir uns den neuen Datentyp &amp;lt;tt&amp;gt;comparator_t&amp;lt;/tt&amp;gt;. Dieser ist ein Zeiger auf eine Funktion, die zwei void-Pointer erhält und einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; zurückliefert, also analog arbeitet zu &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; von oben. &lt;br /&gt;
&lt;br /&gt;
Unsere Sortierfunktion bekommt nun neben dem zu sortierenden Zeiger-Array auch eine Vergleichsfunktion &amp;lt;tt&amp;gt;compare&amp;lt;/tt&amp;gt; mitgeliefert, die sie aufruft, wenn sie zwei Objekte vergleichen will&lt;br /&gt;
 {{comment|comparator_t sind Zeiger auf Funktionen, die 2 void-Pointer&lt;br /&gt;
  * erhalten und einen int zurückliefern}}&lt;br /&gt;
 typedef int (*comparator_t) (void*, void*);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Der Sortierer bekommt einen Funktionszeiger auf den Vergleicher.&lt;br /&gt;
  * Der Aufruf vom compare geht so als wäre es eine &amp;quot;normale&amp;quot; Funktion&lt;br /&gt;
  * (ist es im Endeffekt ja auch)}}&lt;br /&gt;
 void sort2_c (comparator_t compare, void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Bei einem Aufruf von &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; muss man dann einen Komparator mit angeben. In einem Beispiel analog zu &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; von oben ist das:&lt;br /&gt;
 sort2_c (compare_int, p);&lt;br /&gt;
Um zwei Strings lexikographisch zu sortieren nehmen wie die Standard-Funktion &amp;lt;tt&amp;gt;strcmp&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void foo()&lt;br /&gt;
 {&lt;br /&gt;
    char * worte[] = { &amp;quot;Wort1&amp;quot;, &amp;quot;Wort2&amp;quot; };&lt;br /&gt;
 &lt;br /&gt;
    sort2_c ((comparator_t) strcmp, (void**) worte);&lt;br /&gt;
 }&lt;br /&gt;
Die Casts sind hier erforderlich. Alternativ könnte man &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; mit reinen void-Pointern versorgen und diese dann dort umcasten.&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
&lt;br /&gt;
Die Syntax zur Definition/Deklaration von Funktionszeigern ist etwas verzwackt. Zur Verdeutlichung ein paar Beispiele. Dabei legt das linke &amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt; jeweils den Return-Typ fest.&lt;br /&gt;
 {{comment|definiert einen neuen Funktionszeiger-Typ}}&lt;br /&gt;
 typedef {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert einen Funktionszeiger}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert ein Array von Funktionszeigern (mit Initializer)}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}[]) ({{type}}, {{type}}, ...) = { wert1, wert2, ... };&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer}}&lt;br /&gt;
 ({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer und ruft die Funktion auf}}&lt;br /&gt;
 (({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}) (arg1, arg2, ...);&lt;br /&gt;
&lt;br /&gt;
=Standard-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==String-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===strcpy===&lt;br /&gt;
Bei vielen Compilern können sie einem String nicht direkt einen Wert (Text) zuweisen. Dazu müssen Sie dann die Prozedur strcpy() benutzen. Diese erwartet als ersten Parameter den Namen einer String-Variablen (ohne eckige Klammern) und als zweiten Parameter den eines (anderen) Strings. Letzterer kann auch ein in doppelten Hochkommas (&amp;quot;) eingeschlossener Text sein. Die Funktion fügt am Ende automatisch ein 0-Zeichen ein. Um diese Funktion nutzen zu können, müssen Sie die Datei string.h includieren! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri1[21], eingabe[21];&lt;br /&gt;
&lt;br /&gt;
  strcpy (stri1, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Der 1. String: %s\n&amp;quot;, stri1);&lt;br /&gt;
  printf (&amp;quot;Bitte geben Sie maximal 20 Zeichen ein: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%s&amp;quot;, eingabe);&lt;br /&gt;
  strcpy (stri1, eingabe);&lt;br /&gt;
  printf (&amp;quot;\n%s = %s&amp;quot;, stri1, eingabe);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis:''' &lt;br /&gt;
Da ein String, wie jedes Feld, eigentlich ein Zeiger ist, dürfen Sie kein &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; bei &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; angeben!&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
Es werden zwei gleich große Strings definiert: &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;eingabe&amp;lt;/tt&amp;gt;, mit je 20 &amp;quot;nutzbaren&amp;quot; Zeichen. &lt;br /&gt;
In &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; wird die Zeichenkette &amp;lt;tt&amp;gt;&amp;quot;hallo&amp;quot;&amp;lt;/tt&amp;gt; hineinkopiert. Das 0-Zeichen am Ende wird automatisch angefügt. &lt;br /&gt;
Der String wird ausgegeben. Als neues &amp;quot;Sonderzeichen&amp;quot; kommt &amp;lt;tt&amp;gt;%s&amp;lt;/tt&amp;gt; ins Spiel. Es hat die gleiche Aufgabe wie &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt;, nur für Strings. &lt;br /&gt;
Sie werden gebeten, eine String einzugeben. &lt;br /&gt;
Dieser String wird danach in die Variable &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; kopiert. &lt;br /&gt;
Beide Strings, die ja nun die gleiche Zeichenkette enthalten, werden ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===strlen===&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;strlen&amp;lt;/tt&amp;gt;, die als Parameter eine String-Variable erwartet, liefert die Länge diese Strings zurück. Sie werden jetzt vermutlich sagen: &amp;quot;Das ist doch klar, wie lang der String ist. Ich habe es ja bei der Deklaratin angegeben&amp;quot;. Das stimmt schon, aber denken Sie noch einmal an die null-terminierten Strings. Das 0-Zeichen steht am Ende des Strings (am Ende der gültigen Zeichenfolge), aber nicht unbedingt am Ende des reservierten Speicherplatzes. Haben Sie eine Variable &amp;quot;char Variable[21];&amp;quot;, und ihr den Wert &amp;quot;hallo&amp;quot; zugewiesen, dann steht das null-Zeichen in Variable[5]. Der &amp;quot;gültige&amp;quot; String ist also 5 Zeichen (0-4) lang. Und genau das (5) würde strlen zurück liefern. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri[21];&lt;br /&gt;
  &lt;br /&gt;
  strcpy (stri, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
  printf (&amp;quot;Der String ist %d Zeichen lang&amp;quot;, strlen (stri));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird vor allem gebraucht, wenn Sie direkt auf den String zugreifen, mittels &amp;lt;tt&amp;gt;stri[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;stri[1]&amp;lt;/tt&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
==Ein- und Ausgabe-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===Bildschirm-Ausgabe===&lt;br /&gt;
Bisher war das Tutorial trotz aller Beispiele reine Theorie. Sie konnten zwar Programme schreiben, aber die Funktion nicht testen. Hier lernen Sie nun, wie Sie etwas am Bildschirm ausgeben.&lt;br /&gt;
&lt;br /&gt;
Die dazu notwendige Funktione heisst &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (das '&amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt;' ist kein Fehler!). Diese Anweisung gibt die ihr übergebenen Parameter auf das Standard-Ausgabegerät aus, in der Regel also auf den Bildschirm. Sie kann beliebig viele Parameter übernehmen. Es müssen jedoch Standard-Datentypen (z.B. &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;...) sein! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
    int zahl1 = 12;&lt;br /&gt;
    char zeichen1 = 'A';&lt;br /&gt;
    &lt;br /&gt;
    printf (&amp;quot;Das ist Text, und er wird als solcher ausgegeben. \n&amp;quot;);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zahl1' ist: %d \n&amp;quot;, zahl1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %c \n&amp;quot;, zeichen1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %d \n&amp;quot;, zeichen1);&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt Text aus. Das Zeichen am Ende (&amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;) bedeutet &amp;quot;New Line&amp;quot;, es bewegt den Cursor an den Anfang der nächsten Zeile. &lt;br /&gt;
&lt;br /&gt;
Der zweite &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt auch Text aus, am Ende befindet sich wieder das &amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;, um einen Zeilenvorschub zu erreichen. Das &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; wird vom Compiler durch den ersten Parameter ersetzt, der nach dem Text angegeben wird. In diesem Fall wird &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; also durch den Wert der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ersetzt. Das &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; im &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; bedeutet &amp;quot;Dezimalzahl&amp;quot;, der Computer gibt also eine ganze Zahl aus. &lt;br /&gt;
&lt;br /&gt;
In der dritten Ausgabe wird ein Zeichen ausgegeben. Diesmal bedeutet &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; &amp;quot;char&amp;quot; (Zeichen). Es wird also &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; durch ein &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt; ersetzt, denn die Variable &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; wird als Character interpretiert. &lt;br /&gt;
&lt;br /&gt;
Die letzte Ausgabe interpretiert den Inhalt von &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; als Zahl, und gibt dager den ASCII-Wert von &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, also 65 aus. Das ist ein typisches Beispiel für das mögliche unterschiedliche Interpretieren einer  Variablen!&lt;br /&gt;
&lt;br /&gt;
===Tastatur-Eingabe===&lt;br /&gt;
&lt;br /&gt;
Um ein &amp;quot;gscheites&amp;quot; Programm schreiben zu können, muß man wissen, wie der Benutzer über die Tastatur Befehle eingeben kann. Die dafür notwendigen Funktionen stelle ich in diesem Kapitel vor.&lt;br /&gt;
Die wichtigste Funktion ist &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt;. Er liest Daten von der Tastatur. Die Syntax entspricht derer von &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int  zahl1;&lt;br /&gt;
char zeichen1;&lt;br /&gt;
&lt;br /&gt;
printf (&amp;quot;Bitte geben Sie eine Zahl ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl1);&lt;br /&gt;
printf (&amp;quot;Geben Sie einen Zeichen ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%c&amp;quot;, &amp;amp;zeichen1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Programm gibt eine Eingabeaufforderung aus. Dann erwartet es vom Benutzer, daß er eine Zahl eingibt, die mit [ENTER] bestätigt wird. Dieser Wert wird in &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; abgespeichert. Danach erfolgt wiederum eine Aufforderung zur Eingabe, diesmal eines einzelnen Zeichens. Dieses kann man nun eingeben und ebenfalls mit [ENTER] bestätigen.&lt;br /&gt;
&lt;br /&gt;
Macht man keine dem Datentyp der erwarteten Variable entsprechende Eingabe, dann bricht das Programm mit einer Fehlermeldung ab (wenn man z.B. &amp;quot;1_T2&amp;quot; eingibt, wenn eine Zahl erwartet wird)!&lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; vor den Parametern ist notwendig. Warum, das erfahren Sie im Kapitel &amp;quot;Unterprogramme&amp;quot;. Für die Profis eine Kurz-Erklärung: Das Unterprogramm &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; bekommt zwar einen Wert übergeben, kann aber keinen zurückliefern (&amp;quot;call by value&amp;quot;). Daher wird kein Wert, sondern ein Zeiger auf eine Variable übergeben. Mit dem &amp;amp; Zeichen bekommen Sie die Adresse einer Variablen (&amp;quot;call by reference&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=Parameter von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;=&lt;br /&gt;
Das Unterprogramm &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; kann, wie jede andere Funktion, Parameter besitzen. Doch keine selbst gewählten, sondern nur bestimmte. Doch warum braucht main Parameter? Denken Sie einmal an alle Betriebssystembefehle:&lt;br /&gt;
&amp;lt;tt&amp;gt;dir *.exe &amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;copy *.* a:&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;ls -la &amp;lt;/tt&amp;gt;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen!&lt;br /&gt;
&lt;br /&gt;
=Kurzreferenz=&lt;br /&gt;
==Syntax-Bausteine==&lt;br /&gt;
&lt;br /&gt;
Die Erklärung des Aufbaus von C-Befehlen erfolgt neben einfachen Beispielen auch durch ihren prinzipellen Aufbau. In diesen Syntax-Beschreibungen finden sich immer wieder die gleichen Bausteine, die hier näher erklärt werden sollen. Falls Dir solch ein Syntax-Baustein begegnet, kannst Du ihn anklicken und kommst dann zu seiner Erläuterung. &lt;br /&gt;
&lt;br /&gt;
In den Beispielen selbst gehören auch die spitzen Klammern zu dem Baustein (was daran zu erkennen ist, daß auch die Klammern eingefärbt sind). Die Klammern dürfen in einem konkreten C-Programm daher nicht eingetippt werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bezeichner&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Bezeichner in C dienen dazu, Variablen zu identifizieren und ihnen sprechende Namen zu geben, um die Quelle lesbarer zu machen. Man braucht Bezeichner auch, um selbstdefinierte Datentypen zu benennen und zum Benennen von Struct- und Union-Komponenten sowie als Namen für Funktionen und Sprungmarken (Labels).&lt;br /&gt;
&lt;br /&gt;
Bezeichner dürfen aus den Kleinbuchstaben &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;z&amp;lt;/tt&amp;gt;, den Großbuchstaben &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;Z&amp;lt;/tt&amp;gt;, dem Unterstrich&amp;amp;nbsp;&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt; und den Ziffern &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;9&amp;lt;/tt&amp;gt; aufgebaut werden, wobei an erster Stelle jedoch keine Ziffer stehen darf.&lt;br /&gt;
&lt;br /&gt;
Es wird zwischen Groß- und Kleinschreibung unterschieden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Ausdruck in C ist ein Konstrukt, das einen Wert hat. Ob dieser Wert eine ganze Zahl ist, eine Kommazahl oder ein Zeiger, etc. ist dabei egal. Die einfachsten Ausdrücke sind Konstanten wie&lt;br /&gt;
 2&lt;br /&gt;
oder Variablen wie&lt;br /&gt;
 ein_zahl&lt;br /&gt;
Mehrere Ausdrücke können durch [[#Liste der Operatoren|Operatoren]] zu komplexeren Ausdrücken kombiniert werden, etwa&lt;br /&gt;
 eine_zahl + andere_zahl == 2&lt;br /&gt;
oder &lt;br /&gt;
 eine_zahl = 2&lt;br /&gt;
Letzterer hat den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; und den Nebeneffekt, daß er diesen Wert an &amp;lt;tt&amp;gt;eine_zahl&amp;lt;/tt&amp;gt; zuweist.&lt;br /&gt;
&lt;br /&gt;
Auch der Aufruf einer Funktion, die einen Rückgabewert liefert, ist ein Ausdruck:&lt;br /&gt;
 sin (1.2)&lt;br /&gt;
und kann zum Aufbau komplexerer Ausdrüche verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bedingung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Bedingung ist ein Ausdruck, bei der nur interessiert, ob dieser zu&amp;amp;nbsp;0 (unwahr) auswertet oder zu ungleich&amp;amp;nbsp;0 (wahr). Solche Ausdrücke findet man in if-Anweisungen, in Schleifenbedingungen und bedingten Zuweisungen&lt;br /&gt;
 (ein_wert &amp;lt; 2) || (ein_wert &amp;gt; 40)&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Lvalue ist ein Ausdruck, dem etwas zugewiesen werden kann. Der Name ''Lvalue'' kommt aus dem Englischen. Das ''L'' steht abkürzend für left. Ein Lvalue ist damit ein Ausdruck, der auf der linken Seite eine Zuweisung in C stehen darf. Das &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; in den folgenden Beispiel-Ausdrücken muss ein Lvalue sein:&lt;br /&gt;
 x = y-1&lt;br /&gt;
&lt;br /&gt;
 x++&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Konstante&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Konstante ist ein Ausdruck, dessen Wert dem Compiler bekannt ist. Beispiele für Konstanten sind etwa&lt;br /&gt;
 7&lt;br /&gt;
 'B'&lt;br /&gt;
 -13.98e12&lt;br /&gt;
 1+(2*3)&lt;br /&gt;
und die Werte von [[#Enum|Enum]]s. &lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; aus dem folgenden Codestück definiert jedoch keine Konstante in diesem Sinne&lt;br /&gt;
 const double Pi = 3.14159256;&lt;br /&gt;
denn in einem anderen Quellmodul könnte durch die Deklaration&lt;br /&gt;
 extern const double Pi;&lt;br /&gt;
das Symbol &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; bekannt sein, ohne daß sein Wert bekannt ist!&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Adresse&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Adresse ist ein Ausdruck, der einen Speicherort (physikalisch oder virtuell) halten kann. Adressen erhält man dadurch, daß man einem Bezeichner den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt;voranstellt, Adressen durch Arithmetik berechnet oder Zahlen zu Adressen castet. Folgende Ausdrücke sind Adressen (eine sinnvolle Deklaration der auftretenden Variablen vorausgesetzt)&lt;br /&gt;
 &amp;amp; eine_zahl&lt;br /&gt;
 &amp;amp; ein_array[10]&lt;br /&gt;
 &amp;amp; ein_struct&lt;br /&gt;
 &amp;amp; ein_struct.komponente&lt;br /&gt;
 (int *) 0x1234&lt;br /&gt;
 (int *) eine_zahl&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Deklaration&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Anweisungen sind gewissermassen die Atome (oder Moleküle?), aus denen ein C-Programm besteht. Jedes C-Programm ist eine Abfolge von Deklarationen und Anweisungen. Einfache Anweisungen erhält man, in dem man einen Ausdruck nimmt und einen Strichpunkt dahinter schreibt:&lt;br /&gt;
 {{Ausdruck|}};&lt;br /&gt;
wie in&lt;br /&gt;
 x = x+1;&lt;br /&gt;
&lt;br /&gt;
Andere Anweisungen sind die unten aufgeführten Schleifen und die if- sowie die switch-Anweisung.&lt;br /&gt;
&lt;br /&gt;
Mehrere Deklarationen und Anweisungen können zu einem Block zusammengefasst werden. Dieser Block stellt dann wieder eine einzelne Anweisung dar und kann genau so gehandhabt werden!&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
In diesem Sinne ist auch z.B. die Syntax der if-Anweisung zu verstehen&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
besagt, daß der abhängig ausgeführte Code eine einzelne Anweisung sein darf oder eben ein kompletter Block oder die Verschachtelung mehrerer Blöcke etc.&lt;br /&gt;
&lt;br /&gt;
Eine Anweisung kann auch &amp;quot;leer&amp;quot; sein, also nichts tun. Diese Anweisungen sind der leere Block&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
und der Strichpunkt&lt;br /&gt;
 ;&lt;br /&gt;
die man gelegentlich in Schleifen findet:&lt;br /&gt;
 while (!timeout())&lt;br /&gt;
    {}&lt;br /&gt;
oder hinter Sprungmarken, die sonst direkt vor einer schliessenden Blockklammer stünden:&lt;br /&gt;
 {&lt;br /&gt;
    ...&lt;br /&gt;
    goto ein_label;&lt;br /&gt;
    ...&lt;br /&gt;
    {{Label|ein_label}}:;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Nicht jede Anweisung ist an jeder Stelle eines C-Programms erlaubt, so darf ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; nut innerhalb einer Schleife stehen. Gleiches gilt für &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;, das aber auch innerhalb eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; vorkommen darf.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Dies steht für einen Datentyp. Es kann ein elementarer Typ sein wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;, ein Zeiger darauf wie &amp;lt;tt&amp;gt;char*&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;void*&amp;lt;/tt&amp;gt;, und auch Qualifier enthalten wie das &amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt; im Typ &amp;lt;tt&amp;gt;unsigned long long&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Zu den Typen gehören auch zusammengesetzte Datentypen wie Strukturen und Unions, mit &amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt; selbst definierte Typen und natürlich Zeiger darauf, wie aus dem Abschnitt [[#Datentypen|Datentypen]]:&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person *&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;data32_t&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;&lt;br /&gt;
und Zeiger auf Funktionen.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Parameterliste&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
Die Parameterliste bei einer Funktionsdefinition gibt an, wieviel Übergabeparameter sie bekommt, wie diese heissen und welchen Typs diese sind. Der prinzipielle Aufbau ist&lt;br /&gt;
 {{Type}} {{Bezeichner}}, {{Type}} {{Bezeichner}}, ...&lt;br /&gt;
Falls die Funktion keine Parameter hat, dann ist die Parameterliste leer.&lt;br /&gt;
&lt;br /&gt;
Hier als Beispiel die zweiparametrige Funktion &amp;lt;tt&amp;gt;produkt&amp;lt;/tt&amp;gt;. Der erste Parameter heisst&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und ist ein &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;. Der zweite namens&amp;amp;nbsp;&amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; ist vom Typ &amp;quot;Zeiger auf double&amp;quot;, der Inhalt &amp;lt;tt&amp;gt;*b&amp;lt;/tt&amp;gt; ist also auch ein double.&lt;br /&gt;
&lt;br /&gt;
'''Definition der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b)&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
In älteren C-Quellen findet man noch eine andere Syntax für die Deklaration der Parameter, die aber heute praktisch nicht mehr verwendet wird:&lt;br /&gt;
'''alte Definition der Funktion:'''&lt;br /&gt;
 double produkt (a, b)&lt;br /&gt;
 double a, *b;&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Um die Funktion bekannt zu machen, werdendet man eine Deklaration bzw. den Prototypen, der dem Compiler nur mitteilt, welche Parameter die Funktion bekommt und was sie zurückliefert. Für den Aufruf der Funktion muss der Compiler nur diesen Prototyp kennen, ''was'' die Funktion im Endeffekt macht und wie sie implementiert wurde ist egal, sie wird als BlackBox angesehen.&lt;br /&gt;
&lt;br /&gt;
'''Prototyp der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b);&lt;br /&gt;
Hier dürfen die Bezeichner auch fehlen:&lt;br /&gt;
 double produkt (double, double*);&lt;br /&gt;
&lt;br /&gt;
==if==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==if-else==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==for==&lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Eine for-Schleife entspricht folgendem Konstrukt. Dabei sind die drei Ausdrücke optional. Fehlt die Bedingung, dann wird diese als &amp;quot;wahr&amp;quot; angenommen. Die beiden anderen Ausdrücke wird man als Ausdrücke mit Nebeneffekt wählen wie z.B. &amp;lt;tt&amp;gt;x=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;x=x-2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
 {&lt;br /&gt;
    {{Ausdruck|1}};&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_loop}}:&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
    else&lt;br /&gt;
       goto _break;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_continue}}:&lt;br /&gt;
    {{Ausdruck|2}};&lt;br /&gt;
    goto _loop;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_break}}:;&lt;br /&gt;
 }&lt;br /&gt;
Die Labels &amp;lt;tt&amp;gt;_break&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_continue&amp;lt;/tt&amp;gt; entsprechen den Sprungzielen einer &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Anweisung innerhalb von &amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==do-while==&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while  ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
==while==&lt;br /&gt;
 while  ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==switch==&lt;br /&gt;
 switch  ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    ...&lt;br /&gt;
  &lt;br /&gt;
    default:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#break-Anweisung|&amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Konstanten|&amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#continue-Anweisung|&amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#do-while-Schleife|&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Enum|&amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#for-Schleife|&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#goto-Anweisung|&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#return-Anweisung|&amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Liste der Operatoren|sizeof]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Strukturen|&amp;lt;tt&amp;gt;struct&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Eigene Datentypen|&amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Unions|&amp;lt;tt&amp;gt;union&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#while-Schleife|&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund2}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Arithmetische Operatoren&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Dies sind die &amp;quot;normalen&amp;quot; arithmetischen Operationen, wie man sie aus der Schule kennt. Man kann damit und allen anderen Operatoren auch komplexere Ausdrücke aufbauen. Die Prioritäten sind so, wie man sie kennt, also &amp;quot;Punktrechnung vor Strichrechnung&amp;quot;. Will man dies ändern, dann mit den runden Klammern:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;1+2*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 7&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(1+2)*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 9&amp;lt;br/&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}}&amp;amp;nbsp;+&amp;amp;nbsp;{{Ausdruck|}}&amp;lt;/tt&amp;gt; || Addition&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} - {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Subtraktion&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} * {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Multiplikation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} / {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Division&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} % {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Rest der Division (modulo)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;- {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Vorzeichenumkehr, Zweier-Komplement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Logische Operatoren und Vergleiche&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die logischen und die vergleichenden Operatoren liefern als Ergebnis den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (wahr) oder einen Wert ungleich&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (falsch, um genau zu sein den Wert &amp;lt;tt&amp;gt;!0&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Man kann das Ergebnis zwar einer Variablen zuweisen, in aller Regel wird man solche Ausdrücke jedoch in Bedingungen zu &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder in Abbruch-Bedingungen von Schleifen finden.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;&amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches AND: beides wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124;&amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches OR: mind. eines ist wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;! {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches NOT (0 &amp;amp;harr; ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} == {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} != {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist nicht gleich&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bitweise Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~ {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise NOT (Einser-Komplement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise AND&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise ODER&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} ^ {{Ausdruck|}}&amp;lt;/tt&amp;gt; ||bitweise XOR&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Shift-Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;lt;&amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Bits nach links schieben&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;gt;&amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Schieben nach rechts schieben&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Typen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Ein Cast in C kann dazu verwendet werden, den Typ eines Ausdruckes zu ändern oder den Ausdruck mit einer bestimmten Genauigkeit zu berechnen. Wird z.B. eine Berechnung standardmässig in 16 Bit ausgeführt, dann kann man mit einem Cast &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(long) &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
ausdrücken, daß die Berechnung in 32 Bit erfolgen soll. Des weiteren kann man Zeiger und ganze Zahlen und Gleitkommazahlen ineinander umwandeln.&lt;br /&gt;
&lt;br /&gt;
Casts können ''nicht'' dazu verwendet werden, um z.B. eine Zahl in einen String zu konvertieren, der diese Zahl darstellt! Dafür gibt es spezielle Funktionen wie &amp;lt;tt&amp;gt;itoa&amp;lt;/tt&amp;gt;!&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Type}}) {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Cast, Typwandlung&lt;br /&gt;
|-&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;| &amp;lt;tt&amp;gt;sizeof ({{Type}})&amp;lt;/tt&amp;gt; || Eine Konstante, deren Wert die Größe (in Bytes) des Typs ist. &amp;lt;tt&amp;gt;sizeof&amp;lt;/tt&amp;gt; ist auch auf Objekte anwendbar wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, Arrays bekannter Größe, Strukturen und Unions,  Array-, Struktur- und Union-Komponenten, Pointer, etc. Beispiel:&amp;lt;br/&amp;gt;&lt;br /&gt;
 int i, sum=0, array[] = { 1, -13, 4, 0, sizeof (int*) };&lt;br /&gt;
 &lt;br /&gt;
 for (i=0; i&amp;lt; sizeof (array) / sizeof (array[0]); i++)&lt;br /&gt;
    sum += array[i];&lt;br /&gt;
Alle Elemente des Arrays werden aufaddiert, ohne daß deren Anzahl explizit in der Schleife genannt ist.&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zeiger und Adressen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;* {{Adresse}}&amp;lt;/tt&amp;gt; || der Inhalt an Adresse&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp; {{Lvalue}}&amp;lt;/tt&amp;gt; || Adresse von&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Strukturen, Unions, Arrays&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Struct&amp;gt;}}.{{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Zeiger-auf-Struct&amp;gt;}} -&amp;gt; {{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union, deren Adresse man hat&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Adresse}}&amp;amp;#91;{{Ausdruck|}}&amp;amp;#93;&amp;lt;/tt&amp;gt; || Array-Element&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bedingte Auswertung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Bedingung}}) ? {{Ausdruck|}} : {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Auswahl des Wertes abhängig von der Bedingung&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zuweisung und Operatoren mit Nebeneffekt&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die Unterschiede der post- und pre-Varianten der Increment/Decrement kommen in Konstrukten wie &amp;lt;tt&amp;gt;x = *p++&amp;lt;/tt&amp;gt; zum tragen:&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *p++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; p = p+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *++p;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; p = p+1; x = *p;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = (*p)++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; *p = (*p)+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = ++(*p);&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; *p = (*p)+1; x = *p;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} = {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Zuweisung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++ {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-- {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Decrement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ++&amp;lt;/tt&amp;gt; || Post-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} --&amp;lt;/tt&amp;gt; || Post-Decrement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Kurzschreibweisen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Für ganz Faule gibt es anstatt&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a = a @ b&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
für viele Operatoren (hier dargestellt durch ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;@&amp;lt;/tt&amp;gt;) die abkürzende Schreibweise&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a @= b&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} += {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} -= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} *= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} /= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} %= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ^= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;lt;&amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;gt;&amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Autoren'''&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
* Kernighan und Ritchie - Buch&lt;br /&gt;
* Christian Wirth , C Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://wwwuser.gwdg.de/~kboehm/ebook/inhalt.html C-Programmieren unter Linux]&lt;br /&gt;
* [http://www.gdv.uni-hannover.de/documentation.php Skripte zum Selbststudium: C, C++, Java, etc]&lt;br /&gt;
* [http://info.baeumle.com/ansic.html Einführung in ANSI-C]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Quellcode C|!]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Inrfb2</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10403</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10403"/>
				<updated>2007-03-14T11:52:48Z</updated>
		
		<summary type="html">&lt;p&gt;Inrfb2: /* Syntax-Bausteine */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Programmiersprache C wurde 1971 als Gundlage für das Betriebssystem UNIX in den USA entwickelt (UNIX ist zu über 90% in C geschrieben). 1978 wurde von Brian Kernighan und Dennis Ritchie eine eindeutige Sprachdefinition entwickelt. Mittlerweile ist C von ANSI und ISO standardisiert.&lt;br /&gt;
&lt;br /&gt;
Heute sind C und ihr Nachfolger C++ die dominierenden Programmiersprachen. Sehr viele Anwendungen sind in C geschrieben, was inzwischen auch auf eingebettete Systeme zutrifft, die lange in Assembler programmiert werden mussten, da keine ausreichend leistungsfähigen Compiler zur Verfügung standen. &lt;br /&gt;
&lt;br /&gt;
Leider ist C nicht einfach zu lernen &amp;amp;ndash; es wurde weder von noch für Hobby-Programmierer entwickelt &amp;amp;ndash; und eignet sich daher nur bedingt für den Einsteiger. Mit etwas Übung und einem optimierenden Compiler kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
Vom Design her ist C eine Hardware-unabhängig Sprache. Das bedeutet, daß C-Programme mit vertretbarem Aufwand auf ein anderes System portiert werden können. Dazu benötigt man lediglich einen anderen Compiler, und Inline-Assembler-Anweisungen (Assembleranweisungen innerhalb eines C-Programmes) müssen der neuen Hardware (Prozessor) angepasst werden. &lt;br /&gt;
&lt;br /&gt;
==Geschichte==&lt;br /&gt;
;1971: C wird entwickelt&lt;br /&gt;
;1978: Kernighan und Ritchie definieren die Sprache.&lt;br /&gt;
;1983: ANSI und ISO standardisieren C.&lt;br /&gt;
;1992: Bjarne Stroustrup enwickelt die Nachfolgesprache C++.&lt;br /&gt;
&lt;br /&gt;
=Aufbau eines C-Programmes=&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
   C-Programme haben keinen fixen Aufbau wie z.B. Pascal. Es gibt zwar gewisse Regeln, aber sonst sind dem Programmierer alle Freiheiten überlassen. Der folgende &amp;quot;Beispiel-Aufbau&amp;quot; ist daher nicht zwingend und kann durchaus verändert werden.&lt;br /&gt;
&lt;br /&gt;
   Natürlich haben C-Programme einen fixen Aufbau! Ebenso wie Pascal-Programme auch unterliegen sie einer strikten Grammatik! &lt;br /&gt;
Auskommentiert --[[Benutzer:SprinterSB|SprinterSB]] 10:23, 17. Feb 2006 (CET)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Ein einfaches C-Programm könnte folgendermassen aussehen. Das Programm tut eigentlich nichts, aber das Beispiel zeigt den prinzipiellen Aufbau. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 int Zahl1;&lt;br /&gt;
 char Zeichen1;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int zahl2;&lt;br /&gt;
 &lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Beschreibung:'''&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndash; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
 {{comment|void-Definition von main ist nur beim Controller ueblich}}&lt;br /&gt;
 {{comment|spezielle Compilereinstellungen sind noetig, damit bei dieser Definition von main}}&lt;br /&gt;
 {{comment|kein Fehler/Warnung erzeugt wird.}}&lt;br /&gt;
 void main ()&lt;br /&gt;
 {&lt;br /&gt;
     ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
 int main (void)&lt;br /&gt;
 {  {{comment|der Block &amp;quot;main&amp;quot; beginnt}}&lt;br /&gt;
    int zahl;&lt;br /&gt;
    &lt;br /&gt;
    {   {{comment|ein Block beginnt}}&lt;br /&gt;
        {{comment|hier koennen Deklarationen und Anweisungen stehen}}&lt;br /&gt;
    }   {{comment|der Block endet}}&lt;br /&gt;
   &lt;br /&gt;
    return 0;&lt;br /&gt;
 }  {{comment|&amp;quot;main&amp;quot; endet}}&lt;br /&gt;
&lt;br /&gt;
=Datentypen=&lt;br /&gt;
==Elementare Datentypen==&lt;br /&gt;
Der Datentyp einer Variable gibt an, welche Werte eine Variable enthalten kann, welcher Art diese Daten sind und wie sie verarbeitet werden, etwa in arithmetischen Operationen wie einer Addition. So ist es zum Beispiel möglich, in eine Variable vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ganze Zahlen zwischen ca. -32000 und +32000 einzutragen. In einer char-Variable können ASCII-Zeichen gespeichert werden (alles, was Sie mit der Tastatur erzeugen können) oder ganze Zahlen von -128 bis 127.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da C plattformabhängig ist, hängt die Größe eines Datentypes zum Teil von der genutzten Hardware (z.B. 8, 16 oder 32 Bit-Controller) und dem Compiler und dessen Einstellungen ab!&lt;br /&gt;
&lt;br /&gt;
===int, char, short, long (ganze Zahlen)===&lt;br /&gt;
In Variable dieser Typen können Sie ganze Zahlen abspeichern, also z.B. 1, &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;2, 100, 12345. Jeden dieser Typen gibt es in zwei Ausprägungen: als &amp;quot;&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;quot;, also als vorzeichenbehafteten Typ, und als &amp;quot;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&amp;quot;, also ohne Vorzeichen, d.h. das Vorzeichen wird als 0 oder +1 genommen. &lt;br /&gt;
&lt;br /&gt;
Vorzeichenbehaftete Ganzzahl-Typen werden intern im &amp;lt;tt&amp;gt;n-1&amp;lt;/tt&amp;gt;-Komplement dargestellt, das Vorzeichen selbst findet sich also im höchstwertigen Bit. Werden zur Speicherung ''b'' Bits verwendet, dann reicht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;z.B. *zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==Enum==&lt;br /&gt;
&lt;br /&gt;
Über &amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt; können Aufzählungen definiert werden. Die Werte sind &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Werte und beginnen mit&amp;amp;nbsp;0. Der folgende enum hat einen um&amp;amp;nbsp;1 grösseren Wert. Mit einer Zuweisung können auch andere Werte zugeordnet werden. Klarer wird's im Beispiel:&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 enum Farben&lt;br /&gt;
 {&lt;br /&gt;
    ROT,&lt;br /&gt;
    GRUEN,&lt;br /&gt;
    BLAU,&lt;br /&gt;
    BRAUN = 5,&lt;br /&gt;
    SCHWARZ&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
Dies definiert die Konstanten &amp;lt;tt&amp;gt;ROT=0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;GRUEN=1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BLAU=2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BRAUN=5&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;SCHWARZ=6&amp;lt;/tt&amp;gt; und den Typ &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void foo (enum Farben farbe)&lt;br /&gt;
{&lt;br /&gt;
   switch (farbe)&lt;br /&gt;
   {&lt;br /&gt;
      case ROT:&lt;br /&gt;
         ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit kann man anstatt &amp;quot;magischer&amp;quot; Zahlen sprechende Namen im Code verwenden, etwa in Berechnungen und Zuweisungen, Vergleichen oder als Konstante hinter einem &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zusammengesetzte Datentypen==&lt;br /&gt;
===Arrays===&lt;br /&gt;
Oft muß man sehr viele Werte gleichzeitig abspeichern und betrachten, die alle der selben Aufgabe dienen. Man schreibt z.B. ein Programm, das 10 Zahlen einlesen und anschließend wieder ausgeben soll. Man könnte das natürlich mit 10 einzelnen Variablen bewerkstelligen, aber es ist sinnvoller, dabei Arrays &amp;amp;ndash; teilweise auch als ''Felder'' bezeichnet &amp;amp;ndash; zu verwenden.&lt;br /&gt;
&lt;br /&gt;
In einem Array werden mehrere Variablen gleichen Typs zusammengefasst und hintereinander im Speicher abgelegt. So kann man viele tausend Variablen anlegen mit nur einer Zeile Code. Doch es gibt noch größere Vorteile: Sie können das Array mit einer Schleife ganz einfach nach Werten durchsuchen. Stellen Sie sich vor, Sie müssten mit 100 verschiedenen Variablen &amp;lt;tt&amp;gt;Zahl_00&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;Zahl_99&amp;lt;/tt&amp;gt; arbeiten!&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}}&amp;amp;#91;{{Konstante}}&amp;amp;#93;;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 unsigned int werte[100];&lt;br /&gt;
&lt;br /&gt;
Der Name muß natürlich ein gültiger Bezeichner sein, als Datentyp kann jeder Typ genommen werden &amp;amp;ndash; sowohl elementare Datentypen als auch Zeiger, Strukturen, Unions oder selbst definierte Datentypen. In der eckigen Klammer wird die Anzahl der Elemente bekanntgegeben. Ein mit [3] definiertes Array hat Platz für drei Variablen. Da der Index immer bei 0 beginnt, greift man also mit &amp;lt;tt&amp;gt;[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;[1]&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;[2]&amp;lt;/tt&amp;gt; auf den jeweilige Inhalt zu. Um auf eine der im Array enthaltenen Variablen zugreifen zu können, müssen Sie den Variablennamen und in eckigen Klammern den Index (die &amp;quot;Nummer&amp;quot;) der Variablen angeben. Diese Variable verhält sich dann wie eine ganz normale Variable des jeweiligen Datentypes. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #define NZAHLEN 10&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int i;&lt;br /&gt;
    int zahlen[NZAHLEN];  {{comment|zahlen[0] ... zahlen[9]}}&lt;br /&gt;
  &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++)&lt;br /&gt;
    {&lt;br /&gt;
       printf (&amp;quot;Bitte Zahl %d eingeben: &amp;quot;, i);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; zahlen[i]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++) &lt;br /&gt;
       printf (&amp;quot;Zahl %d ist: %d\n&amp;quot;, i, zahlen[i]);&lt;br /&gt;
      &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 10 int-Variablen großes Array angelegt. &lt;br /&gt;
In dieses wird nun der Reihe nach 10 Zahlen eingelesen. &lt;br /&gt;
Anschließend werden alle 10 Zahlen ausgegeben. &lt;br /&gt;
&lt;br /&gt;
Dabei wird die Größe der Arrays und das Schleifenende über das Define &amp;quot;&amp;lt;tt&amp;gt;NZAHLEN&amp;lt;/tt&amp;gt;&amp;quot; angegeben. Dadurch muss nur ''eine Stelle'' im Code geändert werden, wenn die Größe des Arrays einmal einen anderer Wert als 10 haben soll &amp;amp;ndash; dies vermeidet Fehler die dadurch entstehen, wenn man beim Anpassen der Array-Größe eine Codestelle vergisst, zudem wird der Code lesbarer als wenn irgendwo die Zahl &amp;quot;10&amp;quot; auftaucht.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
:Wird ein ungültiger Index angeben (einer, der in der Deklaration nicht enthalten ist) können  undefinierte Dinge passieren, wenn dadurch andere Variableninhalte oder Programmcode überschrieben wird, der hinter oder vor dem Array im Speicher liegt. Schlimmstenfalls kann sogar der Computer/Controller abstürzen. Also darauf achten, daß keine ungültigen Werte als Index auftreten!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Strings (Zeichenketten)===&lt;br /&gt;
Ein String ist nichts anderes als ein Array, das aus einzelnen Zeichen (&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;) gebildet wird. Die Ausgabe auf dem Bildschirm funktioniert am einfachsten mittels Strings.&lt;br /&gt;
&lt;br /&gt;
Die Definition eines Strings erfolgt also genauso wie bei Arrays:&lt;br /&gt;
 char string[21];&lt;br /&gt;
&lt;br /&gt;
Nun haben Sie eine String, in dem Sie 21 Zeichen speichern können. Ganz richtig ist das jedoch nicht. C arbeitet mit &amp;quot;null-terminierten Strings&amp;quot;. Das beudeutet, dass die Länge des Strings nicht abgespeichert wird, sondern das Zeichen mit dem ASCII-Wert 0 das Stringende kennzeichnet. Daher auch die Bezeichnung  &amp;quot;null terminiert&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Das letzte Zeichen eines Strings muß daher immer das ASCII-Zeichen Nr. 0 sein. Ist es das nicht, hat der String kein definiertes Ende, und wenn Sie versuchen, ihn durch eine Standard-Funktion auszugeben zu lassen, könnte es eine Weile dauern, bis sich im Speicher zufällig irgendwo eine 0 befindet. Es stehen ihnen daher bei dem Beispiel nur 20 Zeichen zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
===Mehrdimensionale Arrays===&lt;br /&gt;
Manchmal benötigt man mehr als nur ein eindimensionales Array, wie Sie es bisher kennengelernt haben. Auch dies ist kein Problem. In der Deklaration geben Sie einfach mehrere eckige Klammern hintereinander an. Aber Vorsicht: der Speicherplatz ist begrenzt, ein &amp;quot;&amp;lt;tt&amp;gt;char feld[1024][1024]&amp;lt;/tt&amp;gt;&amp;quot; hat die Speicherplatzgrenzen vermutlich bereits weit überschritten, und der Compiler wird einen (bei gewissen Einstellung auch keinen) Fehler liefern.&lt;br /&gt;
Beim Zugriff auf mehrdimensionale Felder müssen auch mehrere Indizes angeben werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  int x,y;&lt;br /&gt;
  int feld[3][5];&lt;br /&gt;
 &lt;br /&gt;
  for (x=0; x&amp;lt;3; x++) &lt;br /&gt;
  {&lt;br /&gt;
     for (y=0; y&amp;lt;5; y++)&lt;br /&gt;
     {&lt;br /&gt;
       printf (&amp;quot;Feldwert x: %d,  y: %d &amp;quot;, x, y);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; feld[x][y]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  for(x=0; x&amp;lt;3; x++) &lt;br /&gt;
     for (y=0; y&amp;lt;5; y++) &lt;br /&gt;
        printf (&amp;quot;Wert: feld[%d][%d] = %d\n&amp;quot;, x, y, feld[x][y]);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 3 mal 5 &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array angelegt. &lt;br /&gt;
Dann werden die Werte eingegeben: zuerst &amp;lt;tt&amp;gt;feld[0][0]&amp;lt;/tt&amp;gt;, dann &amp;lt;tt&amp;gt;feld[0][1]&amp;lt;/tt&amp;gt;, usw. bis &amp;lt;tt&amp;gt;feld[2][4]&amp;lt;/tt&amp;gt;. &lt;br /&gt;
Zum Schluß werden alle Werte noch einmal ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===Strukturen===&lt;br /&gt;
In C können Sie sogenannte &amp;quot;Strukturen&amp;quot; definieren. Dabei handelt es sich um eine Zusammenfassung mehrerer Datentypen zu einem größeren. Im Unterschied zu Feldern können in Strukturen unterschiedliche Datentypen zusammengestellt und gespeichert werden: &lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 struct {{Bezeichner}}&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur 'Person'}}&lt;br /&gt;
 struct Person &lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;lt;tt&amp;gt;struct Person {&amp;lt;/tt&amp;gt;&amp;quot; leitet die Definition der Struktur mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;Person&amp;lt;/tt&amp;gt;&amp;quot; ein. &lt;br /&gt;
Dann werden in dieser Struktur fünf Komponenten definiert: drei Strings und zwei &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. &lt;br /&gt;
mit &amp;lt;tt&amp;gt;}&amp;lt;/tt&amp;gt; wird die Definition abgeschlossen. Sie haben damit einen Datentyp erstellt. Um eine Variable des Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach an&lt;br /&gt;
 struct Person {{Bezeichner}};&lt;br /&gt;
&lt;br /&gt;
Zum Zugriff auf eine Komponente der Struktur gibt man den Namen der Struktur-Variablen an (im folgenden Beispiel also &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;klaus&amp;lt;/tt&amp;gt;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
 {{comment|Definition zweier Struktur-Variablen}}&lt;br /&gt;
 struct Person hubert, klaus;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Zugriff auf Struktur-Komponenten}}&lt;br /&gt;
 hubert.alter = 32;&lt;br /&gt;
 klaus.alter = hubert.alter + 1;&lt;br /&gt;
&lt;br /&gt;
===Unions===&lt;br /&gt;
Eine Union wird ganz analog zu einer Struktur deklariert und verwendet. Sie unterscheidet sich von einer Struktur jedoch dadurch, daß ihre Elemente nicht nacheinander im Speicher abgelegt werden, sondern sich überlagern. Auf die in einer Union enthaltenen Daten gibt es also verschiedene Sichten: je nachdem, welche Sicht bzw. Interpretation der Daten man gerne hätte, wählt man den gewünschten Zugriff.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
union Daten &lt;br /&gt;
{&lt;br /&gt;
   int id;&lt;br /&gt;
&lt;br /&gt;
   struct Person u_person;&lt;br /&gt;
&lt;br /&gt;
   struct u_double&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      double wert;&lt;br /&gt;
   };&lt;br /&gt;
&lt;br /&gt;
   struct u_pointer&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      union Daten * p1;&lt;br /&gt;
      union Daten * p2;&lt;br /&gt;
   };&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
union Daten data;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies definiert eine Union mit den vier Zugriffsmöglichkeiten &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_double&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Größe der Union richtet sich dabei nach der grössten Komponente. In diesem Beispiel sind alle Komponenten so angelegt worden, daß sie an erster Stelle ein &amp;lt;tt&amp;gt;int id&amp;lt;/tt&amp;gt; enthalten. In &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; könnte man sich also merken, wie die Daten in der Union zu interpretieren sind. Würde &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; nicht dieses &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; enthalten, so würde sich &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; mit &amp;lt;tt&amp;gt;data.u_person.vname&amp;lt;/tt&amp;gt; überlagern. Ein Ändern der ersten Buchstaben von &amp;lt;tt&amp;gt;vname&amp;lt;/tt&amp;gt; hätte also ein Ändern von &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; zur Folge, und man könnte es nicht mehr als Merker verwenden. Mit diesem Feld überlagert das &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; die &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;-Felder der anderen Sichten, z.B. ist &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; der selbe Zugriff wie auf &amp;lt;tt&amp;gt;data.u_person.id&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein anderes Beispiel ist eine Union, die es ermöglicht, auf die einzelnen Bytes eines &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; zuzugreifen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef union&lt;br /&gt;
{&lt;br /&gt;
   unsigned long  as_long;&lt;br /&gt;
   unsignen short as_short[2];&lt;br /&gt;
   unsignen char  as_byte[4];&lt;br /&gt;
} data32_t;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies überlagert einen &amp;lt;tt&amp;gt;unsigned long&amp;lt;/tt&amp;gt; &amp;amp;ndash; also eine 32-Bit-Zahl &amp;amp;ndash; mit vier Bytes bzw. zwei Shorts.&lt;br /&gt;
 data32_t wert;&lt;br /&gt;
 &lt;br /&gt;
 wert.as_long = 0x12345678;&lt;br /&gt;
 wert.as_byte[0] = 0xab;&lt;br /&gt;
 {{comment|nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform)}}&lt;br /&gt;
&lt;br /&gt;
==Eigene Datentypen==&lt;br /&gt;
&lt;br /&gt;
=Variablen=&lt;br /&gt;
Eine Variable ist ein Synonym (=anderer Name) für eine Speicherstelle in einem Computer. Einfacher gesagt, eine Variable bietet Raum, um Daten wie Zahlen oder Zeichen zu speichern und wieder zu lesen.&lt;br /&gt;
&lt;br /&gt;
==Variablennamen==&lt;br /&gt;
Ein Variablenname kann zusammengesetzt werden aus den Buchstaben &amp;lt;tt&amp;gt;'''A'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''Z'''&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;'''a'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''z'''&amp;lt;/tt&amp;gt;, den Ziffern &amp;lt;tt&amp;gt;'''0'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''9'''&amp;lt;/tt&amp;gt;, sowie dem Sonderzeichen &amp;quot;Unterstrich&amp;quot; (underscore) &amp;lt;tt&amp;gt;'''_'''&amp;lt;/tt&amp;gt;. Dabei darf an erster Stelle keine Ziffer stehen. Die Bezeichner &amp;lt;tt&amp;gt;hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALLO&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALL0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;_123&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_HALLO&amp;lt;/tt&amp;gt; sind also alle gültige und unterschiedliche Variablennamen.&lt;br /&gt;
&lt;br /&gt;
==Anlegen von Variablen==&lt;br /&gt;
Um eine Variable verwenden zu können, muss sie zuerst vereinbart (&amp;quot;erzeugt&amp;quot;) werden. Dies wird auch als &amp;quot;''Definition der Variablen''&amp;quot; bezeichnet und geht so: Schreiben Sie zuerst den Datentyp, dann den Namen der Variablen. Zum Schluß kommt noch der Strichpunkt, wie nach jeder C-Anweisung oder Deklaration. Und nicht vergessen: C unterscheidet zwischen  Groß- und Kleinschreibung! &lt;br /&gt;
 int Zahl1, Zahl2;&lt;br /&gt;
 char Zeichen;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    float gleitZahl;&lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:'''&lt;br /&gt;
In einer Zeile können auch mehrere Variablen gleichen Types vereinbart werden, wenn man ein Komma dazwischen setzt. Variablen können in jedem Block vereinbart werden. Siehe [[#Gültigkeitsbereich|Gültigkeitsbereich]].&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen==&lt;br /&gt;
Man kann einer vereinbarten Variable Werte [[#Zuweisungen|zuweisen]]. Dazu schreibt man zuerst den Variablennamen, ein Gleichheitszeichen &amp;quot;&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;&amp;quot; und anschliessend den zuzuweisenden [[#Ausdrücke|Ausdruck]]. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, zahl2 = 12;&lt;br /&gt;
  char zeichen1 = 'A';&lt;br /&gt;
&lt;br /&gt;
  zahl1 = 52;&lt;br /&gt;
  zeichen1 = zeichen1 + 1; &lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Zuerst werden drei Variablen angelegt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;: wird gleich bei der Vereinbarung der Wert 12 zugewiesen. &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl1 = 52&amp;lt;/tt&amp;gt;: Hier wird der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; der Wert 52 zugewiesen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;: wird um 1 erhöht. Da in der Variablen &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; gespeichert ist, gibt sich ihr neuer Wert aus &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt;. Weil &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; dem Wert 65 entspricht, ist &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt; gleich 66, was dem Wert für &amp;lt;tt&amp;gt;'B'&amp;lt;/tt&amp;gt; entspricht.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei float==&lt;br /&gt;
Das funktioniert genau wie bei normale Zuweisungen. Nachkommastellen werden durch einen Punkt abgegrenzt: &lt;br /&gt;
 floatVariable = 3.14;&lt;br /&gt;
Zusätzlich kann eine Zehnerpotenz angegeben werden:&lt;br /&gt;
 floatVariable2 = -1.234E-6;&lt;br /&gt;
Dadurch wird der erst Wert mit 10&amp;lt;sup&amp;gt;&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;6&amp;lt;/sup&amp;gt; multipliziert, der Wert der Variablen ist also &lt;br /&gt;
:&amp;lt;math&amp;gt;-1{,}234\cdot10^{-6} = -0.000001234&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei logischen Variablen==&lt;br /&gt;
Wie bereits erwähnt, besitzt C keinen logischen Datentyp. Es müssen also &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; dafür genutzt werden. Die Zuweisung entpricht der Standard-Zuweisung. Wird der Wert 0 zugewiesen, dann ist die Variable &amp;quot;unwahr&amp;quot;, ansonsten ist sie &amp;quot;wahr&amp;quot;. &lt;br /&gt;
 intVariable = !0;   /* entspricht &amp;quot;wahr&amp;quot;   */&lt;br /&gt;
 intVariable = 0;    /* entspricht &amp;quot;unwahr&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
==Konstanten==&lt;br /&gt;
Konstanten können als Variable angesehen werden, die nicht beschrieben, sondern nur gelesen werden können. Ein typisches Beispiel dafür ist die Zahl &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; (rund 3,141592654). Niemand würde in der realen Welt versuchen, ihr einen anderen Wert zuzuweisen. Würde man &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; jedoch wie eine normale Variable anlegen, wäre dies ohne weiteres möglich. Um dies zu verhindern, gibt es das Schlüsselwort &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in C:&lt;br /&gt;
 const {{Type}} {{Bezeichner}} = {{Konstante}};  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Wichtig dabei ist, dass man Konstanten nur bei der Vereinbarung einen Wert zuweisen kann. &lt;br /&gt;
Da Konstanten gewöhnlich im gesamten Programm, zumindest einer Quelldatei genutzt werden, definiert man diese allerdings gewöhnlich außerhalb des main-Blockes entweder am Anfang eines Programmes, oder in einer sogenannten Header-Datei, die per &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; eingebunden wird.&lt;br /&gt;
 const float PI = 3.141592;  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Es sei jedoch erwähnt, daß auch einer Konstanten nachträglich ein anderer Wert zugewieden werden kann. Im obigen Beispiel könnte mit&lt;br /&gt;
 * ((float*) &amp;amp;PI) = 2;&lt;br /&gt;
der Wert von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; im Nachhinein verändert werden. Es wird die Adresse von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; genommen und diese Adresse durch den Cast in eine ganz normale &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;-Adresse umgewandelt, über welche der Wert geändert wird. Die sei der Vollständigkeit halber erwähnt.&lt;br /&gt;
&lt;br /&gt;
Je nachdem, an welcher Stelle sich das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; bei einer Pointer-Deklaration befindet, markiert es den Pointer als konstant oder das Objekt, auf das dieser Pointer zeigt. Eine häufige Parameterdeklaration in Ausgabe-Funktionen, die einen String erhalten, ist&lt;br /&gt;
 void foo (const char * str, ...);&lt;br /&gt;
Dadurch ist &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; der Zeiger auf eine Zeichenkette, die innerhalt der Funktion nicht verändert wird bzw. verändert werden darf. Eine Zuweisung wie &amp;lt;tt&amp;gt;*str = 'a'&amp;lt;/tt&amp;gt; ergibt also einen Fehler. &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; selbst kann aber sehr wohl verändert werden, etwa mit &amp;lt;tt&amp;gt;str++&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Soll ausgedrückt werden, daß &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; unveränderlich ist, dann so:&lt;br /&gt;
 void foo (char * const str, ...);&lt;br /&gt;
Jetzt wäre eine Änderung des Strings in Ordnung, etwa durch &amp;lt;tt&amp;gt;str[10] = 'a'&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Um sich zu merken, worauf das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; wirkt, trennt man die Deklaration in Gedanken beim&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf: Steht das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; links vom&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, dann gehört es zum &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, steht es rechts davon, dann gehört es zum Pointer. Natürlich ist es auch denkbar, beides &amp;amp;ndash; also den Zeiger und sein Ziel &amp;amp;ndash; als konstant zu markieren.&lt;br /&gt;
&lt;br /&gt;
==Gültigkeitsbereich==&lt;br /&gt;
In C können mehrere Variablen den gleichen Namen haben, solange eindeutig ist, welche in welchen Block gültig ist. Dabei gelten folgende Regeln: &lt;br /&gt;
&lt;br /&gt;
;Lokale Variablen: sind Variablen, die innerhalb eines Blockes definiert werden. Jede Variable ist nur in dem Block gültig, in dem sie vereinbart wurde, sowie in allen darin enthaltenen Blöcken; es sei denn, in einem Unter-Block wird eine Variable gleichen Namens definiert. Dann bezieht sich in diesem Unter-Block der Bezeichner auf die im Unter-Block angelegte Variable.&lt;br /&gt;
;Globale Variablen: werden ausserhalb jedes Blockes definiert und gelten ab der Stelle, an der sie deklariert werden, siehe auch [[#Deklaration und Definition|Deklaration und Definition]]. Wird jedoch in einem Block eine Variable gleichen Namens angelegt, gilt ab hier bis zum Ende des Blocks nicht mehr die globale Variable, sondern die im Block deklarierte. Das Spiel kann man weiterspielen: wird in einem Unter-Block wieder eine namensgleiche Variable angelegt, gilt diese in dem Unterblock.&lt;br /&gt;
&lt;br /&gt;
==Speicherklassen==&lt;br /&gt;
Jede Variable in C gehört zu einer bestimmten Speicherklasse&lt;br /&gt;
;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;: Lokale Variablen sind in aller Regal sogenannte ''automatische Variablen''. Das bedeutet, sie werden automatisch angelegt, wenn ein Block bzw. eine Funktion betreten wird und danach wieder entfernt. Das Schlüsselwort &amp;quot;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;&amp;quot; wird praktisch nie hingeschrieben, denn lokale Variablen ohne die ausdrückliche Angabe einer Speicherklasse, sind automatisch automatische Variablen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;: Eine externes Symbol ist im ganzen Programm bekannt bzw. in dem Block, in der die Deklaration steht. In unterschiedlichen Blöcken stehende Deklarationen beziehen sich auf das gleiche Symbol! Obgleich das Datum global zugreifbar ist, ist der Gültigkeitsbereich auf den deklarierenden Block begrenzt bzw. auf das deklarierende Quell-Modul, sofern das Symbol ausserhalb jedes Blocks des Moduls deklariert wird. Siehe auch [[#Deklaration und Definition|Deklaration und Definition]].&lt;br /&gt;
;&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;: Die Variable ist im Block gültig bzw. im Quell-Modul (also in der C-Datei, in der die angelegt wurde), wenn sie nicht innerhalb eines Blockes angelegt wurde. Statische Variablen werden nicht in Registern oder im Frame der Funktion angelegt, sondern im selben Speicherbereich, in dem auch die globalen Variablen liegen; Konstanten evtl. auch im Flash. Eine lokale Variable, die als &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; angelegt wird, &amp;quot;überlebt&amp;quot; also das Verlassen des Blocks und hat beim neuerlichen Betreten des Blockes ihren bisherigen Wert. In unterschiedlichen Blöcken angelegte lokale statische Variablen beziehen sich auf unterschiedliche Speicherstellen, genau wie bei lokalen Variablen auch.&lt;br /&gt;
;&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;: Durch diese Speicherklasse wird eine Variable &amp;amp;ndash; falls möglich &amp;amp;ndash; als Registervariable angelegt, also in einem Maschinenregister des Computer/Controllers gehalten. Dadurch kann auf solche Variablen besonders schnell zugegriffen werden. Dieses Schlüsselwort ist bei modernen Compilern weitgehend überflüssig, da die entsprechenden Optimierungen selbständig vorgenommen werden, wenn ausreichend Register vorhanden sind. Auch globale Variablen können als Register angelegt werden, davon ist dem Anfänger aber dringend abzuraten, weil leicht schwerauffindbare Fehler und Abstürze auftreten, wenn man nicht genau weiss, welche Implikationen in einer solchen Definition stecken!&lt;br /&gt;
;&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;: (FIXME: volatile ist ein Qualifier und keine Speicherklasse) Dies ist das genaue Gegenteil von &amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt; und bewirkt, dass die Variable auf keinen Fall in einem Register zwischengespeichert werden darf, sondern immer aus dem RAM gelesen und ins RAM geschrieben werden soll. &amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt; müssen alle ''globalen'' Variablen markiert werden, die in [[ISR | Interrupt-Handlern]] verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Ausdrücke=&lt;br /&gt;
Eine Variable oder eine Konstante in C stellen einfache Ausdrücke dar.&lt;br /&gt;
Diese elementaren Ausdrücke können durch Operatoren miteinander verknüpft werden und so zu neuen, komplexeren Ausdrücken zusammen gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Einfache Beispiele für Ausdrücke sind also z.B.:&lt;br /&gt;
 1&lt;br /&gt;
 a&lt;br /&gt;
 'a'&lt;br /&gt;
 1 + a&lt;br /&gt;
 a == 1&lt;br /&gt;
&lt;br /&gt;
Auch Funktionen können einen Wert zurückliefern und in Ausdrücken weiter benutzt werden.&lt;br /&gt;
In den folgenden Abschnitten wird gezeigt, welche Operatoren in C vorhanden sind,&lt;br /&gt;
und wei man damit neue Ausdrücke aufbauen kann.&lt;br /&gt;
&lt;br /&gt;
==Lvalues==&lt;br /&gt;
&lt;br /&gt;
Ein Lvalue in C ist ein Ausdruck, dem ein anderer Ausdruck zugewiesen werden kann, dessen Wert also durch eine Zuweisung verändert werden kann.&lt;br /&gt;
das 'L' leitet sich ab von 'left' bwz. 'links' und das 'value' bedeutet Wert: Ein Lvalue ist ein Ausdruck, der auf der linken Seite einer Zuweisung stehen darf. Ein Lvalue ist also immer auch ein gültiger Ausdruck, aber die Umkehrung gilt in alles Regel nicht.&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für einen Lvalue ist eine &amp;quot;normale&amp;quot; Variable, die nicht mit &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; als Konstante markiert ist:&lt;br /&gt;
 a = 1;&lt;br /&gt;
Hingegen ist der Ausdruck &amp;lt;tt&amp;gt;a+1&amp;lt;/tt&amp;gt; kein Lvalue, denn eine Zuweisung wie&lt;br /&gt;
 a+1 = 2;&lt;br /&gt;
die mathematisch durchaus sinnvoll ist, erzeugt einen Compilerfehler, der etwa lauten könnte &amp;quot;illegal lvalue in assignment&amp;quot;:&lt;br /&gt;
&amp;quot;ungültiger Wert in Zuweisung&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Andere Beipiele für Lvalues sind die Komponenten von (nicht-konstanten) [[#Strukturen|Strukturen]] und [[#Unions|Unions]], [[#Arrays|Array]]-Elemente und die Dereferenzierungen von Pointern: Die Konstante&amp;amp;nbsp;4 wird durch den Cast in eine Adresse umgewandelt. Über die Dereferenzierung&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; wird an die Adresse&amp;amp;nbsp;4 im Speicher eine&amp;amp;nbsp;3 geschrieben. Ob das erlaubt bzw. sinnvoll ist, ist abhängig von der jeweiligen Architektur.&lt;br /&gt;
 * ((unsigned int *) 4) = 3;&lt;br /&gt;
Hier ist der gesamte &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;-Ausdruck ein Lvalue&lt;br /&gt;
&lt;br /&gt;
==Logische (boolsche) Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp;amp;&amp;amp;amp; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr oder &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; || gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; || ungleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;= b&amp;lt;/tt&amp;gt; || kleiner oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt; b&amp;lt;/tt&amp;gt; || kleiner als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt;= b&amp;lt;/tt&amp;gt; || glösser oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt; b&amp;lt;/tt&amp;gt; || grösser als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; nicht wahr und vice versa&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine interessante Eigenschaft der Operatoren &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;amp;amp;&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; ist, dass&lt;br /&gt;
sie die Auswertung abbrechen, sobald das Ergebnis feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet. Ein oft anzutreffendes Codestück sieht so aus, dabei sei &amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
  if (p &amp;amp;&amp;amp; *p == 5)&lt;br /&gt;
  {&lt;br /&gt;
     {{comment|mach was}}&lt;br /&gt;
  }&lt;br /&gt;
Zuerst wird in der Bedinung geprüft, ob Zeiger&amp;amp;nbsp;&amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; einen Wert ungleich Null hat, also ob er überhaupt einen gültigen Wert enthält. Es ist weit verbreitete Konvention in C, daß Zeiger, die keinen gültigen Wert haben, die Adresse&amp;amp;nbsp;0 enthalten. '''Nur dann, wenn ein Zeiger nicht ein Null-Pointer ist, darf überhaupt ein Zugriff über ihn erfolgen!'''&lt;br /&gt;
&lt;br /&gt;
==Vergleich von Variablen==&lt;br /&gt;
Skalare Variablen (also ganze Zahlen, Gleitkommazahlen, Zeiger) können miteinander verglichen werden. Dazu gibt es die folgenden Operatoren in C: &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; || ist nicht gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;=&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;=&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das Ergebnis der Auswertung ist eine ganze Zahl. Ist die Bedingung erfüllt, dann ist der Wert ungleich&amp;amp;nbsp;0. Ist die Bedingung nicht erfüllt, dann ist ihr Wert gleich&amp;amp;nbsp;0.&lt;br /&gt;
Meistens wird man diese Operatoren in &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Konstrukten finden wie zum Beispiel&lt;br /&gt;
 if (x &amp;gt;= 10)&lt;br /&gt;
    x = 10;&lt;br /&gt;
oder in Abbruchbedingungen von Schleifen, wie sie weiter unten erklärt werden.&lt;br /&gt;
&lt;br /&gt;
Es ist auch möglich, das Ergebnis der Auswertung in einer &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Variablen zu speichern:&lt;br /&gt;
 int i;&lt;br /&gt;
 int z1, z2;&lt;br /&gt;
 &lt;br /&gt;
 z1 = 5;&lt;br /&gt;
 z2 = 100;&lt;br /&gt;
 i = z1 &amp;lt;= z2;  {{comment|Ein Vergleich. i wird &amp;quot;wahr&amp;quot;, da z1 kleinergleich z2 ist}}&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich&amp;amp;nbsp;0 (&amp;quot;wahr&amp;quot;), wenn &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; kleiner oder gleich &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt; ist. Ist &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; jedoch größer als &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt;, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich&amp;amp;nbsp;0 (&amp;quot;unwahr&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
==Arithmetische Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a + b&amp;lt;/tt&amp;gt; || Summe (Addition)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a - b&amp;lt;/tt&amp;gt; || Differenz (Subtraktion)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a * b&amp;lt;/tt&amp;gt; || Produkt (Multiplikation)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a / b&amp;lt;/tt&amp;gt; || Quotient (Division, evtl. mit Rest)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a % b&amp;lt;/tt&amp;gt; || Rest bei Division (Modulo)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;-a&amp;lt;/tt&amp;gt; || Vorzeichenumkehr (Zweierkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Bit-Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp; b&amp;lt;/tt&amp;gt; || bitweise und (and)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || bitweise oder (or)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a ^ b&amp;lt;/tt&amp;gt; || bitweise exclusiv-oder (xor, exor)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;~a&amp;lt;/tt&amp;gt; || jedes Bit in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; invertieren (not, Einerkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Index-Operator bei Arrays==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a[b]&amp;lt;/tt&amp;gt; || das (b+1)ste Element des Feldes a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Folgendes gilt es bei der Verwendung des Indexoperators zu beachten:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; muss ein [[C-Tutorial#Felder | Feld]] oder [[C-Tutorial#Zeiger | Zeiger]] sein&lt;br /&gt;
# &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; muss ein Integer sein oder ein Datentyp, der sich in einen int umwandeln läßt (z.B. char)&lt;br /&gt;
# Es wird nicht geprüft, ob der Index &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; im Feld &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gültig ist!&lt;br /&gt;
# Der erste Index eines Feldes ist immer 0. Daher ''(b+1)stes Element'' in der Beschreibung&lt;br /&gt;
&lt;br /&gt;
==Komponenten-Auswahl bei Structs und Unions==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a.b&amp;lt;/tt&amp;gt; || Element b der [[C-Tutorial#Strukturen | Struktur]] oder des Unions a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adress-Operator und Dereferenzierung==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&amp;amp;amp;a&amp;lt;/tt&amp;gt; || Speicheradresse der Variablen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;*a&amp;lt;/tt&amp;gt; || Wert, der an der Adresse &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a-&amp;amp;gt;b&amp;lt;/tt&amp;gt; || Wert des Elements &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; der Struktur, deren Adresse in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Adressoperator &amp;amp; kann auf Variablen angewendet werden und&lt;br /&gt;
gibt die Startadresse der Variablen im Speicher zurück.&lt;br /&gt;
&lt;br /&gt;
Handelt es sich bei einer Variable um einen [[C-Tutorial#Zeiger | Zeiger]], so enthält&lt;br /&gt;
sie eine Speicheradresse. Um an den '''Wert''' zu gelangen, der&lt;br /&gt;
an dieser Adresse steht, wird der Operator * vorangestellt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
&lt;br /&gt;
 {{comment|x ist eine Integervariable und hat den Wert 5}}&lt;br /&gt;
 int x = 5;&lt;br /&gt;
     &lt;br /&gt;
 {{comment|z ist ein Zeiger auf eine Integer-Variable und enthaelt somit}}&lt;br /&gt;
 {{comment|die Speicheradresse einer Integer-Variablen}}&lt;br /&gt;
 int *z;       &lt;br /&gt;
  &lt;br /&gt;
 {{comment|Verwendung des Adress-Operators: weist an z die Adresse von x zu}}&lt;br /&gt;
 z = &amp;amp;x;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Verwendung der Dereferenzierung}}&lt;br /&gt;
 {{comment|erhoehe den Wert, der bei Adresse z steht, um eins}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|da z auf x zeigt, hat x jetzt den Wert 6}}&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff auf Struktir- und Union-Elemente eine abkürzende Schreibweise möglich:&lt;br /&gt;
&lt;br /&gt;
Statt &lt;br /&gt;
  (*strukturZeiger).element&lt;br /&gt;
kann geschrieben werden&lt;br /&gt;
  strukturZeiger-&amp;gt;element&lt;br /&gt;
Beide Schreibweisen sind absolut gleichbedeutend, die Klammern bei der ersteren sind notwendig.&lt;br /&gt;
&lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
:Bei der Dereferenzierung durch &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; findet keine Prüfung statt, ob der Zeiger auch auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu einer Änderung '''irgendeiner''' Speicherstelle!&lt;br /&gt;
&lt;br /&gt;
 int *z; {{comment|z ist ein Zeiger auf einen int}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.}}&lt;br /&gt;
 {{comment|z enthaelt irgendeine ungueltige Adresse!!}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|&amp;quot;Erhoehe einen Integer _irgendwo_ im Speicher um 1&amp;quot; -&amp;gt; CRASH !!!}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
&lt;br /&gt;
==Cast-Operator==&lt;br /&gt;
&lt;br /&gt;
Der Cast Operator dient dazu, den Datentyp eines Wertes zu ändern. Dafür wird einfach der neue Datentyp in Klammern vor den Wert geschrieben.&lt;br /&gt;
&lt;br /&gt;
Um zum Beispiel aus einem Float ein Integer zu machen:&lt;br /&gt;
 var  = (int) 5.60;&lt;br /&gt;
Dabei wird der Wert aber auch gerundet, und es findet somit ein Informationsverlust statt.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Umwandeln einer ganzen Zahl in eine Adresse:&lt;br /&gt;
 int * addr;&lt;br /&gt;
 addr = (int*) 0x1234;&lt;br /&gt;
Damit ist &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; an Adresse 0x1234.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
Der Cast-Operator selbst führt ''keine Konvertierung'' von Darstellungen durch, etwa die Umwandlung der ganzen Zahl 123 ein den String &amp;lt;tt&amp;gt;&amp;quot;123&amp;quot;&amp;lt;/tt&amp;gt;, der diese Zahl darstellt! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
  int main(int argc, char ** argv)&lt;br /&gt;
  {&lt;br /&gt;
        char text[] = &amp;quot;5.6&amp;quot;;&lt;br /&gt;
        int zahl = (int) text;&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, zahl);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Anfangsadresse des Strings &amp;lt;tt&amp;gt;&amp;quot;5.6&amp;quot;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Komma-Operator==&lt;br /&gt;
Mit einem &amp;lt;tt&amp;gt;,&amp;lt;/tt&amp;gt; können mehrere Ausdrücke nacheinander ausgewertet werden.&lt;br /&gt;
Die Auswertung erfolgt von links nach rechts.&lt;br /&gt;
&lt;br /&gt;
Solche Konstrukte sieht man manchmal in Abfragen wie&lt;br /&gt;
 FILE  *file;&lt;br /&gt;
 if (file = fopen (&amp;quot;foo.exe&amp;quot;, &amp;quot;r&amp;quot;), file != NULL)&lt;br /&gt;
was erst an &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; einen Wert zuweist und den &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Block nur betritt,&lt;br /&gt;
wenn &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; nicht der Nullpointer ist.&lt;br /&gt;
&lt;br /&gt;
Bequem kann das auch in einer [[#for-Schleife|for-Schleife]] sein, wenn man zwei (oder mehr) Laufvariablen hat oder so:&lt;br /&gt;
 for (i=0, j=0; i &amp;lt; 10; i++, j += 2)&lt;br /&gt;
    &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Zuweisung===&lt;br /&gt;
=== ++ und -- ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; stellen einfachere Schreibweisen dar zum Addieren bzw. Subtrahieren von&amp;amp;nbsp;1.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; (Inkrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo++; &lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo + 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; 3}}&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; (Dekrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo--;&lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo - 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; -1}}&lt;br /&gt;
&lt;br /&gt;
Die beiden Operatoren können sowohl in der Präfix-Schreibweise (vor der Variablen) als auch als Postfix-Schreibweise (hinter der Variablen) notiert werden. &lt;br /&gt;
Der Unterschied liegt darin, dass beim Präfix der Wert zuerst neu berechnet wird und die Variable dann verwendet wird. Beim Postfix wird die Variable zuerst verwendet und erst nach Auswertung des Ausdrucks, in dem sie enthalten ist, neu berechnet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 int ausgabe1, ausgabe2, var1 = 10, var2 = 10;&lt;br /&gt;
 ausgabe1 = 3 * ++var1; {{comment|ausgabe1 &amp;amp;#61; 33; var1 &amp;amp;#61; 11;}}&lt;br /&gt;
 ausgabe2 = 3 * var2++; {{comment|ausgabe2 &amp;amp;#61; 30; var2 &amp;amp;#61; 11;}}&lt;br /&gt;
&lt;br /&gt;
Für Zeiger arbeiten diese Operatoren etwas anders, siehe dazu [[#Zeiger-Arithmetik|Zeiger-Arithmetik]].&lt;br /&gt;
&lt;br /&gt;
===Bedingter Ausdruck===&lt;br /&gt;
 ({{Bedingung}}) ? {{Ausdruck|1}} : {{Ausdruck|2}}&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; erfüllt ist, dann wertet dieser Ausdruck aus zu &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt;. Ist er nicht erfüllt, dann wertet er aus zu &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 x = (x &amp;gt;= 3) ? 0 : x+1;&lt;br /&gt;
Startet man &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; mit dem Wert 0, dann nimmt es bei mehrfacher Anwendung dieser Zeile (z.B. in einer Schleife) nacheinander die folgende Werte an:&lt;br /&gt;
:&amp;lt;tt&amp;gt;1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, ...&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&lt;br /&gt;
Wie auch in der Mathematik gibt es auch in C genaue Regeln über die Abarbeitungsreihenfolge (precedence)&lt;br /&gt;
der Operatoren. Dass sich alle C-Compiler genau an diesen ANSI-Vorschlag halten, ist leider nicht sicher.&lt;br /&gt;
Sicher jedoch ist, dass nicht jeder Programmierer diese Regel jederzeit im Kopf hat. &lt;br /&gt;
Daher ist es sinnvoll, Ausdrücke durch runde Klammern eindeutig zu kennzeichnen. &lt;br /&gt;
Nebenbei stören sich Compiler nicht an überflüssigen Klammerpaaren.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Priorität ||Operator||Assoziativität&lt;br /&gt;
|-&lt;br /&gt;
  &lt;br /&gt;
|&amp;lt;tt&amp;gt;15&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ( ) [ ] -&amp;gt; . &amp;lt;/tt&amp;gt;                      ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;14&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;! ~ ++ -- + - (TYP) * &amp;amp; sizeof &amp;lt;/tt&amp;gt;    ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;13&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; * / % (Rechenoperationen) &amp;lt;/tt&amp;gt;         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;12&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; + - (binär) &amp;lt;/tt&amp;gt;                       ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;11&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;&amp;lt; &amp;gt;&amp;gt; &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;10&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt; &amp;lt;= &amp;gt; &amp;gt;= &amp;lt;/tt&amp;gt;                         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 9&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; == != &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 8&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp; (bit-AND-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 7&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ^ (bit-XOR-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 6&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; (bit-OR-Operator)&amp;lt;/tt&amp;gt;   ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 5&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp;&amp;amp; &amp;lt;/tt&amp;gt;                                ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 4&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; &amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 3&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;? : &amp;lt;/tt&amp;gt;                               ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 2&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; = += -= /= *= %= &amp;gt;&amp;gt;= &amp;lt;&amp;lt;= &amp;amp;= &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;= ^= &amp;lt;/tt&amp;gt; ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 1&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; , (Sequenz-Operator) &amp;lt;/tt&amp;gt;              ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
&lt;br /&gt;
Peter Baeumle-Courth, ANSI-C im Überblick &amp;lt;p&amp;gt;&lt;br /&gt;
W. Alex, Einführung in C/C++&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
Eine Kontrollanweisung ist eine Anweisung, die Einfluss auf den Programmfluss hat. Normalerweise werden Anweisungen so ausgeführt, wie sie in der Quelldatei stehen: Von links nach rechts (falls mehrere Anweisungen in einer Zeile stehen sollten, wovon i.A. abzuraten ist) und von oben nach unten. Mit einer Kontrollanweisung kann dieser lineare Programmfluss durchbrochen werden: Die Codeausführung kann kann abhängig von einer Bedingung gemacht werden (&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;), kann wiederholt werden (Schleife) oder an einer anderen Stelle der Funktion fortgesetzt werden (&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==if-Anweisung==&lt;br /&gt;
Mit Hilfe des if-Befehls kann man Codeteile abhängig davon einer Bedingung ausführen lassen:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
oder mit else-Teil&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 if (x &amp;gt; 100)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;gt; 100 ist: Fehlerausgabe}}&lt;br /&gt;
    printf (&amp;quot;x = %d ist zu gross fuer die Berechnung!\n&amp;quot;, x);&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;lt;&amp;amp;#61; 100 ist: Berechne Summe der Zahlen 1...x}}&lt;br /&gt;
    {{comment|Die lokale Variable x2 lebt nur innerhalb dieses alse-Blocks}}&lt;br /&gt;
    int x2 = x;&lt;br /&gt;
 &lt;br /&gt;
    for (x = 0; x2 &amp;gt; 0; x2--)&lt;br /&gt;
       x += x2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Wenn die Bedingung wahr ist (&amp;lt;tt&amp;gt;x &amp;gt; 100&amp;lt;/tt&amp;gt;), dann wird eine Meldung ausgegeben; danach ist die if-Anweisung beendet. Der else-Block wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung nicht erfüllt (&amp;lt;tt&amp;gt;x &amp;amp;le; 100&amp;lt;/tt&amp;gt;), dann wird gleich zum else-Teil gesprungen, und nach dessen Ausführung der if-Befehl beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Ein häufiger Fehler ist es, statt &amp;lt;tt&amp;gt;if (a &amp;amp;#61;&amp;amp;#61; 23)&amp;lt;/tt&amp;gt; etwas wie &amp;lt;tt&amp;gt;if (a &amp;amp;#61; 23)&amp;lt;/tt&amp;gt; zu schreiben. &lt;br /&gt;
Dann wird allerdings nicht geprüft, ob die Variable&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gleich 23 ist, sondern der Variablen&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wird der Wert 23 zugewiesen. Der Ausdruck &amp;lt;tt&amp;gt;a &amp;amp;#61; 23&amp;lt;/tt&amp;gt; hat den Wert&amp;amp;nbsp;23 und ist damit immer &amp;quot;wahr&amp;quot;! Daher ist diese if-Bedingung immer erfüllt!&lt;br /&gt;
&lt;br /&gt;
Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken sondern bestenfalls eine Warnung. Damit ist dieser Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise &amp;lt;tt&amp;gt;if (23 &amp;amp;#61;&amp;amp;#61; a)&amp;lt;/tt&amp;gt;. Wenn man dort anstatt des Vergleichsoperators '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;amp;#61;&amp;lt;/tt&amp;gt;' den Zuweisungsoperator '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;lt;/tt&amp;gt;' verwendet, spuckt der Compiler sehr wohl einen Fehler aus! Ist die Zuweisung jedoch erwünscht und eine Compiler-Warnung lästig, dann wählt man eine Schreibweise wie &amp;lt;tt&amp;gt;if ((a &amp;amp;#61; b))&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;if (a &amp;amp;#61; b, a)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist zu schreiben &amp;lt;tt&amp;gt;if (Bedingung);&amp;lt;/tt&amp;gt; Richtig muss es heissen &amp;quot;&amp;lt;tt&amp;gt;if(Bedingung)&amp;lt;/tt&amp;gt;&amp;quot; Das Semikolon im ersten Fall ist eine leere Anweisung, die im if-Falle ausgeführt wird &amp;amp;ndash; sie bleibt also ohne Resultet. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt; ein auf das Semikolon folgende Anweisung die eigentlich zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören soll wird immer ausgeführt, die sie nicht mehr zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; dazu gehört.&lt;br /&gt;
}}&lt;br /&gt;
Bei verschachtelten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Konstrukten gehört ein &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zu letzten &amp;quot;freien&amp;quot; &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;. Soll in einer &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Folge das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zum ersten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören, dann ist das so zu hinzuschreiben:&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Ohne die geschweiften Klammern um das zweite &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehörte das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; dort hinzu.&lt;br /&gt;
&lt;br /&gt;
==switch-Anweisung==&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
&lt;br /&gt;
 switch ({{Ausdruck|}}) &lt;br /&gt;
 {&lt;br /&gt;
     case konstante1:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
    &lt;br /&gt;
     case konstante2:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 &lt;br /&gt;
     {{comment|weitere case-Marken}}&lt;br /&gt;
 &lt;br /&gt;
     default:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 } {{comment|Ende von switch}} &lt;br /&gt;
&lt;br /&gt;
Der Ausdruck muss ein skalarer Typ sein, er wird in die nächste ganze Zahl gewandelt und mit den Werten hinter den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Marken verglichen. Bei einer Übereinstimmung werden alle Befehle ab dem zutreffenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; ausgeführt. Stimmt der Ausdruck mit keinem der Werte überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt falls vorhanden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der nachfolgenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;- und des &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitts werden ausgeführt, wenn die Anweisungen des &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitts nicht mit dem Befehl &amp;lt;tt&amp;gt;break;&amp;lt;/tt&amp;gt; beendet werden!&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es dürfen beliebig viele &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitte angegeben werden, pro Vergleichswert jedoch nur einer.&lt;br /&gt;
Der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ist optional. Die Reihenfolge, in der &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt; angegeben werden, ist unerheblich.&lt;br /&gt;
&lt;br /&gt;
==Schleifen==&lt;br /&gt;
Um Anweisungen mehrmals hintereinander auszuführen, benötigt man Schleifen. Diese führen Anweisungen aus, bis oder solange Bedingungen erfüllt sind.&amp;lt;br&amp;gt; &lt;br /&gt;
Wichtig ist also, ob die Bedingung '''vor''' oder '''nach''' den Schleifen-Anweisungen geprüft wird. &lt;br /&gt;
&lt;br /&gt;
===while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 while ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Die while-Schleife wird solange durchlaufen, wie die Bedingung erfüllt ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Die Anweisung kann natürlich auch ein Block sein, der aus mehreren Deklarationen und Anweisungen besteht. &lt;br /&gt;
&lt;br /&gt;
 int zahl1 = 0;&lt;br /&gt;
 int zahl2 = 1;&lt;br /&gt;
 &lt;br /&gt;
 while (zahl1 &amp;lt; 3)&lt;br /&gt;
 {&lt;br /&gt;
    zahl1 = zahl1 + 1;&lt;br /&gt;
    zahl2 = zahl2 * 2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife drei mal durchlaufen. Zu Beginn des vierten Durchlaufs ist die Bedingung nicht mehr erfüllt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
&lt;br /&gt;
===do-while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
Die do-while-Schleife wird auf jeden Fall einmal durchlaufen und dann solange wiederholt, wie die Bedingung erfüllt ist.&lt;br /&gt;
 int i = 2;&lt;br /&gt;
 &lt;br /&gt;
 do &lt;br /&gt;
 {&lt;br /&gt;
     i = i*i;   {{comment|i quadrieren}}&lt;br /&gt;
     printf (&amp;quot;i = %d\n&amp;quot;, i);&lt;br /&gt;
 }&lt;br /&gt;
 while (i &amp;lt; 20);&lt;br /&gt;
&lt;br /&gt;
Die Schleife wird durchlaufen und wiederholt, solange &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; kleiner als 20 ist. Es werden also nacheinander die Werte 2, 4 und 16 ausgegeben. Nach der Schleife hat&amp;amp;nbsp;&amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; den Wert 256.&lt;br /&gt;
&lt;br /&gt;
===for-Schleife===&lt;br /&gt;
'''Syntax:''' &lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Bei den Ausdrücken wird es sich um einen Ausdrücke mit Nebeneffekt handeln wie etwa &amp;lt;tt&amp;gt;i=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;i=i+2&amp;lt;/tt&amp;gt;. Es werden folgende Aktionen ausgeführt:&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# falls die Bedingung wahr ist, dann führe &amp;lt;tt&amp;gt;Anweisung&amp;lt;/tt&amp;gt; aus.&lt;br /&gt;
# falls die Bedingung unwahr ist, dann sprinte zu 7 (Ende).&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# gehe zu 2&lt;br /&gt;
# nächste Anweisung nach der for-Schleife&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int lauf, summe;&lt;br /&gt;
 &lt;br /&gt;
 for (lauf=1, summe=0; lauf &amp;lt;= 10; lauf += 2) &lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel ist &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; ein [[#Komma-Operator|Komma-Ausdruck]], der zwei Anweisungen kombiniert und daher sogar zwei Nebeneffente hat: er setzt &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;1 und &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;0.&lt;br /&gt;
&lt;br /&gt;
Das Äquivalent als while-Schleife:&lt;br /&gt;
&lt;br /&gt;
 int lauf  = 1;                 {{comment|Anfangswerte}}&lt;br /&gt;
 int summe = 0;&lt;br /&gt;
 &lt;br /&gt;
 while (lauf &amp;lt;= 10)             {{comment|Bedingung}}&lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
    lauf  += 2;                 {{comment|Inkrement}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; in jedem Schleifendurchlauf um die Laufvariable &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; erhöht. Da &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nacheinander die ungeraden Werte von&amp;amp;nbsp;1 bis&amp;amp;nbsp;10 annimmt, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von&amp;amp;nbsp;1 bis kleinergleich 10 gespeichert, also der Wert&amp;amp;nbsp;25. &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; hat nach der Schleife den Wert&amp;amp;nbsp;11.&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf = 1&amp;lt;/tt&amp;gt; bedeutet, dass der Variablen &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; vor dem ersten Schleifendurchlauf der Wert&amp;amp;nbsp;1 zugewiesen wird. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf &amp;lt;= 10&amp;lt;/tt&amp;gt; ist die Schleifenbedingung; ist sie nicht erfüllt, wird die Schleife beendet. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf += 2&amp;lt;/tt&amp;gt; bedeutet, dass &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nach jedem Durchlauf um&amp;amp;nbsp;2 erhöht wird.&lt;br /&gt;
&lt;br /&gt;
===continue-Anweisung===&lt;br /&gt;
Innerhalb einer Schleife darf die &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die nachfolgenden Anweisungen übersprungen werden und mit dem nächsten Schleifendurchlauf fortgesetzt wird &amp;amp;ndash; vorausgesetzt die Schleifenbedingung ist noch erfüllt. Ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; etc. stehen, wenn dieses innerhalb einer Schleife steht.&lt;br /&gt;
&lt;br /&gt;
==break-Anweisung==&lt;br /&gt;
Innerhalb einer Schleife oder eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; darf die &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die Schleifen-/Switch-Anweisung sofort verlassen wird und das Programm dahinter weiter macht. Bei mehrfach geschachtelten Schleifen wird nur die innere verlassen. Ein &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; stehen, wenn dieses innerhalb einer Schleife/Switch-Anweisung steht.&lt;br /&gt;
&lt;br /&gt;
==goto-Anweisung==&lt;br /&gt;
&lt;br /&gt;
Innerhalb ein und derselben Funktion kann mit &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; an eine andere Stelle gesprungen werden. Dazu gibt man hinter dem &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einen Bezeichner an, der dadurch als Label fungiert:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 goto {{Bezeichner}};&lt;br /&gt;
Die Bezeichner selbst steht irgendwo in der Funktion und wird dadurch zur Sprungmarke (Label), daß er von einem Doppelpunkt (und mindestens einer C-Anweisung, die auch leer sein darf) gefolgt wird.&lt;br /&gt;
&lt;br /&gt;
Das Beispiel durchsucht das 2-dimensionale &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array &amp;lt;tt&amp;gt;feld&amp;lt;/tt&amp;gt; mit den &amp;lt;tt&amp;gt;SIZE_X &amp;amp;times; SIZE_Y&amp;lt;/tt&amp;gt; Werten nach dem Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;. Wird er gefunden, dann wird die 2-fach geschachtelte Suchschleife verlassen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int x, y;&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y; y++)&lt;br /&gt;
       if (feld[x][y] == 0)&lt;br /&gt;
          goto done;&lt;br /&gt;
 {{Label|done:}};&lt;br /&gt;
&lt;br /&gt;
Der folgende Code hat die gleiche Funktion, arbeitet jedoch ohne &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int x, y;&lt;br /&gt;
 int found = 0; {{comment|FALSE}}&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X &amp;amp;&amp;amp; !found; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y &amp;amp;&amp;amp; !found; y++)&lt;br /&gt;
       found = (0 == feld[x][y]);&lt;br /&gt;
Der Nachteil der &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-losen Variante ist, daß man eine Variable, die merkt, ob das Suchziel gefunden wurde, mitschleppen und in ''jedem'' Schleifendurchlauf abtesten muss. Dies bedeutet einen höheren Programmier- und Laufzeitaufwand und ist nicht so klar formuliert wie das &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-Beispiel.&lt;br /&gt;
&lt;br /&gt;
Gleichwohl sei angemerkt, daß die Verwendung von &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einem gewissen Dogmatismus unterliegt, der sich wie folgt subsummieren liesse:&lt;br /&gt;
:''goto ist böse und sollte keinesfalls verwendet werden! Wer es dennoch tut, offenbart dadurch seinen schlechten Geschmach sowie mangelhafte C-Kenntnis.'' &amp;lt;div align=&amp;quot;right&amp;quot;&amp;gt;http://www.roboternetz.de/phpBB2/images/smiles/icon_wink.gif&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Funktionen=&lt;br /&gt;
Stellen Dir vor, Du hast eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben &amp;amp;ndash; was Dich Zeit beim Erstellen des Programms und Speicherplatz im ausführbaren Programm kostet &amp;amp;ndash; kannst Du den Code-Abschnitt in eine Funktion schreiben und diese von jeder Stelle des Programms aus verwenden. Die Hauptgründe, um Funktionen zu verwenden, sind:&lt;br /&gt;
;Wiederverwendung von Code: Mehrfach verwendete Codestücke müssen nicht mehrfach implementiert werden. Oft unterscheiden sich die Codesequenzen nur in Kleinigkeiten, die man der Funktion über Parameter mitteilen kann.&lt;br /&gt;
;Übersichtlichkeit: Ein gut gegliedertes C-Programm implementiert klar umrissene Aufgaben in einer Funktion, auch wenn diese Funktion nur einmal im Code aufgerufen wird! Dadurch bleibt der Code um die Aufrufstelle besser verständlich, und man kann auf verschiedenen &amp;quot;Ebenen&amp;quot; denken. Eine Funktion wie &amp;quot;Datei öffnen&amp;quot; kann recht komplex sein. Auf höherer Ebene interessieren die Innereien nicht mehr, man möchte sich um andere Dinge kümmern und will den Code an der Stelle garnicht sehen...&lt;br /&gt;
;Rekursive Funktionen: Eine Funktion kann sich auch selbst aufrufen. In dem Falle nennt man die Funktion ''rekursiv''. Zwar lässt sich das, was eine rekursive Funktion tut, auch mit anderen Mitteln formulieren, die keine rekursiven Funktionen brauchen, aber oft ist der rekursive Weg knackiger und klarer formulierbar als eine nicht-rekursiven Ansatz, auch wenn es etwas mehr Resourcen verbraucht.&lt;br /&gt;
;Modulare Programmierung: Funktionen können anhand ihres Aufgabenbereichs auf verschiedene C-Quellen &amp;amp;ndash; sogenannte ''Module'' &amp;amp;ndash; verteilt werden. Funktionen, die etwas mit dem USB-Bus anstellen, werden in einem anderen Modul sein als mathematische Funktionen. Dies erhöht die Übersichtlichkeit und vereinfacht die Entwicklung im Team.&lt;br /&gt;
;Bibliotheken: Standard-Funktionen wie das hier oft auftauchende &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; sind in Bibliotheken gespeichert. Wenn das eigene Programm übersetzt wird, dann müssen nicht mehr alle Standard-Funktionen übersetzt werden, sondern werden nur noch aus der Bibliothek gelesen und ihr Code zum Programm dazugelinkt. Die Bibliotheks-Funktionen wurden schon zu einem früheren Zeitpunkt compiliert und liegen in dieser compilerten Form in der Bibliothek. Das spart mächtig Entwicklungszeit. Man kann auch selbst solche Bibliotheken erstellen und in diversen Projekten wiederverwenden.&lt;br /&gt;
;Generische Programmierung: In C ist es möglich, einer Funktion eine andere Funktion zu übergeben. (Damit ist nicht gemeint, ihr deren ''Rückgabewert'' zu übergeben (was auch ginge), sondern ''die Funktion selbst'' wird als Parameter übergeben und kann aufgerufen werden.) Ein typisches Beispiel dafür sind Sortieralgorithmen. Einem Sortieralgorithmus kann es egal sein, ''was'' er sortiert. Er muss lediglich wissen, ''wie'' er das Zeug zu sortieren hat: aufsteigend, absteigend, als Zahl, in lexikographischer Ordnung, nach der Quersumme, Körper nach Oberfläche, Durchmesser, Gewicht oder Volumen... Diese Vergleichsfunktion, die für zwei Objekte entscheidet, welches davon &amp;quot;kleiner&amp;quot; ist, kann man dem Sortierer übergeben. Will er zwei Werte vergleichen, dann muss er nur die Vergleichsfunktion aufrufen, ohne zu wissen, was diese tut. Damit kann der Sortieralgorithmus unanhängig von den Objekten gehalten werden, mit denen er hantieren soll.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Definition==&lt;br /&gt;
&lt;br /&gt;
In der ''Definition'' der Funktion wird gesagt, welche Werte sie liefern kann, wie sie heisst (Bezeichner) und wieviele und welche Parameter sie hat. Danach folgt ihre Implementierung:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}} ({{Parameterliste}})&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 &lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
Für Funktionen, die keinen Wert zurückliefern, gibt es den speziellen Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der besagt, daß die Funktion nichts zurückgibt. Die einfachste denkbare Funktion ist eine solch void-Funktion. Sie bekommt keine Parameter, gibt nicht zurück und ihr Body ist leer:&lt;br /&gt;
 void dummy()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==return-Anweisung==&lt;br /&gt;
An jeder Stelle des Programmflusses einer Funktion kann diese mit &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; beendet werden.&lt;br /&gt;
&lt;br /&gt;
'''bei void-Funktionen:'''&lt;br /&gt;
 return;&lt;br /&gt;
'''Funktionen mit Rückgabe-Wert:'''&lt;br /&gt;
 return {{Ausdruck|}};&lt;br /&gt;
Die zweite Variante gibt an, welcher Wert zurückgegeben wird.&lt;br /&gt;
 int main (int argc, char * argv[])&lt;br /&gt;
 {&lt;br /&gt;
    if (argc &amp;lt; 2)&lt;br /&gt;
       return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
Falls die letzte Anweisung einer void-Funktion ein &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; ist, kann es auch weggelassen werden wie oben bei der Funktion &amp;lt;tt&amp;gt;dummy&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Aufruf==&lt;br /&gt;
Um die Funktion aufzurufen gibt man ihren Namen an, gefolgt von den durch Komma getrennten Argumenten in runden Klammern wie im Beispiel unten das&lt;br /&gt;
 quadrat (5) &lt;br /&gt;
Da &amp;lt;tt&amp;gt;quadrat&amp;lt;/tt&amp;gt; einen Wert liefert, kann man damit weiter rechnen wie mit einem normalen Ausdruck:&lt;br /&gt;
 if (quadrat (a) + quadrat (b) == quadrat (c))&lt;br /&gt;
    c = quadrat (quadrat (a)); {{comment|c &amp;amp;#61; a hoch 4}}&lt;br /&gt;
&lt;br /&gt;
;Ein Hinweis am Rande: &lt;br /&gt;
Der Name einer Funktion ohne die beiden runden Klammern ist der Pointer/Zeiger auf ihren Anfang.&lt;br /&gt;
Damit kann ein Funktionsname überall dort verwendet werden, wo Pointer/Zeiger &lt;br /&gt;
zulässig sind. Insbesondere kann er als Argument einer weiteren Funktion dienen. &lt;br /&gt;
&lt;br /&gt;
'''Quelle:'''&lt;br /&gt;
W. Alex, Einführung in C/C++&lt;br /&gt;
&lt;br /&gt;
==Rekursive Funktionen==&lt;br /&gt;
Eine Funktion die sich selbst &amp;amp;ndash; möglicheweise auch über andere Zwischenfunktionen &amp;amp;ndash; wieder selbst aufruft, wird als ''rekursive Funktion'' bezeichnet. In der Definition ist nichts besonderes zu beachten. Ist die Verschachtelungstiefe im laufenden Programm zu tief, dann gibt das natürlich Probleme, aber das gilt bei tief verschachtelten 'normalen' Funktionen abenso...&lt;br /&gt;
&lt;br /&gt;
Das Beispiel berechnet den Größten Gemeinsamen Teiler zweier Zahlen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int ggT (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
     if (0 == a)&lt;br /&gt;
        return b;&lt;br /&gt;
 &lt;br /&gt;
    return ggT (b % a, a);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Ein komplettes kleines Programm:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int quadrat (int param1)&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  zahl = param1 * param1;&lt;br /&gt;
  return zahl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl, ergebnis;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Bitte Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = quadrat (zahl);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, zahl, ergebnis);&lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, 5, quadrat (5));&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur ausserhalb von Blöcken. Geschachtelte Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen beim Aufruf die Klammern angeben werden:&lt;br /&gt;
 dummy();&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Prototypen==&lt;br /&gt;
Wie oben erwähnt, kann ein Unterprogramm an jeder beliebigen Stelle im Programm stehen. Damit ist jedoch eine Bedingung verknüpft: Das Unterprogramm muß in der Datei oberhalb des ersten Aufrufes definiert worden sein. Wenn Sie ein Unterprogramm in Zeile 10 zum ersten mal aufrufen, müssen Sie die Deklaration davor erledigt haben. Verstanden?&lt;br /&gt;
Um dies zu erreichen, gibt es zwei Möglichkeiten: &lt;br /&gt;
&lt;br /&gt;
Entweder Sie schreiben alle Unterprogramme vor &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; in die Datei. Dies muß jedoch wiederum so geschehen, dass Funktionen zum Zeitpunkt ihres Aufrufes bereits bekannt sind! &lt;br /&gt;
Wo dies nicht möglich ist (z.B. sich gegenseitig aufrufende Unterprogramme), oder wenn Sie das stört, müssen Sie Prototypen verwenden. &lt;br /&gt;
Wie definiert man nun Prototypen? Sie kopieren einfach die erste Zeile des Unterprogrammes (z.B. &amp;quot;&amp;lt;tt&amp;gt;void ausgeben (int zahl)&amp;lt;/tt&amp;gt;&amp;quot;), fügen einen Strichpunkt&amp;amp;nbsp;&amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;an und fügen es an einer geeigneten Stelle ein (so, dass alle Aufrufe später in der Datei kommen). &lt;br /&gt;
Solche Definitionen stehen gewöhnlich am Anfang der Quelldatei oder in einer Header-Datei, die eingebunden wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl);  /* Der Prototyp */&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
   ausgeben (12);&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl)   /* Die eigentliche Prozedur */&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Ausgabe: %d\n&amp;quot;, zahl);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Parameterübergabe==&lt;br /&gt;
&lt;br /&gt;
Alle Werte, die an Prozeduren und Funktionen übergeben werden, werden grundsätzlich '''kopiert'''.&lt;br /&gt;
Das hat folgende Auswirkungen:&lt;br /&gt;
&lt;br /&gt;
# Änderungen an einem Parameter in einer Funktion erscheinen ''nicht'' beim Aufrufer!&lt;br /&gt;
# Möchte man, dass eine Funktion einen Wert trotzdem dauerhaft ändern soll, so muss die Adresse des Wertes via [[#Zeiger|Zeiger]] übergeben werden.&lt;br /&gt;
# Werden [[#Strukturen|Strukturen]] übergeben, so wird von ihnen eine Kopie erstellt, was bei großen Strukturen viel Zeit und Arbeitsspeicher kostet. Deshalb wird häufig nur die Adresse von Strukturen übergeben, da die Adresse viel schneller und platzsparender als die Struktur selbst kopiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele:'''&lt;br /&gt;
 void erhoehe (int x)&lt;br /&gt;
 {&lt;br /&gt;
    x = x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe(a);&lt;br /&gt;
    {{comment|a ist immer noch 0}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Beim Aufruf von &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; wird eine Kopie des Wertes von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; (im Beispiel also 0) erstellt und der Prozedur als Parameter &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; übergeben. Weil dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat dies keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|erhoehe den Wert an der Adresse x um eins}}&lt;br /&gt;
    *x = *x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe (&amp;amp;a);&lt;br /&gt;
    {{comment|a ist jetzt 1}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Jetzt wird im Hauptprogramm mittels [[#Adress-Operator und Dereferenzierung|Adress-Operator]] &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; die Speicheradresse von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; bestimmt. Dann wird eine ''Kopie der Adresse'' an das Unterprogramm &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; übergeben. Jetzt kennt das Unterprogramm die&lt;br /&gt;
Adresse des Originals &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und kann direkt mit dem Inhalts-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&lt;br /&gt;
'''Besonderheit bei Feldern'''&lt;br /&gt;
&lt;br /&gt;
Bei der Übergabe von [[#Felder|Feldern]] gibt es eine Besonderheit. Schreibt man nämlich den Namen eines Feldes, so ist das nichts anderes als die '''Speicheradresse des ersten Elements'''.&lt;br /&gt;
Bei der Übergabe eines Feldes wird also eine Kopie der Startadresse übergeben. Somit kann das Unterprogramm auf den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 void erhoehe (int x[])&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
   int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
   erhoehe (a);&lt;br /&gt;
   {{comment|a hat jetzt folgenden Inhalte: 11, 23, 35}}&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Dass die Übergabe einer Adresse erfolgt, sieht man an folgendem Beispiel, das von der Funktionsweise '''absolut identisch''' mit dem vorhergehenden ist:&lt;br /&gt;
&lt;br /&gt;
 {{comment|Bei Parametern gibt es keinen Unterschied zwischen Zeiger und Feld}}&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
    int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
    erhoehe (a);&lt;br /&gt;
 &lt;br /&gt;
    {{comment|a hat jetzt folgenden Inhalt: 11, 23, 35}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
Die Länge des Feldes wird nicht automatisch übergeben. Dafür ist ggf. ein zusätzlicher Parameter notwendig.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Variable Argumentanzahl==&lt;br /&gt;
== Funktionen indirekt aufrufen ==&lt;br /&gt;
Siehe [[#Zeiger auf Funktionen|Zeiger auf Funktionen]]&lt;br /&gt;
&lt;br /&gt;
=Zeiger II=&lt;br /&gt;
&lt;br /&gt;
Zeiger haben wir bereits weiter oben kennen gelernt. Zeiger sind ein zentrales Konzept in C und sollen hier etwas eingehender behandelt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger-Arithmetik==&lt;br /&gt;
In C kann man den Wert eines Zeigers verändern. Betrachten wir dazu die Funktion &amp;lt;tt&amp;gt;suche_0&amp;lt;/tt&amp;gt;, die einen Zeiger auf einen &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; erhält. Die Funktion soll ab der gegebenen Adresse nach dem ersten long-Wert suchen, der 0 ist, und dessen Adresse zurückgeben:&lt;br /&gt;
 long * suche_0 (long * addr)&lt;br /&gt;
 {&lt;br /&gt;
    while (*addr != 0)&lt;br /&gt;
       addr = addr + 1;&lt;br /&gt;
 &lt;br /&gt;
    return addr;&lt;br /&gt;
 }&lt;br /&gt;
In der Bedingung der while-Schleife wird der Inhalt an der Speicherstelle &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf 0 getestet. Ist der Wert 0, dann wird die Schleife beendet und die Adresse zurückgeliefert. Ist der Wert ungleich 0, dann wird &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf den nächste long gesetzt, &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; also um 4 Bytes weitergezählt. &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ist ja ein Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, und ein &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; ist 4 Bytes lang.&lt;br /&gt;
&lt;br /&gt;
Die Bedeutung von&lt;br /&gt;
 address + n&lt;br /&gt;
ist also, die Adresse um das &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;-fache der Größe des Typs, auf den &amp;lt;tt&amp;gt;address&amp;lt;/tt&amp;gt; zeigt, zu erhöhen. Dabei ist &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; eine ganze Zahl und darf auch negativ sein.&lt;br /&gt;
&lt;br /&gt;
Hier noch ein Beispiel einer Funktion, die nach einer Person mit einer bestimmten ID sucht (für die Definition von &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; siehe [[#Strukturen|Strukturen]]). Der Parameter &amp;lt;tt&amp;gt;person&amp;lt;/tt&amp;gt; ist dabei ein Array von Strukturen. Eine Person mit der gesuchten ID muss existieren, ansonsten hat die Suchfunktion kein definiertes Verhalten.&lt;br /&gt;
 {{comment|Sucht nach einer Person mit der ID person_id}}&lt;br /&gt;
 struct Person * &lt;br /&gt;
 suche_person_id (struct Person * person, int person_id)&lt;br /&gt;
 {&lt;br /&gt;
    while (person-&amp;gt;id != person_id)&lt;br /&gt;
       person++;&lt;br /&gt;
 &lt;br /&gt;
    return person;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:1em; padding:1em; border:solid 2px #FF0040;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- Vorlage:FarbigerRahmen funzt hier net --&amp;gt;&lt;br /&gt;
Beachte, daß es nicht sinnvoll ist, zwei Zeiger zu addieren oder zu multiplizieren. Ausserdem ist das &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt; der Zeiger-Arithmetik nicht kommutativ. Eine Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, der an Adresse 1 im Speicher zeigt, wird man schreiben als&lt;br /&gt;
 (long *) 1&lt;br /&gt;
Addiert man darauf eine ganze Zahl, dann haben die entstehenden Ausdrücke unterschiedliche Werte:&lt;br /&gt;
 (long *) 1 + 2    {{comment|zeigt zu Adresse 9}}&lt;br /&gt;
 (long *) 2 + 1    {{comment|zeigt zu Adresse 6}}&lt;br /&gt;
 (long *) (1 + 2)  {{comment|zeigt zu Adresse 3}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==void-Pointer==&lt;br /&gt;
Eine besondere Art von Zeiger ist der void-Pointer&lt;br /&gt;
 void * addr;&lt;br /&gt;
Ein void-Pointer ist ein &amp;quot;Zeiger auf irgendwas&amp;quot;, dementsprechend kann er nicht dereferenziert werden, Anwenden von &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf einen solchen Zeiger gibt also einen Fehler. Ausserdem ist es nicht möglich, mit einem void-Pointer Zeigerarithmetik zu machen, weil er nicht auf eine definierte Art von Objekt zeigt. Der Vorteil eines void-Pointers ist, daß er jede Art von Zeiger aufnehmen kann.&lt;br /&gt;
&lt;br /&gt;
Dazu betrachten wir die Funktion &amp;lt;tt&amp;gt;send_buf&amp;lt;/tt&amp;gt;, die eine Adresse erhält und ab dieser Adresse &amp;lt;tt&amp;gt;num&amp;lt;/tt&amp;gt; Bytes versenden soll. Wir könnten die Funktion so schreiben:&lt;br /&gt;
 void send_buf (unsigned char * buf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   ...&lt;br /&gt;
Das ist jedoch hässlich, wenn wir damit etwas anderes verschicken wollen als &amp;lt;tt&amp;gt; unsigned char&amp;lt;/tt&amp;gt;, etwa eine Struktur wie &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; (vom Typ &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;):&lt;br /&gt;
 send_buf ((unsigned char*) &amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
Ohne den Cast der Adresse von &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; zu einem Zeiger auf &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt; bekommt man eine Warnung oder gar einen Compilerfehler.&lt;br /&gt;
Dieses Zeiger gecaste ist mühsam und hässlich, es muss bei jedem Aufruf der Funktion explizit hingeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Besser ist es, den ersten Parameter der Funktion als void-Pointer zu definieren und den Cast in der Funktion zu machen:&lt;br /&gt;
 void send_buf (void * vbuf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   unsigned char *buf = (unsigned char*) vbuf;&lt;br /&gt;
   ...&lt;br /&gt;
Durch den Cast in der Funktion kann auf den Inhalt des Zeigers zugegriffen werden. Man muss nur festlegen, ''wie'' man zugreifen will, nämlich als &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Der Aufruf kann jetzt ohne Pointer-Cast erfolgen: &lt;br /&gt;
 send_buf (&amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
&lt;br /&gt;
==Null-Pointer==&lt;br /&gt;
==Zeiger als Parameter==&lt;br /&gt;
Wenn Sie ein Unterprogramm aufrufen, können Sie diesem Parameter übergeben, aber keine Werte zurückgekommen (außer den Funktionswert bei Funktionen). Dies hat einen guten Grund: beim Aufruf werden nicht die aufgerufenen Parameter benutzt, sondern es werden deren Werte in neue Variablen kopiert. Diese Variablen werden am Ende des Unterprogrammes &amp;quot;zerstört&amp;quot;, ohne ihre Werte an die aufrufenden Parameter zu übergeben. Jede Veränderung eines Parameters hat daher keine Auswirkung auf den Parameter.&lt;br /&gt;
&lt;br /&gt;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der C-Compiler legt dann immer noch Kopien an. In dieser Kopie steht aber kein Wert, sondern die Adresse einer Varaiblen. Und auf diese können Sie dann zugreifen. Denken Sie nur an &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; &amp;amp;ndash; da übergeben Sie ja auch die Adresse einer Variablen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void erhoehe (int *zeiger)&lt;br /&gt;
{&lt;br /&gt;
  *zeiger = 1 + *zeiger;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  erhoehe (&amp;amp;zahl);&lt;br /&gt;
  printf (&amp;quot;\nDie erhoehte Zahl lautet: %d\n&amp;quot;, zahl);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Zeiger auf Funktionen==&lt;br /&gt;
&lt;br /&gt;
Stell dir vor, du willst einen Sortieralgorithmus wie Bubble-Sort oder Quick-Sort oder wie sie alle heissen implementieren. Für den Sortieralgorithmus ist eigentlich egal, ''was'' er zu sortieren hat. Ihm ist es egal, ob er Zahlen aufwärts sortieren soll oder Strings in lexikographischer Reihenfolge, ob Objekte nach Größe oder Gewicht, Personen nach Alter oder Adressen nach Postleitzahl. Das einzige, was der Algorithmus wissen muss, ist ''wie'' er zwei Objekte zu vergleichen hat und wann eines davon &amp;quot;kleiner&amp;quot; (im Sinne der Ordnung, nach der sortiert werden soll) ist. &lt;br /&gt;
&lt;br /&gt;
Eine einfache Sortierfunktion, die nur zwei Zahlen sortiert, könnte man also so schreiben: &lt;br /&gt;
 {{comment|Sortiert ein Array von 2 int-Zeigern nach den Inhalten &lt;br /&gt;
  * an den Zeiger-Adressen}}&lt;br /&gt;
 void sort2_a (int * p[])&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Inhalte vergleichen...}}&lt;br /&gt;
    if (*p[0] &amp;gt; *p[1])&lt;br /&gt;
    {&lt;br /&gt;
       {{comment|... und ggf. Dreieckstausch der 2 Zeiger}}&lt;br /&gt;
       int * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Die Funktion bekommt ein Array der Länge&amp;amp;nbsp;2. In diesem Array stehen Zeiger auf die zu sortierenden Zahlen. Ein Array mit Zeigern zu verwenden und nicht ein Array von &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; scheint recht umständlich, und das ist es hier auch. Aber stell dir vor, du willst Strukturen wie &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; sortieren. Das Tauschen zweier Strukturen würde bedeuten, ihre kompletten Inhalte umzukopieren! Das wäre sehr aufwändig. Viel einfacher ist das Kopieren, wenn nur die Adressen zu kopieren sind.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; könnte dann so aussehen:&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void sortiere (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|p[] enthält 2 int-Zeiger: die Adressen von a und b}}&lt;br /&gt;
    int * p[2];&lt;br /&gt;
    p[0] = &amp;amp;a; &lt;br /&gt;
    p[1] = &amp;amp;b; &lt;br /&gt;
 &lt;br /&gt;
    {{comment|Sortiere die Zeiger}} &lt;br /&gt;
    sort2_a (p);&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Sortiert: %d, %d\n&amp;quot;, *p[0], *p[1]);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Für den nächsten Schritt überlegen wir uns, daß das Array in &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; ebensogut void-Pointer enthalten kann. Die einzige Stelle, an der wir auf die endgültigen int-Objekte zugreifen, ist der Vergleich. Diesen Vergleich lagern wir in die Funktion &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; aus:&lt;br /&gt;
 {{comment|Bekommt zwei void-Pointer und vergleicht die Inhalte.&lt;br /&gt;
  * Liefert 0 bei Gleichheit,&lt;br /&gt;
  * -1 wenn der erste Wert kleiner ist als der zweite und&lt;br /&gt;
  * 1  wenn der erste Wert größer ist als der zweite}}&lt;br /&gt;
 int compare_int (void * p0, void * p1)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Um über die Zeiger zugreifen zu können müssen wir diese&lt;br /&gt;
     * erst zu int-Zeigern casten}}&lt;br /&gt;
    int a0 = * (int*) p0;&lt;br /&gt;
    int a1 = * (int*) p1;&lt;br /&gt;
 &lt;br /&gt;
    if (a0 &amp;gt; a1)  return  1;&lt;br /&gt;
    if (a0 &amp;lt; a1)  return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void sort2_b (void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare_int (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Ein Aufruf von &amp;lt;tt&amp;gt;sort2_b&amp;lt;/tt&amp;gt; sieht dann genauso aus wie ein Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt definieren wir uns den neuen Datentyp &amp;lt;tt&amp;gt;comparator_t&amp;lt;/tt&amp;gt;. Dieser ist ein Zeiger auf eine Funktion, die zwei void-Pointer erhält und einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; zurückliefert, also analog arbeitet zu &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; von oben. &lt;br /&gt;
&lt;br /&gt;
Unsere Sortierfunktion bekommt nun neben dem zu sortierenden Zeiger-Array auch eine Vergleichsfunktion &amp;lt;tt&amp;gt;compare&amp;lt;/tt&amp;gt; mitgeliefert, die sie aufruft, wenn sie zwei Objekte vergleichen will&lt;br /&gt;
 {{comment|comparator_t sind Zeiger auf Funktionen, die 2 void-Pointer&lt;br /&gt;
  * erhalten und einen int zurückliefern}}&lt;br /&gt;
 typedef int (*comparator_t) (void*, void*);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Der Sortierer bekommt einen Funktionszeiger auf den Vergleicher.&lt;br /&gt;
  * Der Aufruf vom compare geht so als wäre es eine &amp;quot;normale&amp;quot; Funktion&lt;br /&gt;
  * (ist es im Endeffekt ja auch)}}&lt;br /&gt;
 void sort2_c (comparator_t compare, void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Bei einem Aufruf von &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; muss man dann einen Komparator mit angeben. In einem Beispiel analog zu &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; von oben ist das:&lt;br /&gt;
 sort2_c (compare_int, p);&lt;br /&gt;
Um zwei Strings lexikographisch zu sortieren nehmen wie die Standard-Funktion &amp;lt;tt&amp;gt;strcmp&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void foo()&lt;br /&gt;
 {&lt;br /&gt;
    char * worte[] = { &amp;quot;Wort1&amp;quot;, &amp;quot;Wort2&amp;quot; };&lt;br /&gt;
 &lt;br /&gt;
    sort2_c ((comparator_t) strcmp, (void**) worte);&lt;br /&gt;
 }&lt;br /&gt;
Die Casts sind hier erforderlich. Alternativ könnte man &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; mit reinen void-Pointern versorgen und diese dann dort umcasten.&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
&lt;br /&gt;
Die Syntax zur Definition/Deklaration von Funktionszeigern ist etwas verzwackt. Zur Verdeutlichung ein paar Beispiele. Dabei legt das linke &amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt; jeweils den Return-Typ fest.&lt;br /&gt;
 {{comment|definiert einen neuen Funktionszeiger-Typ}}&lt;br /&gt;
 typedef {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert einen Funktionszeiger}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert ein Array von Funktionszeigern (mit Initializer)}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}[]) ({{type}}, {{type}}, ...) = { wert1, wert2, ... };&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer}}&lt;br /&gt;
 ({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer und ruft die Funktion auf}}&lt;br /&gt;
 (({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}) (arg1, arg2, ...);&lt;br /&gt;
&lt;br /&gt;
=Standard-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==String-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===strcpy===&lt;br /&gt;
Bei vielen Compilern können sie einem String nicht direkt einen Wert (Text) zuweisen. Dazu müssen Sie dann die Prozedur strcpy() benutzen. Diese erwartet als ersten Parameter den Namen einer String-Variablen (ohne eckige Klammern) und als zweiten Parameter den eines (anderen) Strings. Letzterer kann auch ein in doppelten Hochkommas (&amp;quot;) eingeschlossener Text sein. Die Funktion fügt am Ende automatisch ein 0-Zeichen ein. Um diese Funktion nutzen zu können, müssen Sie die Datei string.h includieren! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri1[21], eingabe[21];&lt;br /&gt;
&lt;br /&gt;
  strcpy (stri1, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Der 1. String: %s\n&amp;quot;, stri1);&lt;br /&gt;
  printf (&amp;quot;Bitte geben Sie maximal 20 Zeichen ein: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%s&amp;quot;, eingabe);&lt;br /&gt;
  strcpy (stri1, eingabe);&lt;br /&gt;
  printf (&amp;quot;\n%s = %s&amp;quot;, stri1, eingabe);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis:''' &lt;br /&gt;
Da ein String, wie jedes Feld, eigentlich ein Zeiger ist, dürfen Sie kein &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; bei &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; angeben!&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
Es werden zwei gleich große Strings definiert: &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;eingabe&amp;lt;/tt&amp;gt;, mit je 20 &amp;quot;nutzbaren&amp;quot; Zeichen. &lt;br /&gt;
In &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; wird die Zeichenkette &amp;lt;tt&amp;gt;&amp;quot;hallo&amp;quot;&amp;lt;/tt&amp;gt; hineinkopiert. Das 0-Zeichen am Ende wird automatisch angefügt. &lt;br /&gt;
Der String wird ausgegeben. Als neues &amp;quot;Sonderzeichen&amp;quot; kommt &amp;lt;tt&amp;gt;%s&amp;lt;/tt&amp;gt; ins Spiel. Es hat die gleiche Aufgabe wie &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt;, nur für Strings. &lt;br /&gt;
Sie werden gebeten, eine String einzugeben. &lt;br /&gt;
Dieser String wird danach in die Variable &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; kopiert. &lt;br /&gt;
Beide Strings, die ja nun die gleiche Zeichenkette enthalten, werden ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===strlen===&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;strlen&amp;lt;/tt&amp;gt;, die als Parameter eine String-Variable erwartet, liefert die Länge diese Strings zurück. Sie werden jetzt vermutlich sagen: &amp;quot;Das ist doch klar, wie lang der String ist. Ich habe es ja bei der Deklaratin angegeben&amp;quot;. Das stimmt schon, aber denken Sie noch einmal an die null-terminierten Strings. Das 0-Zeichen steht am Ende des Strings (am Ende der gültigen Zeichenfolge), aber nicht unbedingt am Ende des reservierten Speicherplatzes. Haben Sie eine Variable &amp;quot;char Variable[21];&amp;quot;, und ihr den Wert &amp;quot;hallo&amp;quot; zugewiesen, dann steht das null-Zeichen in Variable[5]. Der &amp;quot;gültige&amp;quot; String ist also 5 Zeichen (0-4) lang. Und genau das (5) würde strlen zurück liefern. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri[21];&lt;br /&gt;
  &lt;br /&gt;
  strcpy (stri, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
  printf (&amp;quot;Der String ist %d Zeichen lang&amp;quot;, strlen (stri));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird vor allem gebraucht, wenn Sie direkt auf den String zugreifen, mittels &amp;lt;tt&amp;gt;stri[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;stri[1]&amp;lt;/tt&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
==Ein- und Ausgabe-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===Bildschirm-Ausgabe===&lt;br /&gt;
Bisher war das Tutorial trotz aller Beispiele reine Theorie. Sie konnten zwar Programme schreiben, aber die Funktion nicht testen. Hier lernen Sie nun, wie Sie etwas am Bildschirm ausgeben.&lt;br /&gt;
&lt;br /&gt;
Die dazu notwendige Funktione heisst &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (das '&amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt;' ist kein Fehler!). Diese Anweisung gibt die ihr übergebenen Parameter auf das Standard-Ausgabegerät aus, in der Regel also auf den Bildschirm. Sie kann beliebig viele Parameter übernehmen. Es müssen jedoch Standard-Datentypen (z.B. &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;...) sein! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
    int zahl1 = 12;&lt;br /&gt;
    char zeichen1 = 'A';&lt;br /&gt;
    &lt;br /&gt;
    printf (&amp;quot;Das ist Text, und er wird als solcher ausgegeben. \n&amp;quot;);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zahl1' ist: %d \n&amp;quot;, zahl1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %c \n&amp;quot;, zeichen1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %d \n&amp;quot;, zeichen1);&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt Text aus. Das Zeichen am Ende (&amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;) bedeutet &amp;quot;New Line&amp;quot;, es bewegt den Cursor an den Anfang der nächsten Zeile. &lt;br /&gt;
&lt;br /&gt;
Der zweite &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt auch Text aus, am Ende befindet sich wieder das &amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;, um einen Zeilenvorschub zu erreichen. Das &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; wird vom Compiler durch den ersten Parameter ersetzt, der nach dem Text angegeben wird. In diesem Fall wird &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; also durch den Wert der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ersetzt. Das &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; im &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; bedeutet &amp;quot;Dezimalzahl&amp;quot;, der Computer gibt also eine ganze Zahl aus. &lt;br /&gt;
&lt;br /&gt;
In der dritten Ausgabe wird ein Zeichen ausgegeben. Diesmal bedeutet &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; &amp;quot;char&amp;quot; (Zeichen). Es wird also &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; durch ein &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt; ersetzt, denn die Variable &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; wird als Character interpretiert. &lt;br /&gt;
&lt;br /&gt;
Die letzte Ausgabe interpretiert den Inhalt von &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; als Zahl, und gibt dager den ASCII-Wert von &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, also 65 aus. Das ist ein typisches Beispiel für das mögliche unterschiedliche Interpretieren einer  Variablen!&lt;br /&gt;
&lt;br /&gt;
===Tastatur-Eingabe===&lt;br /&gt;
&lt;br /&gt;
Um ein &amp;quot;gscheites&amp;quot; Programm schreiben zu können, muß man wissen, wie der Benutzer über die Tastatur Befehle eingeben kann. Die dafür notwendigen Funktionen stelle ich in diesem Kapitel vor.&lt;br /&gt;
Die wichtigste Funktion ist &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt;. Er liest Daten von der Tastatur. Die Syntax entspricht derer von &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int  zahl1;&lt;br /&gt;
char zeichen1;&lt;br /&gt;
&lt;br /&gt;
printf (&amp;quot;Bitte geben Sie eine Zahl ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl1);&lt;br /&gt;
printf (&amp;quot;Geben Sie einen Zeichen ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%c&amp;quot;, &amp;amp;zeichen1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Programm gibt eine Eingabeaufforderung aus. Dann erwartet es vom Benutzer, daß er eine Zahl eingibt, die mit [ENTER] bestätigt wird. Dieser Wert wird in &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; abgespeichert. Danach erfolgt wiederum eine Aufforderung zur Eingabe, diesmal eines einzelnen Zeichens. Dieses kann man nun eingeben und ebenfalls mit [ENTER] bestätigen.&lt;br /&gt;
&lt;br /&gt;
Macht man keine dem Datentyp der erwarteten Variable entsprechende Eingabe, dann bricht das Programm mit einer Fehlermeldung ab (wenn man z.B. &amp;quot;1_T2&amp;quot; eingibt, wenn eine Zahl erwartet wird)!&lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; vor den Parametern ist notwendig. Warum, das erfahren Sie im Kapitel &amp;quot;Unterprogramme&amp;quot;. Für die Profis eine Kurz-Erklärung: Das Unterprogramm &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; bekommt zwar einen Wert übergeben, kann aber keinen zurückliefern (&amp;quot;call by value&amp;quot;). Daher wird kein Wert, sondern ein Zeiger auf eine Variable übergeben. Mit dem &amp;amp; Zeichen bekommen Sie die Adresse einer Variablen (&amp;quot;call by reference&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=Parameter von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;=&lt;br /&gt;
Das Unterprogramm &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; kann, wie jede andere Funktion, Parameter besitzen. Doch keine selbst gewählten, sondern nur bestimmte. Doch warum braucht main Parameter? Denken Sie einmal an alle Betriebssystembefehle:&lt;br /&gt;
&amp;lt;tt&amp;gt;dir *.exe &amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;copy *.* a:&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;ls -la &amp;lt;/tt&amp;gt;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen!&lt;br /&gt;
&lt;br /&gt;
=Kurzreferenz=&lt;br /&gt;
==Syntax-Bausteine==&lt;br /&gt;
&lt;br /&gt;
Die Erklärung des Aufbaus von C-Befehlen erfolgt neben einfachen Beispielen auch durch ihren prinzipellen Aufbau. In diesen Syntax-Beschreibungen finden sich immer wieder die gleichen Bausteine, die hier näher erklärt werden sollen. Falls Dir solch ein Syntax-Baustein begegnet, kannst Du ihn anklicken und kommst dann zu seiner Erläuterung. &lt;br /&gt;
&lt;br /&gt;
In den Beispielen selbst gehören auch die spitzen Klammern zu dem Baustein (was daran zu erkennen ist, daß auch die Klammern eingefärbt sind). Die Klammern dürfen in einem konkreten C-Programm daher nicht eingetippt werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bezeichner&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Bezeichner in C dienen dazu, Variablen zu identifizieren und ihnen sprechende Namen zu geben, um die Quelle lesbarer zu machen. Man braucht Bezeichner auch, um selbstdefinierte Datentypen zu benennen und zum Benennen von Struct- und Union-Komponenten sowie als Namen für Funktionen und Sprungmarken (Labels).&lt;br /&gt;
&lt;br /&gt;
Bezeichner dürfen aus den Kleinbuchstaben &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;z&amp;lt;/tt&amp;gt;, den Großbuchstaben &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;Z&amp;lt;/tt&amp;gt;, dem Unterstrich&amp;amp;nbsp;&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt; und den Ziffern &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;9&amp;lt;/tt&amp;gt; aufgebaut werden, wobei an erster Stelle jedoch keine Ziffer stehen darf.&lt;br /&gt;
&lt;br /&gt;
Es wird zwischen Groß- und Kleinschreibung unterschieden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Ausdruck in C ist ein Konstrukt, das einen Wert hat. Ob dieser Wert eine ganze Zahl ist, eine Kommazahl oder ein Zeiger, etc. ist dabei egal. Die einfachsten Ausdrücke sind Konstanten wie&lt;br /&gt;
 2&lt;br /&gt;
oder Variablen wie&lt;br /&gt;
 ein_zahl&lt;br /&gt;
Mehrere Ausdrücke können durch [[#Liste der Operatoren|Operatoren]] zu komplexeren Ausdrücken kombiniert werden, etwa&lt;br /&gt;
 eine_zahl + andere_zahl == 2&lt;br /&gt;
oder &lt;br /&gt;
 eine_zahl = 2&lt;br /&gt;
Letzterer hat den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; und den Nebeneffekt, daß er diesen Wert an &amp;lt;tt&amp;gt;eine_zahl&amp;lt;/tt&amp;gt; zuweist.&lt;br /&gt;
&lt;br /&gt;
Auch der Aufruf einer Funktion, die einen Rückgabewert liefert, ist ein Ausdruck:&lt;br /&gt;
 sin (1.2)&lt;br /&gt;
und kann zum Aufbau komplexerer Ausdrüche verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bedingung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Bedingung ist ein Ausdruck, bei der nur interessiert, ob dieser zu&amp;amp;nbsp;0 (unwahr) auswertet oder zu ungleich&amp;amp;nbsp;0 (wahr). Solche Ausdrücke findet man in if-Anweisungen, in Schleifenbedingungen und bedingten Zuweisungen&lt;br /&gt;
 (ein_wert &amp;lt; 2) || (ein_wert &amp;gt; 40)&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Lvalue ist ein Ausdruck, dem etwas zugewiesen werden kann. Der Name ''Lvalue'' kommt aus dem Englischen. Das ''L'' steht abkürzend für left. Ein Lvalue ist damit ein Ausdruck, der auf der linken Seite eine Zuweisung in C stehen darf. Das &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; in den folgenden Beispiel-Ausdrücken muss ein Lvalue sein:&lt;br /&gt;
 x = y-1&lt;br /&gt;
&lt;br /&gt;
 x++&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Konstante&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Konstante ist ein Ausdruck, dessen Wert dem Compiler bekannt ist. Beispiele für Konstanten sind etwa&lt;br /&gt;
 7&lt;br /&gt;
 'B'&lt;br /&gt;
 -13.98e12&lt;br /&gt;
 1+(2*3)&lt;br /&gt;
und die Werte von [[#Enum|Enum]]s. &lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; aus dem folgenden Codestück definiert jedoch keine Konstante in diesem Sinne&lt;br /&gt;
 const double Pi = 3.14159256;&lt;br /&gt;
denn in einem anderen Quellmodul könnte durch die Deklaration&lt;br /&gt;
 extern const double Pi;&lt;br /&gt;
das Symbol &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; bekannt sein, ohne daß sein Wert bekannt ist!&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Adresse&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Adresse ist ein Ausdruck, der einen Speicherort (physikalisch oder virtuell) halten kann. Adressen erhält man dadurch, daß man einem Bezeichner den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt;voranstellt, Adressen durch Arithmetik berechnet oder Zahlen zu Adressen castet. Folgende Ausdrücke sind Adressen (eine sinnvolle Deklaration der auftretenden Variablen vorausgesetzt)&lt;br /&gt;
 &amp;amp; eine_zahl&lt;br /&gt;
 &amp;amp; ein_array[10]&lt;br /&gt;
 &amp;amp; ein_struct&lt;br /&gt;
 &amp;amp; ein_struct.komponente&lt;br /&gt;
 (int *) 0x1234&lt;br /&gt;
 (int *) eine_zahl&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Deklaration&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Anweisungen sind gewissermassen die Atome (oder Moleküle?), aus denen ein C-Programm besteht. Jedes C-Programm ist eine Abfolge von Deklarationen und Anweisungen. Einfache Anweisungen erhält man, in dem man einen Ausdruck nimmt und einen Strichpunkt dahinter schreibt:&lt;br /&gt;
 {{Ausdruck|}};&lt;br /&gt;
wie in&lt;br /&gt;
 x = x+1;&lt;br /&gt;
&lt;br /&gt;
Andere Anweisungen sind die unten aufgeführten Schleifen und die if- sowie die switch-Anweisung.&lt;br /&gt;
&lt;br /&gt;
Mehrere Deklarationen und Anweisungen können zu einem Block zusammengefasst werden. Dieser Block stellt dann wieder eine einzelne Anweisung dar und kann genau so gehandhabt werden!&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
In diesem Sinne ist auch z.B. die Syntax der if-Anweisung zu verstehen&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
besagt, daß der abhängig ausgeführte Code eine einzelne Anweisung sein darf oder eben ein kompletter Block oder die Verschachtelung mehrerer Blöcke etc.&lt;br /&gt;
&lt;br /&gt;
Eine Anweisung kann auch &amp;quot;leer&amp;quot; sein, also nichts tun. Diese Anweisungen sind der leere Block&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
und der Strichpunkt&lt;br /&gt;
 ;&lt;br /&gt;
die man gelegentlich in Schleifen findet:&lt;br /&gt;
 while (!timeout())&lt;br /&gt;
    {}&lt;br /&gt;
oder hinter Sprungmarken, die sonst direkt vor einer schliessenden Blockklammer stünden:&lt;br /&gt;
 {&lt;br /&gt;
    ...&lt;br /&gt;
    goto ein_label;&lt;br /&gt;
    ...&lt;br /&gt;
    {{Label|ein_label}}:;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Nicht jede Anweisung ist an jeder Stelle eines C-Programms erlaubt, so darf ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; nut innerhalb einer Schleife stehen. Gleiches gilt für &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;, das aber auch innerhalb eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; vorkommen darf.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Dies steht für einen Datentyp. Es kann ein elementarer Typ sein wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;, ein Zeiger darauf wie &amp;lt;tt&amp;gt;char*&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;void*&amp;lt;/tt&amp;gt;, und auch Qualifier enthalten wie das &amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt; im Typ &amp;lt;tt&amp;gt;unsigned long long&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Zu den Typen gehören auch zusammengesetzte Datentypen wie Strukturen und Unions, mit &amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt; selbst definierte Typen und natürlich Zeiger darauf, wie aus dem Abschnitt [[#Datentypen|Datentypen]]:&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person *&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;data32_t&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;&lt;br /&gt;
und Zeiger auf Funktionen.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Parameterliste&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
Die Parameterliste bei einer Funktionsdefinition gibt an, wieviel Übergabeparameter sie bekommt, wie diese heissen und welchen Typs diese sind. Der prinzipielle Aufbau ist&lt;br /&gt;
 {{Type}} {{Bezeichner}}, {{Type}} {{Bezeichner}}, ...&lt;br /&gt;
Falls die Funktion keine Parameter hat, dann ist die Parameterliste leer.&lt;br /&gt;
&lt;br /&gt;
Hier als Beispiel die zweiparametrige Funktion &amp;lt;tt&amp;gt;produkt&amp;lt;/tt&amp;gt;. Der erste Parameter heisst&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und ist ein &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;. Der zweite namens&amp;amp;nbsp;&amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; ist vom Typ &amp;quot;Zeiger auf double&amp;quot;, der Inhalt &amp;lt;tt&amp;gt;*b&amp;lt;/tt&amp;gt; ist also auch ein double.&lt;br /&gt;
&lt;br /&gt;
'''Definition der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b)&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
In älteren C-Quellen findet man noch eine andere Syntax für die Deklaration der Parameter, die aber heute praktisch nicht mehr verwendet wird:&lt;br /&gt;
'''alte Definition der Funktion:'''&lt;br /&gt;
 double produkt (a, b)&lt;br /&gt;
 double a, *b;&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Um die Funktion bekannt zu machen, werdendet man eine Deklaration bzw. den Prototypen, der dem Compiler nur mitteilt, welche Parameter die Funktion bekommt und was sie zurückliefert. Für den Aufruf der Funktion muss der Compiler nur diesen Prototyp kennen, ''was'' die Funktion im Endeffekt macht und wie sie implementiert wurde ist egal, sie wird als BlackBox angesehen.&lt;br /&gt;
&lt;br /&gt;
'''Prototyp der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b);&lt;br /&gt;
Hier dürfen die Bezeichner auch fehlen:&lt;br /&gt;
 double produkt (double, double*);&lt;br /&gt;
&lt;br /&gt;
==if==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==if-else==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==for==&lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Eine for-Schleife entspricht folgendem Konstrukt. Dabei sind die drei Ausdrücke optional. Fehlt die Bedingung, dann wird diese als &amp;quot;wahr&amp;quot; angenommen. Die beiden anderen Ausdrücke wird man als Ausdrücke mit Nebeneffekt wählen wie z.B. &amp;lt;tt&amp;gt;x=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;x=x-2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
 {&lt;br /&gt;
    {{Ausdruck|1}};&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_loop}}:&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
    else&lt;br /&gt;
       goto _break;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_continue}}:&lt;br /&gt;
    {{Ausdruck|2}};&lt;br /&gt;
    goto _loop;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_break}}:;&lt;br /&gt;
 }&lt;br /&gt;
Die Labels &amp;lt;tt&amp;gt;_break&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_continue&amp;lt;/tt&amp;gt; entsprechen den Sprungzielen einer &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Anweisung innerhalb von &amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==do-while==&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while  ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
==while==&lt;br /&gt;
 while  ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==switch==&lt;br /&gt;
 switch  ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    ...&lt;br /&gt;
  &lt;br /&gt;
    default:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#break-Anweisung|&amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Konstanten|&amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#continue-Anweisung|&amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#do-while-Schleife|&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Enum|&amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#for-Schleife|&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#goto-Anweisung|&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#return-Anweisung|&amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Liste der Operatoren|sizeof]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Strukturen|&amp;lt;tt&amp;gt;struct&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Eigene Datentypen|&amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Unions|&amp;lt;tt&amp;gt;union&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#while-Schleife|&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund2}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Arithmetische Operatoren&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Dies sind die &amp;quot;normalen&amp;quot; arithmetischen Operationen, wie man sie aus der Schule kennt. Man kann damit und allen anderen Operatoren auch komplexere Ausdrücke aufbauen. Die Prioritäten sind so, wie man sie kennt, also &amp;quot;Punktrechnung vor Strichrechnung&amp;quot;. Will man dies ändern, dann mit den runden Klammern:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;1+2*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 7&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(1+2)*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 9&amp;lt;br/&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}}&amp;amp;nbsp;+&amp;amp;nbsp;{{Ausdruck|}}&amp;lt;/tt&amp;gt; || Addition&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} - {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Subtraktion&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} * {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Multiplikation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} / {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Division&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} % {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Rest der Division (modulo)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;- {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Vorzeichenumkehr, Zweier-Komplement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Logische Operatoren und Vergleiche&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die logischen und die vergleichenden Operatoren liefern als Ergebnis den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (wahr) oder einen Wert ungleich&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (falsch, um genau zu sein den Wert &amp;lt;tt&amp;gt;!0&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Man kann das Ergebnis zwar einer Variablen zuweisen, in aller Regel wird man solche Ausdrücke jedoch in Bedingungen zu &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder in Abbruch-Bedingungen von Schleifen finden.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;&amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches AND: beides wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124;&amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches OR: mind. eines ist wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;! {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches NOT (0 &amp;amp;harr; ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} == {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} != {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist nicht gleich&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bitweise Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~ {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise NOT (Einser-Komplement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise AND&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise ODER&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} ^ {{Ausdruck|}}&amp;lt;/tt&amp;gt; ||bitweise XOR&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Shift-Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;lt;&amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Bits nach links schieben&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;gt;&amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Schieben nach rechts schieben&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Typen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Ein Cast in C kann dazu verwendet werden, den Typ eines Ausdruckes zu ändern oder den Ausdruck mit einer bestimmten Genauigkeit zu berechnen. Wird z.B. eine Berechnung standardmässig in 16 Bit ausgeführt, dann kann man mit einem Cast &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(long) &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
ausdrücken, daß die Berechnung in 32 Bit erfolgen soll. Des weiteren kann man Zeiger und ganze Zahlen und Gleitkommazahlen ineinander umwandeln.&lt;br /&gt;
&lt;br /&gt;
Casts können ''nicht'' dazu verwendet werden, um z.B. eine Zahl in einen String zu konvertieren, der diese Zahl darstellt! Dafür gibt es spezielle Funktionen wie &amp;lt;tt&amp;gt;itoa&amp;lt;/tt&amp;gt;!&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Type}}) {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Cast, Typwandlung&lt;br /&gt;
|-&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;| &amp;lt;tt&amp;gt;sizeof ({{Type}})&amp;lt;/tt&amp;gt; || Eine Konstante, deren Wert die Größe (in Bytes) des Typs ist. &amp;lt;tt&amp;gt;sizeof&amp;lt;/tt&amp;gt; ist auch auf Objekte anwendbar wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, Arrays bekannter Größe, Strukturen und Unions,  Array-, Struktur- und Union-Komponenten, Pointer, etc. Beispiel:&amp;lt;br/&amp;gt;&lt;br /&gt;
 int i, sum=0, array[] = { 1, -13, 4, 0, sizeof (int*) };&lt;br /&gt;
 &lt;br /&gt;
 for (i=0; i&amp;lt; sizeof (array) / sizeof (array[0]); i++)&lt;br /&gt;
    sum += array[i];&lt;br /&gt;
Alle Elemente des Arrays werden aufaddiert, ohne daß deren Anzahl explizit in der Schleife genannt ist.&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zeiger und Adressen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;* {{Adresse}}&amp;lt;/tt&amp;gt; || der Inhalt an Adresse&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp; {{Lvalue}}&amp;lt;/tt&amp;gt; || Adresse von&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Strukturen, Unions, Arrays&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Struct&amp;gt;}}.{{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Zeiger-auf-Struct&amp;gt;}} -&amp;gt; {{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union, deren Adresse man hat&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Adresse}}&amp;amp;#91;{{Ausdruck|}}&amp;amp;#93;&amp;lt;/tt&amp;gt; || Array-Element&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bedingte Auswertung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Bedingung}}) ? {{Ausdruck|}} : {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Auswahl des Wertes abhängig von der Bedingung&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zuweisung und Operatoren mit Nebeneffekt&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die Unterschiede der post- und pre-Varianten der Increment/Decrement kommen in Konstrukten wie &amp;lt;tt&amp;gt;x = *p++&amp;lt;/tt&amp;gt; zum tragen:&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *p++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; p = p+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *++p;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; p = p+1; x = *p;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = (*p)++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; *p = (*p)+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = ++(*p);&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; *p = (*p)+1; x = *p;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} = {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Zuweisung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++ {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-- {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Decrement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ++&amp;lt;/tt&amp;gt; || Post-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} --&amp;lt;/tt&amp;gt; || Post-Decrement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Kurzschreibweisen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Für ganz Faule gibt es anstatt&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a = a @ b&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
für viele Operatoren (hier dargestellt durch ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;@&amp;lt;/tt&amp;gt;) die abkürzende Schreibweise&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a @= b&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} += {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} -= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} *= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} /= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} %= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ^= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;lt;&amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;gt;&amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Autoren'''&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
* Kernighan und Ritchie - Buch&lt;br /&gt;
* Christian Wirth , C Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://wwwuser.gwdg.de/~kboehm/ebook/inhalt.html C-Programmieren unter Linux]&lt;br /&gt;
* [http://www.gdv.uni-hannover.de/documentation.php Skripte zum Selbststudium: C, C++, Java, etc]&lt;br /&gt;
* [http://info.baeumle.com/ansic.html Einführung in ANSI-C]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Quellcode C|!]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Inrfb2</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10402</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10402"/>
				<updated>2007-03-14T11:44:29Z</updated>
		
		<summary type="html">&lt;p&gt;Inrfb2: /* Syntax-Bausteine */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Programmiersprache C wurde 1971 als Gundlage für das Betriebssystem UNIX in den USA entwickelt (UNIX ist zu über 90% in C geschrieben). 1978 wurde von Brian Kernighan und Dennis Ritchie eine eindeutige Sprachdefinition entwickelt. Mittlerweile ist C von ANSI und ISO standardisiert.&lt;br /&gt;
&lt;br /&gt;
Heute sind C und ihr Nachfolger C++ die dominierenden Programmiersprachen. Sehr viele Anwendungen sind in C geschrieben, was inzwischen auch auf eingebettete Systeme zutrifft, die lange in Assembler programmiert werden mussten, da keine ausreichend leistungsfähigen Compiler zur Verfügung standen. &lt;br /&gt;
&lt;br /&gt;
Leider ist C nicht einfach zu lernen &amp;amp;ndash; es wurde weder von noch für Hobby-Programmierer entwickelt &amp;amp;ndash; und eignet sich daher nur bedingt für den Einsteiger. Mit etwas Übung und einem optimierenden Compiler kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
Vom Design her ist C eine Hardware-unabhängig Sprache. Das bedeutet, daß C-Programme mit vertretbarem Aufwand auf ein anderes System portiert werden können. Dazu benötigt man lediglich einen anderen Compiler, und Inline-Assembler-Anweisungen (Assembleranweisungen innerhalb eines C-Programmes) müssen der neuen Hardware (Prozessor) angepasst werden. &lt;br /&gt;
&lt;br /&gt;
==Geschichte==&lt;br /&gt;
;1971: C wird entwickelt&lt;br /&gt;
;1978: Kernighan und Ritchie definieren die Sprache.&lt;br /&gt;
;1983: ANSI und ISO standardisieren C.&lt;br /&gt;
;1992: Bjarne Stroustrup enwickelt die Nachfolgesprache C++.&lt;br /&gt;
&lt;br /&gt;
=Aufbau eines C-Programmes=&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
   C-Programme haben keinen fixen Aufbau wie z.B. Pascal. Es gibt zwar gewisse Regeln, aber sonst sind dem Programmierer alle Freiheiten überlassen. Der folgende &amp;quot;Beispiel-Aufbau&amp;quot; ist daher nicht zwingend und kann durchaus verändert werden.&lt;br /&gt;
&lt;br /&gt;
   Natürlich haben C-Programme einen fixen Aufbau! Ebenso wie Pascal-Programme auch unterliegen sie einer strikten Grammatik! &lt;br /&gt;
Auskommentiert --[[Benutzer:SprinterSB|SprinterSB]] 10:23, 17. Feb 2006 (CET)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Ein einfaches C-Programm könnte folgendermassen aussehen. Das Programm tut eigentlich nichts, aber das Beispiel zeigt den prinzipiellen Aufbau. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 int Zahl1;&lt;br /&gt;
 char Zeichen1;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int zahl2;&lt;br /&gt;
 &lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Beschreibung:'''&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndash; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
 {{comment|void-Definition von main ist nur beim Controller ueblich}}&lt;br /&gt;
 {{comment|spezielle Compilereinstellungen sind noetig, damit bei dieser Definition von main}}&lt;br /&gt;
 {{comment|kein Fehler/Warnung erzeugt wird.}}&lt;br /&gt;
 void main ()&lt;br /&gt;
 {&lt;br /&gt;
     ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
 int main (void)&lt;br /&gt;
 {  {{comment|der Block &amp;quot;main&amp;quot; beginnt}}&lt;br /&gt;
    int zahl;&lt;br /&gt;
    &lt;br /&gt;
    {   {{comment|ein Block beginnt}}&lt;br /&gt;
        {{comment|hier koennen Deklarationen und Anweisungen stehen}}&lt;br /&gt;
    }   {{comment|der Block endet}}&lt;br /&gt;
   &lt;br /&gt;
    return 0;&lt;br /&gt;
 }  {{comment|&amp;quot;main&amp;quot; endet}}&lt;br /&gt;
&lt;br /&gt;
=Datentypen=&lt;br /&gt;
==Elementare Datentypen==&lt;br /&gt;
Der Datentyp einer Variable gibt an, welche Werte eine Variable enthalten kann, welcher Art diese Daten sind und wie sie verarbeitet werden, etwa in arithmetischen Operationen wie einer Addition. So ist es zum Beispiel möglich, in eine Variable vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ganze Zahlen zwischen ca. -32000 und +32000 einzutragen. In einer char-Variable können ASCII-Zeichen gespeichert werden (alles, was Sie mit der Tastatur erzeugen können) oder ganze Zahlen von -128 bis 127.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da C plattformabhängig ist, hängt die Größe eines Datentypes zum Teil von der genutzten Hardware (z.B. 8, 16 oder 32 Bit-Controller) und dem Compiler und dessen Einstellungen ab!&lt;br /&gt;
&lt;br /&gt;
===int, char, short, long (ganze Zahlen)===&lt;br /&gt;
In Variable dieser Typen können Sie ganze Zahlen abspeichern, also z.B. 1, &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;2, 100, 12345. Jeden dieser Typen gibt es in zwei Ausprägungen: als &amp;quot;&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;quot;, also als vorzeichenbehafteten Typ, und als &amp;quot;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&amp;quot;, also ohne Vorzeichen, d.h. das Vorzeichen wird als 0 oder +1 genommen. &lt;br /&gt;
&lt;br /&gt;
Vorzeichenbehaftete Ganzzahl-Typen werden intern im &amp;lt;tt&amp;gt;n-1&amp;lt;/tt&amp;gt;-Komplement dargestellt, das Vorzeichen selbst findet sich also im höchstwertigen Bit. Werden zur Speicherung ''b'' Bits verwendet, dann reicht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;z.B. *zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==Enum==&lt;br /&gt;
&lt;br /&gt;
Über &amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt; können Aufzählungen definiert werden. Die Werte sind &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Werte und beginnen mit&amp;amp;nbsp;0. Der folgende enum hat einen um&amp;amp;nbsp;1 grösseren Wert. Mit einer Zuweisung können auch andere Werte zugeordnet werden. Klarer wird's im Beispiel:&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 enum Farben&lt;br /&gt;
 {&lt;br /&gt;
    ROT,&lt;br /&gt;
    GRUEN,&lt;br /&gt;
    BLAU,&lt;br /&gt;
    BRAUN = 5,&lt;br /&gt;
    SCHWARZ&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
Dies definiert die Konstanten &amp;lt;tt&amp;gt;ROT=0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;GRUEN=1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BLAU=2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BRAUN=5&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;SCHWARZ=6&amp;lt;/tt&amp;gt; und den Typ &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void foo (enum Farben farbe)&lt;br /&gt;
{&lt;br /&gt;
   switch (farbe)&lt;br /&gt;
   {&lt;br /&gt;
      case ROT:&lt;br /&gt;
         ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit kann man anstatt &amp;quot;magischer&amp;quot; Zahlen sprechende Namen im Code verwenden, etwa in Berechnungen und Zuweisungen, Vergleichen oder als Konstante hinter einem &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zusammengesetzte Datentypen==&lt;br /&gt;
===Arrays===&lt;br /&gt;
Oft muß man sehr viele Werte gleichzeitig abspeichern und betrachten, die alle der selben Aufgabe dienen. Man schreibt z.B. ein Programm, das 10 Zahlen einlesen und anschließend wieder ausgeben soll. Man könnte das natürlich mit 10 einzelnen Variablen bewerkstelligen, aber es ist sinnvoller, dabei Arrays &amp;amp;ndash; teilweise auch als ''Felder'' bezeichnet &amp;amp;ndash; zu verwenden.&lt;br /&gt;
&lt;br /&gt;
In einem Array werden mehrere Variablen gleichen Typs zusammengefasst und hintereinander im Speicher abgelegt. So kann man viele tausend Variablen anlegen mit nur einer Zeile Code. Doch es gibt noch größere Vorteile: Sie können das Array mit einer Schleife ganz einfach nach Werten durchsuchen. Stellen Sie sich vor, Sie müssten mit 100 verschiedenen Variablen &amp;lt;tt&amp;gt;Zahl_00&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;Zahl_99&amp;lt;/tt&amp;gt; arbeiten!&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}}&amp;amp;#91;{{Konstante}}&amp;amp;#93;;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 unsigned int werte[100];&lt;br /&gt;
&lt;br /&gt;
Der Name muß natürlich ein gültiger Bezeichner sein, als Datentyp kann jeder Typ genommen werden &amp;amp;ndash; sowohl elementare Datentypen als auch Zeiger, Strukturen, Unions oder selbst definierte Datentypen. In der eckigen Klammer wird die Anzahl der Elemente bekanntgegeben. Ein mit [3] definiertes Array hat Platz für drei Variablen. Da der Index immer bei 0 beginnt, greift man also mit &amp;lt;tt&amp;gt;[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;[1]&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;[2]&amp;lt;/tt&amp;gt; auf den jeweilige Inhalt zu. Um auf eine der im Array enthaltenen Variablen zugreifen zu können, müssen Sie den Variablennamen und in eckigen Klammern den Index (die &amp;quot;Nummer&amp;quot;) der Variablen angeben. Diese Variable verhält sich dann wie eine ganz normale Variable des jeweiligen Datentypes. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #define NZAHLEN 10&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int i;&lt;br /&gt;
    int zahlen[NZAHLEN];  {{comment|zahlen[0] ... zahlen[9]}}&lt;br /&gt;
  &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++)&lt;br /&gt;
    {&lt;br /&gt;
       printf (&amp;quot;Bitte Zahl %d eingeben: &amp;quot;, i);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; zahlen[i]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++) &lt;br /&gt;
       printf (&amp;quot;Zahl %d ist: %d\n&amp;quot;, i, zahlen[i]);&lt;br /&gt;
      &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 10 int-Variablen großes Array angelegt. &lt;br /&gt;
In dieses wird nun der Reihe nach 10 Zahlen eingelesen. &lt;br /&gt;
Anschließend werden alle 10 Zahlen ausgegeben. &lt;br /&gt;
&lt;br /&gt;
Dabei wird die Größe der Arrays und das Schleifenende über das Define &amp;quot;&amp;lt;tt&amp;gt;NZAHLEN&amp;lt;/tt&amp;gt;&amp;quot; angegeben. Dadurch muss nur ''eine Stelle'' im Code geändert werden, wenn die Größe des Arrays einmal einen anderer Wert als 10 haben soll &amp;amp;ndash; dies vermeidet Fehler die dadurch entstehen, wenn man beim Anpassen der Array-Größe eine Codestelle vergisst, zudem wird der Code lesbarer als wenn irgendwo die Zahl &amp;quot;10&amp;quot; auftaucht.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
:Wird ein ungültiger Index angeben (einer, der in der Deklaration nicht enthalten ist) können  undefinierte Dinge passieren, wenn dadurch andere Variableninhalte oder Programmcode überschrieben wird, der hinter oder vor dem Array im Speicher liegt. Schlimmstenfalls kann sogar der Computer/Controller abstürzen. Also darauf achten, daß keine ungültigen Werte als Index auftreten!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Strings (Zeichenketten)===&lt;br /&gt;
Ein String ist nichts anderes als ein Array, das aus einzelnen Zeichen (&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;) gebildet wird. Die Ausgabe auf dem Bildschirm funktioniert am einfachsten mittels Strings.&lt;br /&gt;
&lt;br /&gt;
Die Definition eines Strings erfolgt also genauso wie bei Arrays:&lt;br /&gt;
 char string[21];&lt;br /&gt;
&lt;br /&gt;
Nun haben Sie eine String, in dem Sie 21 Zeichen speichern können. Ganz richtig ist das jedoch nicht. C arbeitet mit &amp;quot;null-terminierten Strings&amp;quot;. Das beudeutet, dass die Länge des Strings nicht abgespeichert wird, sondern das Zeichen mit dem ASCII-Wert 0 das Stringende kennzeichnet. Daher auch die Bezeichnung  &amp;quot;null terminiert&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Das letzte Zeichen eines Strings muß daher immer das ASCII-Zeichen Nr. 0 sein. Ist es das nicht, hat der String kein definiertes Ende, und wenn Sie versuchen, ihn durch eine Standard-Funktion auszugeben zu lassen, könnte es eine Weile dauern, bis sich im Speicher zufällig irgendwo eine 0 befindet. Es stehen ihnen daher bei dem Beispiel nur 20 Zeichen zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
===Mehrdimensionale Arrays===&lt;br /&gt;
Manchmal benötigt man mehr als nur ein eindimensionales Array, wie Sie es bisher kennengelernt haben. Auch dies ist kein Problem. In der Deklaration geben Sie einfach mehrere eckige Klammern hintereinander an. Aber Vorsicht: der Speicherplatz ist begrenzt, ein &amp;quot;&amp;lt;tt&amp;gt;char feld[1024][1024]&amp;lt;/tt&amp;gt;&amp;quot; hat die Speicherplatzgrenzen vermutlich bereits weit überschritten, und der Compiler wird einen (bei gewissen Einstellung auch keinen) Fehler liefern.&lt;br /&gt;
Beim Zugriff auf mehrdimensionale Felder müssen auch mehrere Indizes angeben werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  int x,y;&lt;br /&gt;
  int feld[3][5];&lt;br /&gt;
 &lt;br /&gt;
  for (x=0; x&amp;lt;3; x++) &lt;br /&gt;
  {&lt;br /&gt;
     for (y=0; y&amp;lt;5; y++)&lt;br /&gt;
     {&lt;br /&gt;
       printf (&amp;quot;Feldwert x: %d,  y: %d &amp;quot;, x, y);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; feld[x][y]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  for(x=0; x&amp;lt;3; x++) &lt;br /&gt;
     for (y=0; y&amp;lt;5; y++) &lt;br /&gt;
        printf (&amp;quot;Wert: feld[%d][%d] = %d\n&amp;quot;, x, y, feld[x][y]);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 3 mal 5 &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array angelegt. &lt;br /&gt;
Dann werden die Werte eingegeben: zuerst &amp;lt;tt&amp;gt;feld[0][0]&amp;lt;/tt&amp;gt;, dann &amp;lt;tt&amp;gt;feld[0][1]&amp;lt;/tt&amp;gt;, usw. bis &amp;lt;tt&amp;gt;feld[2][4]&amp;lt;/tt&amp;gt;. &lt;br /&gt;
Zum Schluß werden alle Werte noch einmal ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===Strukturen===&lt;br /&gt;
In C können Sie sogenannte &amp;quot;Strukturen&amp;quot; definieren. Dabei handelt es sich um eine Zusammenfassung mehrerer Datentypen zu einem größeren. Im Unterschied zu Feldern können in Strukturen unterschiedliche Datentypen zusammengestellt und gespeichert werden: &lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 struct {{Bezeichner}}&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur 'Person'}}&lt;br /&gt;
 struct Person &lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;lt;tt&amp;gt;struct Person {&amp;lt;/tt&amp;gt;&amp;quot; leitet die Definition der Struktur mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;Person&amp;lt;/tt&amp;gt;&amp;quot; ein. &lt;br /&gt;
Dann werden in dieser Struktur fünf Komponenten definiert: drei Strings und zwei &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. &lt;br /&gt;
mit &amp;lt;tt&amp;gt;}&amp;lt;/tt&amp;gt; wird die Definition abgeschlossen. Sie haben damit einen Datentyp erstellt. Um eine Variable des Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach an&lt;br /&gt;
 struct Person {{Bezeichner}};&lt;br /&gt;
&lt;br /&gt;
Zum Zugriff auf eine Komponente der Struktur gibt man den Namen der Struktur-Variablen an (im folgenden Beispiel also &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;klaus&amp;lt;/tt&amp;gt;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
 {{comment|Definition zweier Struktur-Variablen}}&lt;br /&gt;
 struct Person hubert, klaus;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Zugriff auf Struktur-Komponenten}}&lt;br /&gt;
 hubert.alter = 32;&lt;br /&gt;
 klaus.alter = hubert.alter + 1;&lt;br /&gt;
&lt;br /&gt;
===Unions===&lt;br /&gt;
Eine Union wird ganz analog zu einer Struktur deklariert und verwendet. Sie unterscheidet sich von einer Struktur jedoch dadurch, daß ihre Elemente nicht nacheinander im Speicher abgelegt werden, sondern sich überlagern. Auf die in einer Union enthaltenen Daten gibt es also verschiedene Sichten: je nachdem, welche Sicht bzw. Interpretation der Daten man gerne hätte, wählt man den gewünschten Zugriff.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
union Daten &lt;br /&gt;
{&lt;br /&gt;
   int id;&lt;br /&gt;
&lt;br /&gt;
   struct Person u_person;&lt;br /&gt;
&lt;br /&gt;
   struct u_double&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      double wert;&lt;br /&gt;
   };&lt;br /&gt;
&lt;br /&gt;
   struct u_pointer&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      union Daten * p1;&lt;br /&gt;
      union Daten * p2;&lt;br /&gt;
   };&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
union Daten data;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies definiert eine Union mit den vier Zugriffsmöglichkeiten &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_double&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Größe der Union richtet sich dabei nach der grössten Komponente. In diesem Beispiel sind alle Komponenten so angelegt worden, daß sie an erster Stelle ein &amp;lt;tt&amp;gt;int id&amp;lt;/tt&amp;gt; enthalten. In &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; könnte man sich also merken, wie die Daten in der Union zu interpretieren sind. Würde &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; nicht dieses &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; enthalten, so würde sich &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; mit &amp;lt;tt&amp;gt;data.u_person.vname&amp;lt;/tt&amp;gt; überlagern. Ein Ändern der ersten Buchstaben von &amp;lt;tt&amp;gt;vname&amp;lt;/tt&amp;gt; hätte also ein Ändern von &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; zur Folge, und man könnte es nicht mehr als Merker verwenden. Mit diesem Feld überlagert das &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; die &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;-Felder der anderen Sichten, z.B. ist &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; der selbe Zugriff wie auf &amp;lt;tt&amp;gt;data.u_person.id&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein anderes Beispiel ist eine Union, die es ermöglicht, auf die einzelnen Bytes eines &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; zuzugreifen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef union&lt;br /&gt;
{&lt;br /&gt;
   unsigned long  as_long;&lt;br /&gt;
   unsignen short as_short[2];&lt;br /&gt;
   unsignen char  as_byte[4];&lt;br /&gt;
} data32_t;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies überlagert einen &amp;lt;tt&amp;gt;unsigned long&amp;lt;/tt&amp;gt; &amp;amp;ndash; also eine 32-Bit-Zahl &amp;amp;ndash; mit vier Bytes bzw. zwei Shorts.&lt;br /&gt;
 data32_t wert;&lt;br /&gt;
 &lt;br /&gt;
 wert.as_long = 0x12345678;&lt;br /&gt;
 wert.as_byte[0] = 0xab;&lt;br /&gt;
 {{comment|nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform)}}&lt;br /&gt;
&lt;br /&gt;
==Eigene Datentypen==&lt;br /&gt;
&lt;br /&gt;
=Variablen=&lt;br /&gt;
Eine Variable ist ein Synonym (=anderer Name) für eine Speicherstelle in einem Computer. Einfacher gesagt, eine Variable bietet Raum, um Daten wie Zahlen oder Zeichen zu speichern und wieder zu lesen.&lt;br /&gt;
&lt;br /&gt;
==Variablennamen==&lt;br /&gt;
Ein Variablenname kann zusammengesetzt werden aus den Buchstaben &amp;lt;tt&amp;gt;'''A'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''Z'''&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;'''a'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''z'''&amp;lt;/tt&amp;gt;, den Ziffern &amp;lt;tt&amp;gt;'''0'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''9'''&amp;lt;/tt&amp;gt;, sowie dem Sonderzeichen &amp;quot;Unterstrich&amp;quot; (underscore) &amp;lt;tt&amp;gt;'''_'''&amp;lt;/tt&amp;gt;. Dabei darf an erster Stelle keine Ziffer stehen. Die Bezeichner &amp;lt;tt&amp;gt;hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALLO&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALL0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;_123&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_HALLO&amp;lt;/tt&amp;gt; sind also alle gültige und unterschiedliche Variablennamen.&lt;br /&gt;
&lt;br /&gt;
==Anlegen von Variablen==&lt;br /&gt;
Um eine Variable verwenden zu können, muss sie zuerst vereinbart (&amp;quot;erzeugt&amp;quot;) werden. Dies wird auch als &amp;quot;''Definition der Variablen''&amp;quot; bezeichnet und geht so: Schreiben Sie zuerst den Datentyp, dann den Namen der Variablen. Zum Schluß kommt noch der Strichpunkt, wie nach jeder C-Anweisung oder Deklaration. Und nicht vergessen: C unterscheidet zwischen  Groß- und Kleinschreibung! &lt;br /&gt;
 int Zahl1, Zahl2;&lt;br /&gt;
 char Zeichen;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    float gleitZahl;&lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:'''&lt;br /&gt;
In einer Zeile können auch mehrere Variablen gleichen Types vereinbart werden, wenn man ein Komma dazwischen setzt. Variablen können in jedem Block vereinbart werden. Siehe [[#Gültigkeitsbereich|Gültigkeitsbereich]].&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen==&lt;br /&gt;
Man kann einer vereinbarten Variable Werte [[#Zuweisungen|zuweisen]]. Dazu schreibt man zuerst den Variablennamen, ein Gleichheitszeichen &amp;quot;&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;&amp;quot; und anschliessend den zuzuweisenden [[#Ausdrücke|Ausdruck]]. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, zahl2 = 12;&lt;br /&gt;
  char zeichen1 = 'A';&lt;br /&gt;
&lt;br /&gt;
  zahl1 = 52;&lt;br /&gt;
  zeichen1 = zeichen1 + 1; &lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Zuerst werden drei Variablen angelegt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;: wird gleich bei der Vereinbarung der Wert 12 zugewiesen. &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl1 = 52&amp;lt;/tt&amp;gt;: Hier wird der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; der Wert 52 zugewiesen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;: wird um 1 erhöht. Da in der Variablen &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; gespeichert ist, gibt sich ihr neuer Wert aus &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt;. Weil &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; dem Wert 65 entspricht, ist &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt; gleich 66, was dem Wert für &amp;lt;tt&amp;gt;'B'&amp;lt;/tt&amp;gt; entspricht.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei float==&lt;br /&gt;
Das funktioniert genau wie bei normale Zuweisungen. Nachkommastellen werden durch einen Punkt abgegrenzt: &lt;br /&gt;
 floatVariable = 3.14;&lt;br /&gt;
Zusätzlich kann eine Zehnerpotenz angegeben werden:&lt;br /&gt;
 floatVariable2 = -1.234E-6;&lt;br /&gt;
Dadurch wird der erst Wert mit 10&amp;lt;sup&amp;gt;&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;6&amp;lt;/sup&amp;gt; multipliziert, der Wert der Variablen ist also &lt;br /&gt;
:&amp;lt;math&amp;gt;-1{,}234\cdot10^{-6} = -0.000001234&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei logischen Variablen==&lt;br /&gt;
Wie bereits erwähnt, besitzt C keinen logischen Datentyp. Es müssen also &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; dafür genutzt werden. Die Zuweisung entpricht der Standard-Zuweisung. Wird der Wert 0 zugewiesen, dann ist die Variable &amp;quot;unwahr&amp;quot;, ansonsten ist sie &amp;quot;wahr&amp;quot;. &lt;br /&gt;
 intVariable = !0;   /* entspricht &amp;quot;wahr&amp;quot;   */&lt;br /&gt;
 intVariable = 0;    /* entspricht &amp;quot;unwahr&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
==Konstanten==&lt;br /&gt;
Konstanten können als Variable angesehen werden, die nicht beschrieben, sondern nur gelesen werden können. Ein typisches Beispiel dafür ist die Zahl &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; (rund 3,141592654). Niemand würde in der realen Welt versuchen, ihr einen anderen Wert zuzuweisen. Würde man &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; jedoch wie eine normale Variable anlegen, wäre dies ohne weiteres möglich. Um dies zu verhindern, gibt es das Schlüsselwort &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in C:&lt;br /&gt;
 const {{Type}} {{Bezeichner}} = {{Konstante}};  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Wichtig dabei ist, dass man Konstanten nur bei der Vereinbarung einen Wert zuweisen kann. &lt;br /&gt;
Da Konstanten gewöhnlich im gesamten Programm, zumindest einer Quelldatei genutzt werden, definiert man diese allerdings gewöhnlich außerhalb des main-Blockes entweder am Anfang eines Programmes, oder in einer sogenannten Header-Datei, die per &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; eingebunden wird.&lt;br /&gt;
 const float PI = 3.141592;  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Es sei jedoch erwähnt, daß auch einer Konstanten nachträglich ein anderer Wert zugewieden werden kann. Im obigen Beispiel könnte mit&lt;br /&gt;
 * ((float*) &amp;amp;PI) = 2;&lt;br /&gt;
der Wert von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; im Nachhinein verändert werden. Es wird die Adresse von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; genommen und diese Adresse durch den Cast in eine ganz normale &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;-Adresse umgewandelt, über welche der Wert geändert wird. Die sei der Vollständigkeit halber erwähnt.&lt;br /&gt;
&lt;br /&gt;
Je nachdem, an welcher Stelle sich das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; bei einer Pointer-Deklaration befindet, markiert es den Pointer als konstant oder das Objekt, auf das dieser Pointer zeigt. Eine häufige Parameterdeklaration in Ausgabe-Funktionen, die einen String erhalten, ist&lt;br /&gt;
 void foo (const char * str, ...);&lt;br /&gt;
Dadurch ist &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; der Zeiger auf eine Zeichenkette, die innerhalt der Funktion nicht verändert wird bzw. verändert werden darf. Eine Zuweisung wie &amp;lt;tt&amp;gt;*str = 'a'&amp;lt;/tt&amp;gt; ergibt also einen Fehler. &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; selbst kann aber sehr wohl verändert werden, etwa mit &amp;lt;tt&amp;gt;str++&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Soll ausgedrückt werden, daß &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; unveränderlich ist, dann so:&lt;br /&gt;
 void foo (char * const str, ...);&lt;br /&gt;
Jetzt wäre eine Änderung des Strings in Ordnung, etwa durch &amp;lt;tt&amp;gt;str[10] = 'a'&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Um sich zu merken, worauf das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; wirkt, trennt man die Deklaration in Gedanken beim&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf: Steht das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; links vom&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, dann gehört es zum &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, steht es rechts davon, dann gehört es zum Pointer. Natürlich ist es auch denkbar, beides &amp;amp;ndash; also den Zeiger und sein Ziel &amp;amp;ndash; als konstant zu markieren.&lt;br /&gt;
&lt;br /&gt;
==Gültigkeitsbereich==&lt;br /&gt;
In C können mehrere Variablen den gleichen Namen haben, solange eindeutig ist, welche in welchen Block gültig ist. Dabei gelten folgende Regeln: &lt;br /&gt;
&lt;br /&gt;
;Lokale Variablen: sind Variablen, die innerhalb eines Blockes definiert werden. Jede Variable ist nur in dem Block gültig, in dem sie vereinbart wurde, sowie in allen darin enthaltenen Blöcken; es sei denn, in einem Unter-Block wird eine Variable gleichen Namens definiert. Dann bezieht sich in diesem Unter-Block der Bezeichner auf die im Unter-Block angelegte Variable.&lt;br /&gt;
;Globale Variablen: werden ausserhalb jedes Blockes definiert und gelten ab der Stelle, an der sie deklariert werden, siehe auch [[#Deklaration und Definition|Deklaration und Definition]]. Wird jedoch in einem Block eine Variable gleichen Namens angelegt, gilt ab hier bis zum Ende des Blocks nicht mehr die globale Variable, sondern die im Block deklarierte. Das Spiel kann man weiterspielen: wird in einem Unter-Block wieder eine namensgleiche Variable angelegt, gilt diese in dem Unterblock.&lt;br /&gt;
&lt;br /&gt;
==Speicherklassen==&lt;br /&gt;
Jede Variable in C gehört zu einer bestimmten Speicherklasse&lt;br /&gt;
;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;: Lokale Variablen sind in aller Regal sogenannte ''automatische Variablen''. Das bedeutet, sie werden automatisch angelegt, wenn ein Block bzw. eine Funktion betreten wird und danach wieder entfernt. Das Schlüsselwort &amp;quot;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;&amp;quot; wird praktisch nie hingeschrieben, denn lokale Variablen ohne die ausdrückliche Angabe einer Speicherklasse, sind automatisch automatische Variablen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;: Eine externes Symbol ist im ganzen Programm bekannt bzw. in dem Block, in der die Deklaration steht. In unterschiedlichen Blöcken stehende Deklarationen beziehen sich auf das gleiche Symbol! Obgleich das Datum global zugreifbar ist, ist der Gültigkeitsbereich auf den deklarierenden Block begrenzt bzw. auf das deklarierende Quell-Modul, sofern das Symbol ausserhalb jedes Blocks des Moduls deklariert wird. Siehe auch [[#Deklaration und Definition|Deklaration und Definition]].&lt;br /&gt;
;&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;: Die Variable ist im Block gültig bzw. im Quell-Modul (also in der C-Datei, in der die angelegt wurde), wenn sie nicht innerhalb eines Blockes angelegt wurde. Statische Variablen werden nicht in Registern oder im Frame der Funktion angelegt, sondern im selben Speicherbereich, in dem auch die globalen Variablen liegen; Konstanten evtl. auch im Flash. Eine lokale Variable, die als &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; angelegt wird, &amp;quot;überlebt&amp;quot; also das Verlassen des Blocks und hat beim neuerlichen Betreten des Blockes ihren bisherigen Wert. In unterschiedlichen Blöcken angelegte lokale statische Variablen beziehen sich auf unterschiedliche Speicherstellen, genau wie bei lokalen Variablen auch.&lt;br /&gt;
;&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;: Durch diese Speicherklasse wird eine Variable &amp;amp;ndash; falls möglich &amp;amp;ndash; als Registervariable angelegt, also in einem Maschinenregister des Computer/Controllers gehalten. Dadurch kann auf solche Variablen besonders schnell zugegriffen werden. Dieses Schlüsselwort ist bei modernen Compilern weitgehend überflüssig, da die entsprechenden Optimierungen selbständig vorgenommen werden, wenn ausreichend Register vorhanden sind. Auch globale Variablen können als Register angelegt werden, davon ist dem Anfänger aber dringend abzuraten, weil leicht schwerauffindbare Fehler und Abstürze auftreten, wenn man nicht genau weiss, welche Implikationen in einer solchen Definition stecken!&lt;br /&gt;
;&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;: (FIXME: volatile ist ein Qualifier und keine Speicherklasse) Dies ist das genaue Gegenteil von &amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt; und bewirkt, dass die Variable auf keinen Fall in einem Register zwischengespeichert werden darf, sondern immer aus dem RAM gelesen und ins RAM geschrieben werden soll. &amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt; müssen alle ''globalen'' Variablen markiert werden, die in [[ISR | Interrupt-Handlern]] verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Ausdrücke=&lt;br /&gt;
Eine Variable oder eine Konstante in C stellen einfache Ausdrücke dar.&lt;br /&gt;
Diese elementaren Ausdrücke können durch Operatoren miteinander verknüpft werden und so zu neuen, komplexeren Ausdrücken zusammen gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Einfache Beispiele für Ausdrücke sind also z.B.:&lt;br /&gt;
 1&lt;br /&gt;
 a&lt;br /&gt;
 'a'&lt;br /&gt;
 1 + a&lt;br /&gt;
 a == 1&lt;br /&gt;
&lt;br /&gt;
Auch Funktionen können einen Wert zurückliefern und in Ausdrücken weiter benutzt werden.&lt;br /&gt;
In den folgenden Abschnitten wird gezeigt, welche Operatoren in C vorhanden sind,&lt;br /&gt;
und wei man damit neue Ausdrücke aufbauen kann.&lt;br /&gt;
&lt;br /&gt;
==Lvalues==&lt;br /&gt;
&lt;br /&gt;
Ein Lvalue in C ist ein Ausdruck, dem ein anderer Ausdruck zugewiesen werden kann, dessen Wert also durch eine Zuweisung verändert werden kann.&lt;br /&gt;
das 'L' leitet sich ab von 'left' bwz. 'links' und das 'value' bedeutet Wert: Ein Lvalue ist ein Ausdruck, der auf der linken Seite einer Zuweisung stehen darf. Ein Lvalue ist also immer auch ein gültiger Ausdruck, aber die Umkehrung gilt in alles Regel nicht.&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für einen Lvalue ist eine &amp;quot;normale&amp;quot; Variable, die nicht mit &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; als Konstante markiert ist:&lt;br /&gt;
 a = 1;&lt;br /&gt;
Hingegen ist der Ausdruck &amp;lt;tt&amp;gt;a+1&amp;lt;/tt&amp;gt; kein Lvalue, denn eine Zuweisung wie&lt;br /&gt;
 a+1 = 2;&lt;br /&gt;
die mathematisch durchaus sinnvoll ist, erzeugt einen Compilerfehler, der etwa lauten könnte &amp;quot;illegal lvalue in assignment&amp;quot;:&lt;br /&gt;
&amp;quot;ungültiger Wert in Zuweisung&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Andere Beipiele für Lvalues sind die Komponenten von (nicht-konstanten) [[#Strukturen|Strukturen]] und [[#Unions|Unions]], [[#Arrays|Array]]-Elemente und die Dereferenzierungen von Pointern: Die Konstante&amp;amp;nbsp;4 wird durch den Cast in eine Adresse umgewandelt. Über die Dereferenzierung&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; wird an die Adresse&amp;amp;nbsp;4 im Speicher eine&amp;amp;nbsp;3 geschrieben. Ob das erlaubt bzw. sinnvoll ist, ist abhängig von der jeweiligen Architektur.&lt;br /&gt;
 * ((unsigned int *) 4) = 3;&lt;br /&gt;
Hier ist der gesamte &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;-Ausdruck ein Lvalue&lt;br /&gt;
&lt;br /&gt;
==Logische (boolsche) Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp;amp;&amp;amp;amp; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr oder &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; || gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; || ungleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;= b&amp;lt;/tt&amp;gt; || kleiner oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt; b&amp;lt;/tt&amp;gt; || kleiner als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt;= b&amp;lt;/tt&amp;gt; || glösser oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt; b&amp;lt;/tt&amp;gt; || grösser als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; nicht wahr und vice versa&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine interessante Eigenschaft der Operatoren &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;amp;amp;&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; ist, dass&lt;br /&gt;
sie die Auswertung abbrechen, sobald das Ergebnis feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet. Ein oft anzutreffendes Codestück sieht so aus, dabei sei &amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
  if (p &amp;amp;&amp;amp; *p == 5)&lt;br /&gt;
  {&lt;br /&gt;
     {{comment|mach was}}&lt;br /&gt;
  }&lt;br /&gt;
Zuerst wird in der Bedinung geprüft, ob Zeiger&amp;amp;nbsp;&amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; einen Wert ungleich Null hat, also ob er überhaupt einen gültigen Wert enthält. Es ist weit verbreitete Konvention in C, daß Zeiger, die keinen gültigen Wert haben, die Adresse&amp;amp;nbsp;0 enthalten. '''Nur dann, wenn ein Zeiger nicht ein Null-Pointer ist, darf überhaupt ein Zugriff über ihn erfolgen!'''&lt;br /&gt;
&lt;br /&gt;
==Vergleich von Variablen==&lt;br /&gt;
Skalare Variablen (also ganze Zahlen, Gleitkommazahlen, Zeiger) können miteinander verglichen werden. Dazu gibt es die folgenden Operatoren in C: &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; || ist nicht gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;=&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;=&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das Ergebnis der Auswertung ist eine ganze Zahl. Ist die Bedingung erfüllt, dann ist der Wert ungleich&amp;amp;nbsp;0. Ist die Bedingung nicht erfüllt, dann ist ihr Wert gleich&amp;amp;nbsp;0.&lt;br /&gt;
Meistens wird man diese Operatoren in &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Konstrukten finden wie zum Beispiel&lt;br /&gt;
 if (x &amp;gt;= 10)&lt;br /&gt;
    x = 10;&lt;br /&gt;
oder in Abbruchbedingungen von Schleifen, wie sie weiter unten erklärt werden.&lt;br /&gt;
&lt;br /&gt;
Es ist auch möglich, das Ergebnis der Auswertung in einer &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Variablen zu speichern:&lt;br /&gt;
 int i;&lt;br /&gt;
 int z1, z2;&lt;br /&gt;
 &lt;br /&gt;
 z1 = 5;&lt;br /&gt;
 z2 = 100;&lt;br /&gt;
 i = z1 &amp;lt;= z2;  {{comment|Ein Vergleich. i wird &amp;quot;wahr&amp;quot;, da z1 kleinergleich z2 ist}}&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich&amp;amp;nbsp;0 (&amp;quot;wahr&amp;quot;), wenn &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; kleiner oder gleich &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt; ist. Ist &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; jedoch größer als &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt;, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich&amp;amp;nbsp;0 (&amp;quot;unwahr&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
==Arithmetische Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a + b&amp;lt;/tt&amp;gt; || Summe (Addition)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a - b&amp;lt;/tt&amp;gt; || Differenz (Subtraktion)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a * b&amp;lt;/tt&amp;gt; || Produkt (Multiplikation)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a / b&amp;lt;/tt&amp;gt; || Quotient (Division, evtl. mit Rest)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a % b&amp;lt;/tt&amp;gt; || Rest bei Division (Modulo)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;-a&amp;lt;/tt&amp;gt; || Vorzeichenumkehr (Zweierkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Bit-Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp; b&amp;lt;/tt&amp;gt; || bitweise und (and)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || bitweise oder (or)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a ^ b&amp;lt;/tt&amp;gt; || bitweise exclusiv-oder (xor, exor)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;~a&amp;lt;/tt&amp;gt; || jedes Bit in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; invertieren (not, Einerkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Index-Operator bei Arrays==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a[b]&amp;lt;/tt&amp;gt; || das (b+1)ste Element des Feldes a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Folgendes gilt es bei der Verwendung des Indexoperators zu beachten:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; muss ein [[C-Tutorial#Felder | Feld]] oder [[C-Tutorial#Zeiger | Zeiger]] sein&lt;br /&gt;
# &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; muss ein Integer sein oder ein Datentyp, der sich in einen int umwandeln läßt (z.B. char)&lt;br /&gt;
# Es wird nicht geprüft, ob der Index &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; im Feld &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gültig ist!&lt;br /&gt;
# Der erste Index eines Feldes ist immer 0. Daher ''(b+1)stes Element'' in der Beschreibung&lt;br /&gt;
&lt;br /&gt;
==Komponenten-Auswahl bei Structs und Unions==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a.b&amp;lt;/tt&amp;gt; || Element b der [[C-Tutorial#Strukturen | Struktur]] oder des Unions a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adress-Operator und Dereferenzierung==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&amp;amp;amp;a&amp;lt;/tt&amp;gt; || Speicheradresse der Variablen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;*a&amp;lt;/tt&amp;gt; || Wert, der an der Adresse &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a-&amp;amp;gt;b&amp;lt;/tt&amp;gt; || Wert des Elements &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; der Struktur, deren Adresse in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Adressoperator &amp;amp; kann auf Variablen angewendet werden und&lt;br /&gt;
gibt die Startadresse der Variablen im Speicher zurück.&lt;br /&gt;
&lt;br /&gt;
Handelt es sich bei einer Variable um einen [[C-Tutorial#Zeiger | Zeiger]], so enthält&lt;br /&gt;
sie eine Speicheradresse. Um an den '''Wert''' zu gelangen, der&lt;br /&gt;
an dieser Adresse steht, wird der Operator * vorangestellt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
&lt;br /&gt;
 {{comment|x ist eine Integervariable und hat den Wert 5}}&lt;br /&gt;
 int x = 5;&lt;br /&gt;
     &lt;br /&gt;
 {{comment|z ist ein Zeiger auf eine Integer-Variable und enthaelt somit}}&lt;br /&gt;
 {{comment|die Speicheradresse einer Integer-Variablen}}&lt;br /&gt;
 int *z;       &lt;br /&gt;
  &lt;br /&gt;
 {{comment|Verwendung des Adress-Operators: weist an z die Adresse von x zu}}&lt;br /&gt;
 z = &amp;amp;x;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Verwendung der Dereferenzierung}}&lt;br /&gt;
 {{comment|erhoehe den Wert, der bei Adresse z steht, um eins}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|da z auf x zeigt, hat x jetzt den Wert 6}}&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff auf Struktir- und Union-Elemente eine abkürzende Schreibweise möglich:&lt;br /&gt;
&lt;br /&gt;
Statt &lt;br /&gt;
  (*strukturZeiger).element&lt;br /&gt;
kann geschrieben werden&lt;br /&gt;
  strukturZeiger-&amp;gt;element&lt;br /&gt;
Beide Schreibweisen sind absolut gleichbedeutend, die Klammern bei der ersteren sind notwendig.&lt;br /&gt;
&lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
:Bei der Dereferenzierung durch &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; findet keine Prüfung statt, ob der Zeiger auch auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu einer Änderung '''irgendeiner''' Speicherstelle!&lt;br /&gt;
&lt;br /&gt;
 int *z; {{comment|z ist ein Zeiger auf einen int}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.}}&lt;br /&gt;
 {{comment|z enthaelt irgendeine ungueltige Adresse!!}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|&amp;quot;Erhoehe einen Integer _irgendwo_ im Speicher um 1&amp;quot; -&amp;gt; CRASH !!!}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
&lt;br /&gt;
==Cast-Operator==&lt;br /&gt;
&lt;br /&gt;
Der Cast Operator dient dazu, den Datentyp eines Wertes zu ändern. Dafür wird einfach der neue Datentyp in Klammern vor den Wert geschrieben.&lt;br /&gt;
&lt;br /&gt;
Um zum Beispiel aus einem Float ein Integer zu machen:&lt;br /&gt;
 var  = (int) 5.60;&lt;br /&gt;
Dabei wird der Wert aber auch gerundet, und es findet somit ein Informationsverlust statt.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Umwandeln einer ganzen Zahl in eine Adresse:&lt;br /&gt;
 int * addr;&lt;br /&gt;
 addr = (int*) 0x1234;&lt;br /&gt;
Damit ist &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; an Adresse 0x1234.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
Der Cast-Operator selbst führt ''keine Konvertierung'' von Darstellungen durch, etwa die Umwandlung der ganzen Zahl 123 ein den String &amp;lt;tt&amp;gt;&amp;quot;123&amp;quot;&amp;lt;/tt&amp;gt;, der diese Zahl darstellt! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
  int main(int argc, char ** argv)&lt;br /&gt;
  {&lt;br /&gt;
        char text[] = &amp;quot;5.6&amp;quot;;&lt;br /&gt;
        int zahl = (int) text;&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, zahl);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Anfangsadresse des Strings &amp;lt;tt&amp;gt;&amp;quot;5.6&amp;quot;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Komma-Operator==&lt;br /&gt;
Mit einem &amp;lt;tt&amp;gt;,&amp;lt;/tt&amp;gt; können mehrere Ausdrücke nacheinander ausgewertet werden.&lt;br /&gt;
Die Auswertung erfolgt von links nach rechts.&lt;br /&gt;
&lt;br /&gt;
Solche Konstrukte sieht man manchmal in Abfragen wie&lt;br /&gt;
 FILE  *file;&lt;br /&gt;
 if (file = fopen (&amp;quot;foo.exe&amp;quot;, &amp;quot;r&amp;quot;), file != NULL)&lt;br /&gt;
was erst an &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; einen Wert zuweist und den &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Block nur betritt,&lt;br /&gt;
wenn &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; nicht der Nullpointer ist.&lt;br /&gt;
&lt;br /&gt;
Bequem kann das auch in einer [[#for-Schleife|for-Schleife]] sein, wenn man zwei (oder mehr) Laufvariablen hat oder so:&lt;br /&gt;
 for (i=0, j=0; i &amp;lt; 10; i++, j += 2)&lt;br /&gt;
    &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Zuweisung===&lt;br /&gt;
=== ++ und -- ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; stellen einfachere Schreibweisen dar zum Addieren bzw. Subtrahieren von&amp;amp;nbsp;1.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; (Inkrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo++; &lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo + 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; 3}}&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; (Dekrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo--;&lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo - 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; -1}}&lt;br /&gt;
&lt;br /&gt;
Die beiden Operatoren können sowohl in der Präfix-Schreibweise (vor der Variablen) als auch als Postfix-Schreibweise (hinter der Variablen) notiert werden. &lt;br /&gt;
Der Unterschied liegt darin, dass beim Präfix der Wert zuerst neu berechnet wird und die Variable dann verwendet wird. Beim Postfix wird die Variable zuerst verwendet und erst nach Auswertung des Ausdrucks, in dem sie enthalten ist, neu berechnet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 int ausgabe1, ausgabe2, var1 = 10, var2 = 10;&lt;br /&gt;
 ausgabe1 = 3 * ++var1; {{comment|ausgabe1 &amp;amp;#61; 33; var1 &amp;amp;#61; 11;}}&lt;br /&gt;
 ausgabe2 = 3 * var2++; {{comment|ausgabe2 &amp;amp;#61; 30; var2 &amp;amp;#61; 11;}}&lt;br /&gt;
&lt;br /&gt;
Für Zeiger arbeiten diese Operatoren etwas anders, siehe dazu [[#Zeiger-Arithmetik|Zeiger-Arithmetik]].&lt;br /&gt;
&lt;br /&gt;
===Bedingter Ausdruck===&lt;br /&gt;
 ({{Bedingung}}) ? {{Ausdruck|1}} : {{Ausdruck|2}}&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; erfüllt ist, dann wertet dieser Ausdruck aus zu &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt;. Ist er nicht erfüllt, dann wertet er aus zu &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 x = (x &amp;gt;= 3) ? 0 : x+1;&lt;br /&gt;
Startet man &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; mit dem Wert 0, dann nimmt es bei mehrfacher Anwendung dieser Zeile (z.B. in einer Schleife) nacheinander die folgende Werte an:&lt;br /&gt;
:&amp;lt;tt&amp;gt;1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, ...&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&lt;br /&gt;
Wie auch in der Mathematik gibt es auch in C genaue Regeln über die Abarbeitungsreihenfolge (precedence)&lt;br /&gt;
der Operatoren. Dass sich alle C-Compiler genau an diesen ANSI-Vorschlag halten, ist leider nicht sicher.&lt;br /&gt;
Sicher jedoch ist, dass nicht jeder Programmierer diese Regel jederzeit im Kopf hat. &lt;br /&gt;
Daher ist es sinnvoll, Ausdrücke durch runde Klammern eindeutig zu kennzeichnen. &lt;br /&gt;
Nebenbei stören sich Compiler nicht an überflüssigen Klammerpaaren.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Priorität ||Operator||Assoziativität&lt;br /&gt;
|-&lt;br /&gt;
  &lt;br /&gt;
|&amp;lt;tt&amp;gt;15&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ( ) [ ] -&amp;gt; . &amp;lt;/tt&amp;gt;                      ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;14&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;! ~ ++ -- + - (TYP) * &amp;amp; sizeof &amp;lt;/tt&amp;gt;    ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;13&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; * / % (Rechenoperationen) &amp;lt;/tt&amp;gt;         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;12&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; + - (binär) &amp;lt;/tt&amp;gt;                       ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;11&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;&amp;lt; &amp;gt;&amp;gt; &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;10&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt; &amp;lt;= &amp;gt; &amp;gt;= &amp;lt;/tt&amp;gt;                         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 9&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; == != &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 8&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp; (bit-AND-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 7&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ^ (bit-XOR-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 6&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; (bit-OR-Operator)&amp;lt;/tt&amp;gt;   ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 5&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp;&amp;amp; &amp;lt;/tt&amp;gt;                                ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 4&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; &amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 3&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;? : &amp;lt;/tt&amp;gt;                               ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 2&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; = += -= /= *= %= &amp;gt;&amp;gt;= &amp;lt;&amp;lt;= &amp;amp;= &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;= ^= &amp;lt;/tt&amp;gt; ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 1&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; , (Sequenz-Operator) &amp;lt;/tt&amp;gt;              ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
&lt;br /&gt;
Peter Baeumle-Courth, ANSI-C im Überblick &amp;lt;p&amp;gt;&lt;br /&gt;
W. Alex, Einführung in C/C++&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
Eine Kontrollanweisung ist eine Anweisung, die Einfluss auf den Programmfluss hat. Normalerweise werden Anweisungen so ausgeführt, wie sie in der Quelldatei stehen: Von links nach rechts (falls mehrere Anweisungen in einer Zeile stehen sollten, wovon i.A. abzuraten ist) und von oben nach unten. Mit einer Kontrollanweisung kann dieser lineare Programmfluss durchbrochen werden: Die Codeausführung kann kann abhängig von einer Bedingung gemacht werden (&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;), kann wiederholt werden (Schleife) oder an einer anderen Stelle der Funktion fortgesetzt werden (&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==if-Anweisung==&lt;br /&gt;
Mit Hilfe des if-Befehls kann man Codeteile abhängig davon einer Bedingung ausführen lassen:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
oder mit else-Teil&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 if (x &amp;gt; 100)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;gt; 100 ist: Fehlerausgabe}}&lt;br /&gt;
    printf (&amp;quot;x = %d ist zu gross fuer die Berechnung!\n&amp;quot;, x);&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;lt;&amp;amp;#61; 100 ist: Berechne Summe der Zahlen 1...x}}&lt;br /&gt;
    {{comment|Die lokale Variable x2 lebt nur innerhalb dieses alse-Blocks}}&lt;br /&gt;
    int x2 = x;&lt;br /&gt;
 &lt;br /&gt;
    for (x = 0; x2 &amp;gt; 0; x2--)&lt;br /&gt;
       x += x2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Wenn die Bedingung wahr ist (&amp;lt;tt&amp;gt;x &amp;gt; 100&amp;lt;/tt&amp;gt;), dann wird eine Meldung ausgegeben; danach ist die if-Anweisung beendet. Der else-Block wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung nicht erfüllt (&amp;lt;tt&amp;gt;x &amp;amp;le; 100&amp;lt;/tt&amp;gt;), dann wird gleich zum else-Teil gesprungen, und nach dessen Ausführung der if-Befehl beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Ein häufiger Fehler ist es, statt &amp;lt;tt&amp;gt;if (a &amp;amp;#61;&amp;amp;#61; 23)&amp;lt;/tt&amp;gt; etwas wie &amp;lt;tt&amp;gt;if (a &amp;amp;#61; 23)&amp;lt;/tt&amp;gt; zu schreiben. &lt;br /&gt;
Dann wird allerdings nicht geprüft, ob die Variable&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gleich 23 ist, sondern der Variablen&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wird der Wert 23 zugewiesen. Der Ausdruck &amp;lt;tt&amp;gt;a &amp;amp;#61; 23&amp;lt;/tt&amp;gt; hat den Wert&amp;amp;nbsp;23 und ist damit immer &amp;quot;wahr&amp;quot;! Daher ist diese if-Bedingung immer erfüllt!&lt;br /&gt;
&lt;br /&gt;
Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken sondern bestenfalls eine Warnung. Damit ist dieser Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise &amp;lt;tt&amp;gt;if (23 &amp;amp;#61;&amp;amp;#61; a)&amp;lt;/tt&amp;gt;. Wenn man dort anstatt des Vergleichsoperators '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;amp;#61;&amp;lt;/tt&amp;gt;' den Zuweisungsoperator '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;lt;/tt&amp;gt;' verwendet, spuckt der Compiler sehr wohl einen Fehler aus! Ist die Zuweisung jedoch erwünscht und eine Compiler-Warnung lästig, dann wählt man eine Schreibweise wie &amp;lt;tt&amp;gt;if ((a &amp;amp;#61; b))&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;if (a &amp;amp;#61; b, a)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist zu schreiben &amp;lt;tt&amp;gt;if (Bedingung);&amp;lt;/tt&amp;gt; Richtig muss es heissen &amp;quot;&amp;lt;tt&amp;gt;if(Bedingung)&amp;lt;/tt&amp;gt;&amp;quot; Das Semikolon im ersten Fall ist eine leere Anweisung, die im if-Falle ausgeführt wird &amp;amp;ndash; sie bleibt also ohne Resultet. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt; ein auf das Semikolon folgende Anweisung die eigentlich zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören soll wird immer ausgeführt, die sie nicht mehr zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; dazu gehört.&lt;br /&gt;
}}&lt;br /&gt;
Bei verschachtelten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Konstrukten gehört ein &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zu letzten &amp;quot;freien&amp;quot; &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;. Soll in einer &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Folge das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zum ersten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören, dann ist das so zu hinzuschreiben:&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Ohne die geschweiften Klammern um das zweite &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehörte das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; dort hinzu.&lt;br /&gt;
&lt;br /&gt;
==switch-Anweisung==&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
&lt;br /&gt;
 switch ({{Ausdruck|}}) &lt;br /&gt;
 {&lt;br /&gt;
     case konstante1:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
    &lt;br /&gt;
     case konstante2:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 &lt;br /&gt;
     {{comment|weitere case-Marken}}&lt;br /&gt;
 &lt;br /&gt;
     default:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 } {{comment|Ende von switch}} &lt;br /&gt;
&lt;br /&gt;
Der Ausdruck muss ein skalarer Typ sein, er wird in die nächste ganze Zahl gewandelt und mit den Werten hinter den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Marken verglichen. Bei einer Übereinstimmung werden alle Befehle ab dem zutreffenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; ausgeführt. Stimmt der Ausdruck mit keinem der Werte überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt falls vorhanden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der nachfolgenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;- und des &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitts werden ausgeführt, wenn die Anweisungen des &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitts nicht mit dem Befehl &amp;lt;tt&amp;gt;break;&amp;lt;/tt&amp;gt; beendet werden!&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es dürfen beliebig viele &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitte angegeben werden, pro Vergleichswert jedoch nur einer.&lt;br /&gt;
Der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ist optional. Die Reihenfolge, in der &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt; angegeben werden, ist unerheblich.&lt;br /&gt;
&lt;br /&gt;
==Schleifen==&lt;br /&gt;
Um Anweisungen mehrmals hintereinander auszuführen, benötigt man Schleifen. Diese führen Anweisungen aus, bis oder solange Bedingungen erfüllt sind.&amp;lt;br&amp;gt; &lt;br /&gt;
Wichtig ist also, ob die Bedingung '''vor''' oder '''nach''' den Schleifen-Anweisungen geprüft wird. &lt;br /&gt;
&lt;br /&gt;
===while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 while ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Die while-Schleife wird solange durchlaufen, wie die Bedingung erfüllt ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Die Anweisung kann natürlich auch ein Block sein, der aus mehreren Deklarationen und Anweisungen besteht. &lt;br /&gt;
&lt;br /&gt;
 int zahl1 = 0;&lt;br /&gt;
 int zahl2 = 1;&lt;br /&gt;
 &lt;br /&gt;
 while (zahl1 &amp;lt; 3)&lt;br /&gt;
 {&lt;br /&gt;
    zahl1 = zahl1 + 1;&lt;br /&gt;
    zahl2 = zahl2 * 2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife drei mal durchlaufen. Zu Beginn des vierten Durchlaufs ist die Bedingung nicht mehr erfüllt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
&lt;br /&gt;
===do-while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
Die do-while-Schleife wird auf jeden Fall einmal durchlaufen und dann solange wiederholt, wie die Bedingung erfüllt ist.&lt;br /&gt;
 int i = 2;&lt;br /&gt;
 &lt;br /&gt;
 do &lt;br /&gt;
 {&lt;br /&gt;
     i = i*i;   {{comment|i quadrieren}}&lt;br /&gt;
     printf (&amp;quot;i = %d\n&amp;quot;, i);&lt;br /&gt;
 }&lt;br /&gt;
 while (i &amp;lt; 20);&lt;br /&gt;
&lt;br /&gt;
Die Schleife wird durchlaufen und wiederholt, solange &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; kleiner als 20 ist. Es werden also nacheinander die Werte 2, 4 und 16 ausgegeben. Nach der Schleife hat&amp;amp;nbsp;&amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; den Wert 256.&lt;br /&gt;
&lt;br /&gt;
===for-Schleife===&lt;br /&gt;
'''Syntax:''' &lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Bei den Ausdrücken wird es sich um einen Ausdrücke mit Nebeneffekt handeln wie etwa &amp;lt;tt&amp;gt;i=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;i=i+2&amp;lt;/tt&amp;gt;. Es werden folgende Aktionen ausgeführt:&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# falls die Bedingung wahr ist, dann führe &amp;lt;tt&amp;gt;Anweisung&amp;lt;/tt&amp;gt; aus.&lt;br /&gt;
# falls die Bedingung unwahr ist, dann sprinte zu 7 (Ende).&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# gehe zu 2&lt;br /&gt;
# nächste Anweisung nach der for-Schleife&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int lauf, summe;&lt;br /&gt;
 &lt;br /&gt;
 for (lauf=1, summe=0; lauf &amp;lt;= 10; lauf += 2) &lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel ist &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; ein [[#Komma-Operator|Komma-Ausdruck]], der zwei Anweisungen kombiniert und daher sogar zwei Nebeneffente hat: er setzt &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;1 und &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;0.&lt;br /&gt;
&lt;br /&gt;
Das Äquivalent als while-Schleife:&lt;br /&gt;
&lt;br /&gt;
 int lauf  = 1;                 {{comment|Anfangswerte}}&lt;br /&gt;
 int summe = 0;&lt;br /&gt;
 &lt;br /&gt;
 while (lauf &amp;lt;= 10)             {{comment|Bedingung}}&lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
    lauf  += 2;                 {{comment|Inkrement}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; in jedem Schleifendurchlauf um die Laufvariable &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; erhöht. Da &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nacheinander die ungeraden Werte von&amp;amp;nbsp;1 bis&amp;amp;nbsp;10 annimmt, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von&amp;amp;nbsp;1 bis kleinergleich 10 gespeichert, also der Wert&amp;amp;nbsp;25. &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; hat nach der Schleife den Wert&amp;amp;nbsp;11.&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf = 1&amp;lt;/tt&amp;gt; bedeutet, dass der Variablen &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; vor dem ersten Schleifendurchlauf der Wert&amp;amp;nbsp;1 zugewiesen wird. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf &amp;lt;= 10&amp;lt;/tt&amp;gt; ist die Schleifenbedingung; ist sie nicht erfüllt, wird die Schleife beendet. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf += 2&amp;lt;/tt&amp;gt; bedeutet, dass &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nach jedem Durchlauf um&amp;amp;nbsp;2 erhöht wird.&lt;br /&gt;
&lt;br /&gt;
===continue-Anweisung===&lt;br /&gt;
Innerhalb einer Schleife darf die &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die nachfolgenden Anweisungen übersprungen werden und mit dem nächsten Schleifendurchlauf fortgesetzt wird &amp;amp;ndash; vorausgesetzt die Schleifenbedingung ist noch erfüllt. Ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; etc. stehen, wenn dieses innerhalb einer Schleife steht.&lt;br /&gt;
&lt;br /&gt;
==break-Anweisung==&lt;br /&gt;
Innerhalb einer Schleife oder eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; darf die &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die Schleifen-/Switch-Anweisung sofort verlassen wird und das Programm dahinter weiter macht. Bei mehrfach geschachtelten Schleifen wird nur die innere verlassen. Ein &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; stehen, wenn dieses innerhalb einer Schleife/Switch-Anweisung steht.&lt;br /&gt;
&lt;br /&gt;
==goto-Anweisung==&lt;br /&gt;
&lt;br /&gt;
Innerhalb ein und derselben Funktion kann mit &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; an eine andere Stelle gesprungen werden. Dazu gibt man hinter dem &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einen Bezeichner an, der dadurch als Label fungiert:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 goto {{Bezeichner}};&lt;br /&gt;
Die Bezeichner selbst steht irgendwo in der Funktion und wird dadurch zur Sprungmarke (Label), daß er von einem Doppelpunkt (und mindestens einer C-Anweisung, die auch leer sein darf) gefolgt wird.&lt;br /&gt;
&lt;br /&gt;
Das Beispiel durchsucht das 2-dimensionale &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array &amp;lt;tt&amp;gt;feld&amp;lt;/tt&amp;gt; mit den &amp;lt;tt&amp;gt;SIZE_X &amp;amp;times; SIZE_Y&amp;lt;/tt&amp;gt; Werten nach dem Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;. Wird er gefunden, dann wird die 2-fach geschachtelte Suchschleife verlassen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int x, y;&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y; y++)&lt;br /&gt;
       if (feld[x][y] == 0)&lt;br /&gt;
          goto done;&lt;br /&gt;
 {{Label|done:}};&lt;br /&gt;
&lt;br /&gt;
Der folgende Code hat die gleiche Funktion, arbeitet jedoch ohne &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int x, y;&lt;br /&gt;
 int found = 0; {{comment|FALSE}}&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X &amp;amp;&amp;amp; !found; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y &amp;amp;&amp;amp; !found; y++)&lt;br /&gt;
       found = (0 == feld[x][y]);&lt;br /&gt;
Der Nachteil der &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-losen Variante ist, daß man eine Variable, die merkt, ob das Suchziel gefunden wurde, mitschleppen und in ''jedem'' Schleifendurchlauf abtesten muss. Dies bedeutet einen höheren Programmier- und Laufzeitaufwand und ist nicht so klar formuliert wie das &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-Beispiel.&lt;br /&gt;
&lt;br /&gt;
Gleichwohl sei angemerkt, daß die Verwendung von &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einem gewissen Dogmatismus unterliegt, der sich wie folgt subsummieren liesse:&lt;br /&gt;
:''goto ist böse und sollte keinesfalls verwendet werden! Wer es dennoch tut, offenbart dadurch seinen schlechten Geschmach sowie mangelhafte C-Kenntnis.'' &amp;lt;div align=&amp;quot;right&amp;quot;&amp;gt;http://www.roboternetz.de/phpBB2/images/smiles/icon_wink.gif&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Funktionen=&lt;br /&gt;
Stellen Dir vor, Du hast eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben &amp;amp;ndash; was Dich Zeit beim Erstellen des Programms und Speicherplatz im ausführbaren Programm kostet &amp;amp;ndash; kannst Du den Code-Abschnitt in eine Funktion schreiben und diese von jeder Stelle des Programms aus verwenden. Die Hauptgründe, um Funktionen zu verwenden, sind:&lt;br /&gt;
;Wiederverwendung von Code: Mehrfach verwendete Codestücke müssen nicht mehrfach implementiert werden. Oft unterscheiden sich die Codesequenzen nur in Kleinigkeiten, die man der Funktion über Parameter mitteilen kann.&lt;br /&gt;
;Übersichtlichkeit: Ein gut gegliedertes C-Programm implementiert klar umrissene Aufgaben in einer Funktion, auch wenn diese Funktion nur einmal im Code aufgerufen wird! Dadurch bleibt der Code um die Aufrufstelle besser verständlich, und man kann auf verschiedenen &amp;quot;Ebenen&amp;quot; denken. Eine Funktion wie &amp;quot;Datei öffnen&amp;quot; kann recht komplex sein. Auf höherer Ebene interessieren die Innereien nicht mehr, man möchte sich um andere Dinge kümmern und will den Code an der Stelle garnicht sehen...&lt;br /&gt;
;Rekursive Funktionen: Eine Funktion kann sich auch selbst aufrufen. In dem Falle nennt man die Funktion ''rekursiv''. Zwar lässt sich das, was eine rekursive Funktion tut, auch mit anderen Mitteln formulieren, die keine rekursiven Funktionen brauchen, aber oft ist der rekursive Weg knackiger und klarer formulierbar als eine nicht-rekursiven Ansatz, auch wenn es etwas mehr Resourcen verbraucht.&lt;br /&gt;
;Modulare Programmierung: Funktionen können anhand ihres Aufgabenbereichs auf verschiedene C-Quellen &amp;amp;ndash; sogenannte ''Module'' &amp;amp;ndash; verteilt werden. Funktionen, die etwas mit dem USB-Bus anstellen, werden in einem anderen Modul sein als mathematische Funktionen. Dies erhöht die Übersichtlichkeit und vereinfacht die Entwicklung im Team.&lt;br /&gt;
;Bibliotheken: Standard-Funktionen wie das hier oft auftauchende &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; sind in Bibliotheken gespeichert. Wenn das eigene Programm übersetzt wird, dann müssen nicht mehr alle Standard-Funktionen übersetzt werden, sondern werden nur noch aus der Bibliothek gelesen und ihr Code zum Programm dazugelinkt. Die Bibliotheks-Funktionen wurden schon zu einem früheren Zeitpunkt compiliert und liegen in dieser compilerten Form in der Bibliothek. Das spart mächtig Entwicklungszeit. Man kann auch selbst solche Bibliotheken erstellen und in diversen Projekten wiederverwenden.&lt;br /&gt;
;Generische Programmierung: In C ist es möglich, einer Funktion eine andere Funktion zu übergeben. (Damit ist nicht gemeint, ihr deren ''Rückgabewert'' zu übergeben (was auch ginge), sondern ''die Funktion selbst'' wird als Parameter übergeben und kann aufgerufen werden.) Ein typisches Beispiel dafür sind Sortieralgorithmen. Einem Sortieralgorithmus kann es egal sein, ''was'' er sortiert. Er muss lediglich wissen, ''wie'' er das Zeug zu sortieren hat: aufsteigend, absteigend, als Zahl, in lexikographischer Ordnung, nach der Quersumme, Körper nach Oberfläche, Durchmesser, Gewicht oder Volumen... Diese Vergleichsfunktion, die für zwei Objekte entscheidet, welches davon &amp;quot;kleiner&amp;quot; ist, kann man dem Sortierer übergeben. Will er zwei Werte vergleichen, dann muss er nur die Vergleichsfunktion aufrufen, ohne zu wissen, was diese tut. Damit kann der Sortieralgorithmus unanhängig von den Objekten gehalten werden, mit denen er hantieren soll.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Definition==&lt;br /&gt;
&lt;br /&gt;
In der ''Definition'' der Funktion wird gesagt, welche Werte sie liefern kann, wie sie heisst (Bezeichner) und wieviele und welche Parameter sie hat. Danach folgt ihre Implementierung:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}} ({{Parameterliste}})&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 &lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
Für Funktionen, die keinen Wert zurückliefern, gibt es den speziellen Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der besagt, daß die Funktion nichts zurückgibt. Die einfachste denkbare Funktion ist eine solch void-Funktion. Sie bekommt keine Parameter, gibt nicht zurück und ihr Body ist leer:&lt;br /&gt;
 void dummy()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==return-Anweisung==&lt;br /&gt;
An jeder Stelle des Programmflusses einer Funktion kann diese mit &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; beendet werden.&lt;br /&gt;
&lt;br /&gt;
'''bei void-Funktionen:'''&lt;br /&gt;
 return;&lt;br /&gt;
'''Funktionen mit Rückgabe-Wert:'''&lt;br /&gt;
 return {{Ausdruck|}};&lt;br /&gt;
Die zweite Variante gibt an, welcher Wert zurückgegeben wird.&lt;br /&gt;
 int main (int argc, char * argv[])&lt;br /&gt;
 {&lt;br /&gt;
    if (argc &amp;lt; 2)&lt;br /&gt;
       return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
Falls die letzte Anweisung einer void-Funktion ein &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; ist, kann es auch weggelassen werden wie oben bei der Funktion &amp;lt;tt&amp;gt;dummy&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Aufruf==&lt;br /&gt;
Um die Funktion aufzurufen gibt man ihren Namen an, gefolgt von den durch Komma getrennten Argumenten in runden Klammern wie im Beispiel unten das&lt;br /&gt;
 quadrat (5) &lt;br /&gt;
Da &amp;lt;tt&amp;gt;quadrat&amp;lt;/tt&amp;gt; einen Wert liefert, kann man damit weiter rechnen wie mit einem normalen Ausdruck:&lt;br /&gt;
 if (quadrat (a) + quadrat (b) == quadrat (c))&lt;br /&gt;
    c = quadrat (quadrat (a)); {{comment|c &amp;amp;#61; a hoch 4}}&lt;br /&gt;
&lt;br /&gt;
;Ein Hinweis am Rande: &lt;br /&gt;
Der Name einer Funktion ohne die beiden runden Klammern ist der Pointer/Zeiger auf ihren Anfang.&lt;br /&gt;
Damit kann ein Funktionsname überall dort verwendet werden, wo Pointer/Zeiger &lt;br /&gt;
zulässig sind. Insbesondere kann er als Argument einer weiteren Funktion dienen. &lt;br /&gt;
&lt;br /&gt;
'''Quelle:'''&lt;br /&gt;
W. Alex, Einführung in C/C++&lt;br /&gt;
&lt;br /&gt;
==Rekursive Funktionen==&lt;br /&gt;
Eine Funktion die sich selbst &amp;amp;ndash; möglicheweise auch über andere Zwischenfunktionen &amp;amp;ndash; wieder selbst aufruft, wird als ''rekursive Funktion'' bezeichnet. In der Definition ist nichts besonderes zu beachten. Ist die Verschachtelungstiefe im laufenden Programm zu tief, dann gibt das natürlich Probleme, aber das gilt bei tief verschachtelten 'normalen' Funktionen abenso...&lt;br /&gt;
&lt;br /&gt;
Das Beispiel berechnet den Größten Gemeinsamen Teiler zweier Zahlen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int ggT (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
     if (0 == a)&lt;br /&gt;
        return b;&lt;br /&gt;
 &lt;br /&gt;
    return ggT (b % a, a);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Ein komplettes kleines Programm:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int quadrat (int param1)&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  zahl = param1 * param1;&lt;br /&gt;
  return zahl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl, ergebnis;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Bitte Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = quadrat (zahl);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, zahl, ergebnis);&lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, 5, quadrat (5));&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur ausserhalb von Blöcken. Geschachtelte Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen beim Aufruf die Klammern angeben werden:&lt;br /&gt;
 dummy();&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Prototypen==&lt;br /&gt;
Wie oben erwähnt, kann ein Unterprogramm an jeder beliebigen Stelle im Programm stehen. Damit ist jedoch eine Bedingung verknüpft: Das Unterprogramm muß in der Datei oberhalb des ersten Aufrufes definiert worden sein. Wenn Sie ein Unterprogramm in Zeile 10 zum ersten mal aufrufen, müssen Sie die Deklaration davor erledigt haben. Verstanden?&lt;br /&gt;
Um dies zu erreichen, gibt es zwei Möglichkeiten: &lt;br /&gt;
&lt;br /&gt;
Entweder Sie schreiben alle Unterprogramme vor &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; in die Datei. Dies muß jedoch wiederum so geschehen, dass Funktionen zum Zeitpunkt ihres Aufrufes bereits bekannt sind! &lt;br /&gt;
Wo dies nicht möglich ist (z.B. sich gegenseitig aufrufende Unterprogramme), oder wenn Sie das stört, müssen Sie Prototypen verwenden. &lt;br /&gt;
Wie definiert man nun Prototypen? Sie kopieren einfach die erste Zeile des Unterprogrammes (z.B. &amp;quot;&amp;lt;tt&amp;gt;void ausgeben (int zahl)&amp;lt;/tt&amp;gt;&amp;quot;), fügen einen Strichpunkt&amp;amp;nbsp;&amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;an und fügen es an einer geeigneten Stelle ein (so, dass alle Aufrufe später in der Datei kommen). &lt;br /&gt;
Solche Definitionen stehen gewöhnlich am Anfang der Quelldatei oder in einer Header-Datei, die eingebunden wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl);  /* Der Prototyp */&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
   ausgeben (12);&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl)   /* Die eigentliche Prozedur */&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Ausgabe: %d\n&amp;quot;, zahl);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Parameterübergabe==&lt;br /&gt;
&lt;br /&gt;
Alle Werte, die an Prozeduren und Funktionen übergeben werden, werden grundsätzlich '''kopiert'''.&lt;br /&gt;
Das hat folgende Auswirkungen:&lt;br /&gt;
&lt;br /&gt;
# Änderungen an einem Parameter in einer Funktion erscheinen ''nicht'' beim Aufrufer!&lt;br /&gt;
# Möchte man, dass eine Funktion einen Wert trotzdem dauerhaft ändern soll, so muss die Adresse des Wertes via [[#Zeiger|Zeiger]] übergeben werden.&lt;br /&gt;
# Werden [[#Strukturen|Strukturen]] übergeben, so wird von ihnen eine Kopie erstellt, was bei großen Strukturen viel Zeit und Arbeitsspeicher kostet. Deshalb wird häufig nur die Adresse von Strukturen übergeben, da die Adresse viel schneller und platzsparender als die Struktur selbst kopiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele:'''&lt;br /&gt;
 void erhoehe (int x)&lt;br /&gt;
 {&lt;br /&gt;
    x = x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe(a);&lt;br /&gt;
    {{comment|a ist immer noch 0}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Beim Aufruf von &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; wird eine Kopie des Wertes von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; (im Beispiel also 0) erstellt und der Prozedur als Parameter &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; übergeben. Weil dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat dies keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|erhoehe den Wert an der Adresse x um eins}}&lt;br /&gt;
    *x = *x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe (&amp;amp;a);&lt;br /&gt;
    {{comment|a ist jetzt 1}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Jetzt wird im Hauptprogramm mittels [[#Adress-Operator und Dereferenzierung|Adress-Operator]] &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; die Speicheradresse von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; bestimmt. Dann wird eine ''Kopie der Adresse'' an das Unterprogramm &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; übergeben. Jetzt kennt das Unterprogramm die&lt;br /&gt;
Adresse des Originals &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und kann direkt mit dem Inhalts-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&lt;br /&gt;
'''Besonderheit bei Feldern'''&lt;br /&gt;
&lt;br /&gt;
Bei der Übergabe von [[#Felder|Feldern]] gibt es eine Besonderheit. Schreibt man nämlich den Namen eines Feldes, so ist das nichts anderes als die '''Speicheradresse des ersten Elements'''.&lt;br /&gt;
Bei der Übergabe eines Feldes wird also eine Kopie der Startadresse übergeben. Somit kann das Unterprogramm auf den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 void erhoehe (int x[])&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
   int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
   erhoehe (a);&lt;br /&gt;
   {{comment|a hat jetzt folgenden Inhalte: 11, 23, 35}}&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Dass die Übergabe einer Adresse erfolgt, sieht man an folgendem Beispiel, das von der Funktionsweise '''absolut identisch''' mit dem vorhergehenden ist:&lt;br /&gt;
&lt;br /&gt;
 {{comment|Bei Parametern gibt es keinen Unterschied zwischen Zeiger und Feld}}&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
    int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
    erhoehe (a);&lt;br /&gt;
 &lt;br /&gt;
    {{comment|a hat jetzt folgenden Inhalt: 11, 23, 35}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
Die Länge des Feldes wird nicht automatisch übergeben. Dafür ist ggf. ein zusätzlicher Parameter notwendig.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Variable Argumentanzahl==&lt;br /&gt;
== Funktionen indirekt aufrufen ==&lt;br /&gt;
Siehe [[#Zeiger auf Funktionen|Zeiger auf Funktionen]]&lt;br /&gt;
&lt;br /&gt;
=Zeiger II=&lt;br /&gt;
&lt;br /&gt;
Zeiger haben wir bereits weiter oben kennen gelernt. Zeiger sind ein zentrales Konzept in C und sollen hier etwas eingehender behandelt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger-Arithmetik==&lt;br /&gt;
In C kann man den Wert eines Zeigers verändern. Betrachten wir dazu die Funktion &amp;lt;tt&amp;gt;suche_0&amp;lt;/tt&amp;gt;, die einen Zeiger auf einen &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; erhält. Die Funktion soll ab der gegebenen Adresse nach dem ersten long-Wert suchen, der 0 ist, und dessen Adresse zurückgeben:&lt;br /&gt;
 long * suche_0 (long * addr)&lt;br /&gt;
 {&lt;br /&gt;
    while (*addr != 0)&lt;br /&gt;
       addr = addr + 1;&lt;br /&gt;
 &lt;br /&gt;
    return addr;&lt;br /&gt;
 }&lt;br /&gt;
In der Bedingung der while-Schleife wird der Inhalt an der Speicherstelle &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf 0 getestet. Ist der Wert 0, dann wird die Schleife beendet und die Adresse zurückgeliefert. Ist der Wert ungleich 0, dann wird &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf den nächste long gesetzt, &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; also um 4 Bytes weitergezählt. &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ist ja ein Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, und ein &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; ist 4 Bytes lang.&lt;br /&gt;
&lt;br /&gt;
Die Bedeutung von&lt;br /&gt;
 address + n&lt;br /&gt;
ist also, die Adresse um das &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;-fache der Größe des Typs, auf den &amp;lt;tt&amp;gt;address&amp;lt;/tt&amp;gt; zeigt, zu erhöhen. Dabei ist &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; eine ganze Zahl und darf auch negativ sein.&lt;br /&gt;
&lt;br /&gt;
Hier noch ein Beispiel einer Funktion, die nach einer Person mit einer bestimmten ID sucht (für die Definition von &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; siehe [[#Strukturen|Strukturen]]). Der Parameter &amp;lt;tt&amp;gt;person&amp;lt;/tt&amp;gt; ist dabei ein Array von Strukturen. Eine Person mit der gesuchten ID muss existieren, ansonsten hat die Suchfunktion kein definiertes Verhalten.&lt;br /&gt;
 {{comment|Sucht nach einer Person mit der ID person_id}}&lt;br /&gt;
 struct Person * &lt;br /&gt;
 suche_person_id (struct Person * person, int person_id)&lt;br /&gt;
 {&lt;br /&gt;
    while (person-&amp;gt;id != person_id)&lt;br /&gt;
       person++;&lt;br /&gt;
 &lt;br /&gt;
    return person;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:1em; padding:1em; border:solid 2px #FF0040;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- Vorlage:FarbigerRahmen funzt hier net --&amp;gt;&lt;br /&gt;
Beachte, daß es nicht sinnvoll ist, zwei Zeiger zu addieren oder zu multiplizieren. Ausserdem ist das &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt; der Zeiger-Arithmetik nicht kommutativ. Eine Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, der an Adresse 1 im Speicher zeigt, wird man schreiben als&lt;br /&gt;
 (long *) 1&lt;br /&gt;
Addiert man darauf eine ganze Zahl, dann haben die entstehenden Ausdrücke unterschiedliche Werte:&lt;br /&gt;
 (long *) 1 + 2    {{comment|zeigt zu Adresse 9}}&lt;br /&gt;
 (long *) 2 + 1    {{comment|zeigt zu Adresse 6}}&lt;br /&gt;
 (long *) (1 + 2)  {{comment|zeigt zu Adresse 3}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==void-Pointer==&lt;br /&gt;
Eine besondere Art von Zeiger ist der void-Pointer&lt;br /&gt;
 void * addr;&lt;br /&gt;
Ein void-Pointer ist ein &amp;quot;Zeiger auf irgendwas&amp;quot;, dementsprechend kann er nicht dereferenziert werden, Anwenden von &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf einen solchen Zeiger gibt also einen Fehler. Ausserdem ist es nicht möglich, mit einem void-Pointer Zeigerarithmetik zu machen, weil er nicht auf eine definierte Art von Objekt zeigt. Der Vorteil eines void-Pointers ist, daß er jede Art von Zeiger aufnehmen kann.&lt;br /&gt;
&lt;br /&gt;
Dazu betrachten wir die Funktion &amp;lt;tt&amp;gt;send_buf&amp;lt;/tt&amp;gt;, die eine Adresse erhält und ab dieser Adresse &amp;lt;tt&amp;gt;num&amp;lt;/tt&amp;gt; Bytes versenden soll. Wir könnten die Funktion so schreiben:&lt;br /&gt;
 void send_buf (unsigned char * buf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   ...&lt;br /&gt;
Das ist jedoch hässlich, wenn wir damit etwas anderes verschicken wollen als &amp;lt;tt&amp;gt; unsigned char&amp;lt;/tt&amp;gt;, etwa eine Struktur wie &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; (vom Typ &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;):&lt;br /&gt;
 send_buf ((unsigned char*) &amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
Ohne den Cast der Adresse von &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; zu einem Zeiger auf &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt; bekommt man eine Warnung oder gar einen Compilerfehler.&lt;br /&gt;
Dieses Zeiger gecaste ist mühsam und hässlich, es muss bei jedem Aufruf der Funktion explizit hingeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Besser ist es, den ersten Parameter der Funktion als void-Pointer zu definieren und den Cast in der Funktion zu machen:&lt;br /&gt;
 void send_buf (void * vbuf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   unsigned char *buf = (unsigned char*) vbuf;&lt;br /&gt;
   ...&lt;br /&gt;
Durch den Cast in der Funktion kann auf den Inhalt des Zeigers zugegriffen werden. Man muss nur festlegen, ''wie'' man zugreifen will, nämlich als &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Der Aufruf kann jetzt ohne Pointer-Cast erfolgen: &lt;br /&gt;
 send_buf (&amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
&lt;br /&gt;
==Null-Pointer==&lt;br /&gt;
==Zeiger als Parameter==&lt;br /&gt;
Wenn Sie ein Unterprogramm aufrufen, können Sie diesem Parameter übergeben, aber keine Werte zurückgekommen (außer den Funktionswert bei Funktionen). Dies hat einen guten Grund: beim Aufruf werden nicht die aufgerufenen Parameter benutzt, sondern es werden deren Werte in neue Variablen kopiert. Diese Variablen werden am Ende des Unterprogrammes &amp;quot;zerstört&amp;quot;, ohne ihre Werte an die aufrufenden Parameter zu übergeben. Jede Veränderung eines Parameters hat daher keine Auswirkung auf den Parameter.&lt;br /&gt;
&lt;br /&gt;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der C-Compiler legt dann immer noch Kopien an. In dieser Kopie steht aber kein Wert, sondern die Adresse einer Varaiblen. Und auf diese können Sie dann zugreifen. Denken Sie nur an &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; &amp;amp;ndash; da übergeben Sie ja auch die Adresse einer Variablen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void erhoehe (int *zeiger)&lt;br /&gt;
{&lt;br /&gt;
  *zeiger = 1 + *zeiger;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  erhoehe (&amp;amp;zahl);&lt;br /&gt;
  printf (&amp;quot;\nDie erhoehte Zahl lautet: %d\n&amp;quot;, zahl);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Zeiger auf Funktionen==&lt;br /&gt;
&lt;br /&gt;
Stell dir vor, du willst einen Sortieralgorithmus wie Bubble-Sort oder Quick-Sort oder wie sie alle heissen implementieren. Für den Sortieralgorithmus ist eigentlich egal, ''was'' er zu sortieren hat. Ihm ist es egal, ob er Zahlen aufwärts sortieren soll oder Strings in lexikographischer Reihenfolge, ob Objekte nach Größe oder Gewicht, Personen nach Alter oder Adressen nach Postleitzahl. Das einzige, was der Algorithmus wissen muss, ist ''wie'' er zwei Objekte zu vergleichen hat und wann eines davon &amp;quot;kleiner&amp;quot; (im Sinne der Ordnung, nach der sortiert werden soll) ist. &lt;br /&gt;
&lt;br /&gt;
Eine einfache Sortierfunktion, die nur zwei Zahlen sortiert, könnte man also so schreiben: &lt;br /&gt;
 {{comment|Sortiert ein Array von 2 int-Zeigern nach den Inhalten &lt;br /&gt;
  * an den Zeiger-Adressen}}&lt;br /&gt;
 void sort2_a (int * p[])&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Inhalte vergleichen...}}&lt;br /&gt;
    if (*p[0] &amp;gt; *p[1])&lt;br /&gt;
    {&lt;br /&gt;
       {{comment|... und ggf. Dreieckstausch der 2 Zeiger}}&lt;br /&gt;
       int * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Die Funktion bekommt ein Array der Länge&amp;amp;nbsp;2. In diesem Array stehen Zeiger auf die zu sortierenden Zahlen. Ein Array mit Zeigern zu verwenden und nicht ein Array von &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; scheint recht umständlich, und das ist es hier auch. Aber stell dir vor, du willst Strukturen wie &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; sortieren. Das Tauschen zweier Strukturen würde bedeuten, ihre kompletten Inhalte umzukopieren! Das wäre sehr aufwändig. Viel einfacher ist das Kopieren, wenn nur die Adressen zu kopieren sind.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; könnte dann so aussehen:&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void sortiere (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|p[] enthält 2 int-Zeiger: die Adressen von a und b}}&lt;br /&gt;
    int * p[2];&lt;br /&gt;
    p[0] = &amp;amp;a; &lt;br /&gt;
    p[1] = &amp;amp;b; &lt;br /&gt;
 &lt;br /&gt;
    {{comment|Sortiere die Zeiger}} &lt;br /&gt;
    sort2_a (p);&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Sortiert: %d, %d\n&amp;quot;, *p[0], *p[1]);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Für den nächsten Schritt überlegen wir uns, daß das Array in &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; ebensogut void-Pointer enthalten kann. Die einzige Stelle, an der wir auf die endgültigen int-Objekte zugreifen, ist der Vergleich. Diesen Vergleich lagern wir in die Funktion &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; aus:&lt;br /&gt;
 {{comment|Bekommt zwei void-Pointer und vergleicht die Inhalte.&lt;br /&gt;
  * Liefert 0 bei Gleichheit,&lt;br /&gt;
  * -1 wenn der erste Wert kleiner ist als der zweite und&lt;br /&gt;
  * 1  wenn der erste Wert größer ist als der zweite}}&lt;br /&gt;
 int compare_int (void * p0, void * p1)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Um über die Zeiger zugreifen zu können müssen wir diese&lt;br /&gt;
     * erst zu int-Zeigern casten}}&lt;br /&gt;
    int a0 = * (int*) p0;&lt;br /&gt;
    int a1 = * (int*) p1;&lt;br /&gt;
 &lt;br /&gt;
    if (a0 &amp;gt; a1)  return  1;&lt;br /&gt;
    if (a0 &amp;lt; a1)  return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void sort2_b (void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare_int (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Ein Aufruf von &amp;lt;tt&amp;gt;sort2_b&amp;lt;/tt&amp;gt; sieht dann genauso aus wie ein Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt definieren wir uns den neuen Datentyp &amp;lt;tt&amp;gt;comparator_t&amp;lt;/tt&amp;gt;. Dieser ist ein Zeiger auf eine Funktion, die zwei void-Pointer erhält und einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; zurückliefert, also analog arbeitet zu &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; von oben. &lt;br /&gt;
&lt;br /&gt;
Unsere Sortierfunktion bekommt nun neben dem zu sortierenden Zeiger-Array auch eine Vergleichsfunktion &amp;lt;tt&amp;gt;compare&amp;lt;/tt&amp;gt; mitgeliefert, die sie aufruft, wenn sie zwei Objekte vergleichen will&lt;br /&gt;
 {{comment|comparator_t sind Zeiger auf Funktionen, die 2 void-Pointer&lt;br /&gt;
  * erhalten und einen int zurückliefern}}&lt;br /&gt;
 typedef int (*comparator_t) (void*, void*);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Der Sortierer bekommt einen Funktionszeiger auf den Vergleicher.&lt;br /&gt;
  * Der Aufruf vom compare geht so als wäre es eine &amp;quot;normale&amp;quot; Funktion&lt;br /&gt;
  * (ist es im Endeffekt ja auch)}}&lt;br /&gt;
 void sort2_c (comparator_t compare, void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Bei einem Aufruf von &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; muss man dann einen Komparator mit angeben. In einem Beispiel analog zu &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; von oben ist das:&lt;br /&gt;
 sort2_c (compare_int, p);&lt;br /&gt;
Um zwei Strings lexikographisch zu sortieren nehmen wie die Standard-Funktion &amp;lt;tt&amp;gt;strcmp&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void foo()&lt;br /&gt;
 {&lt;br /&gt;
    char * worte[] = { &amp;quot;Wort1&amp;quot;, &amp;quot;Wort2&amp;quot; };&lt;br /&gt;
 &lt;br /&gt;
    sort2_c ((comparator_t) strcmp, (void**) worte);&lt;br /&gt;
 }&lt;br /&gt;
Die Casts sind hier erforderlich. Alternativ könnte man &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; mit reinen void-Pointern versorgen und diese dann dort umcasten.&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
&lt;br /&gt;
Die Syntax zur Definition/Deklaration von Funktionszeigern ist etwas verzwackt. Zur Verdeutlichung ein paar Beispiele. Dabei legt das linke &amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt; jeweils den Return-Typ fest.&lt;br /&gt;
 {{comment|definiert einen neuen Funktionszeiger-Typ}}&lt;br /&gt;
 typedef {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert einen Funktionszeiger}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert ein Array von Funktionszeigern (mit Initializer)}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}[]) ({{type}}, {{type}}, ...) = { wert1, wert2, ... };&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer}}&lt;br /&gt;
 ({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer und ruft die Funktion auf}}&lt;br /&gt;
 (({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}) (arg1, arg2, ...);&lt;br /&gt;
&lt;br /&gt;
=Standard-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==String-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===strcpy===&lt;br /&gt;
Bei vielen Compilern können sie einem String nicht direkt einen Wert (Text) zuweisen. Dazu müssen Sie dann die Prozedur strcpy() benutzen. Diese erwartet als ersten Parameter den Namen einer String-Variablen (ohne eckige Klammern) und als zweiten Parameter den eines (anderen) Strings. Letzterer kann auch ein in doppelten Hochkommas (&amp;quot;) eingeschlossener Text sein. Die Funktion fügt am Ende automatisch ein 0-Zeichen ein. Um diese Funktion nutzen zu können, müssen Sie die Datei string.h includieren! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri1[21], eingabe[21];&lt;br /&gt;
&lt;br /&gt;
  strcpy (stri1, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Der 1. String: %s\n&amp;quot;, stri1);&lt;br /&gt;
  printf (&amp;quot;Bitte geben Sie maximal 20 Zeichen ein: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%s&amp;quot;, eingabe);&lt;br /&gt;
  strcpy (stri1, eingabe);&lt;br /&gt;
  printf (&amp;quot;\n%s = %s&amp;quot;, stri1, eingabe);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis:''' &lt;br /&gt;
Da ein String, wie jedes Feld, eigentlich ein Zeiger ist, dürfen Sie kein &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; bei &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; angeben!&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
Es werden zwei gleich große Strings definiert: &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;eingabe&amp;lt;/tt&amp;gt;, mit je 20 &amp;quot;nutzbaren&amp;quot; Zeichen. &lt;br /&gt;
In &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; wird die Zeichenkette &amp;lt;tt&amp;gt;&amp;quot;hallo&amp;quot;&amp;lt;/tt&amp;gt; hineinkopiert. Das 0-Zeichen am Ende wird automatisch angefügt. &lt;br /&gt;
Der String wird ausgegeben. Als neues &amp;quot;Sonderzeichen&amp;quot; kommt &amp;lt;tt&amp;gt;%s&amp;lt;/tt&amp;gt; ins Spiel. Es hat die gleiche Aufgabe wie &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt;, nur für Strings. &lt;br /&gt;
Sie werden gebeten, eine String einzugeben. &lt;br /&gt;
Dieser String wird danach in die Variable &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; kopiert. &lt;br /&gt;
Beide Strings, die ja nun die gleiche Zeichenkette enthalten, werden ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===strlen===&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;strlen&amp;lt;/tt&amp;gt;, die als Parameter eine String-Variable erwartet, liefert die Länge diese Strings zurück. Sie werden jetzt vermutlich sagen: &amp;quot;Das ist doch klar, wie lang der String ist. Ich habe es ja bei der Deklaratin angegeben&amp;quot;. Das stimmt schon, aber denken Sie noch einmal an die null-terminierten Strings. Das 0-Zeichen steht am Ende des Strings (am Ende der gültigen Zeichenfolge), aber nicht unbedingt am Ende des reservierten Speicherplatzes. Haben Sie eine Variable &amp;quot;char Variable[21];&amp;quot;, und ihr den Wert &amp;quot;hallo&amp;quot; zugewiesen, dann steht das null-Zeichen in Variable[5]. Der &amp;quot;gültige&amp;quot; String ist also 5 Zeichen (0-4) lang. Und genau das (5) würde strlen zurück liefern. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri[21];&lt;br /&gt;
  &lt;br /&gt;
  strcpy (stri, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
  printf (&amp;quot;Der String ist %d Zeichen lang&amp;quot;, strlen (stri));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird vor allem gebraucht, wenn Sie direkt auf den String zugreifen, mittels &amp;lt;tt&amp;gt;stri[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;stri[1]&amp;lt;/tt&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
==Ein- und Ausgabe-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===Bildschirm-Ausgabe===&lt;br /&gt;
Bisher war das Tutorial trotz aller Beispiele reine Theorie. Sie konnten zwar Programme schreiben, aber die Funktion nicht testen. Hier lernen Sie nun, wie Sie etwas am Bildschirm ausgeben.&lt;br /&gt;
&lt;br /&gt;
Die dazu notwendige Funktione heisst &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (das '&amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt;' ist kein Fehler!). Diese Anweisung gibt die ihr übergebenen Parameter auf das Standard-Ausgabegerät aus, in der Regel also auf den Bildschirm. Sie kann beliebig viele Parameter übernehmen. Es müssen jedoch Standard-Datentypen (z.B. &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;...) sein! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
    int zahl1 = 12;&lt;br /&gt;
    char zeichen1 = 'A';&lt;br /&gt;
    &lt;br /&gt;
    printf (&amp;quot;Das ist Text, und er wird als solcher ausgegeben. \n&amp;quot;);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zahl1' ist: %d \n&amp;quot;, zahl1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %c \n&amp;quot;, zeichen1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %d \n&amp;quot;, zeichen1);&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt Text aus. Das Zeichen am Ende (&amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;) bedeutet &amp;quot;New Line&amp;quot;, es bewegt den Cursor an den Anfang der nächsten Zeile. &lt;br /&gt;
&lt;br /&gt;
Der zweite &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt auch Text aus, am Ende befindet sich wieder das &amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;, um einen Zeilenvorschub zu erreichen. Das &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; wird vom Compiler durch den ersten Parameter ersetzt, der nach dem Text angegeben wird. In diesem Fall wird &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; also durch den Wert der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ersetzt. Das &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; im &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; bedeutet &amp;quot;Dezimalzahl&amp;quot;, der Computer gibt also eine ganze Zahl aus. &lt;br /&gt;
&lt;br /&gt;
In der dritten Ausgabe wird ein Zeichen ausgegeben. Diesmal bedeutet &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; &amp;quot;char&amp;quot; (Zeichen). Es wird also &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; durch ein &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt; ersetzt, denn die Variable &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; wird als Character interpretiert. &lt;br /&gt;
&lt;br /&gt;
Die letzte Ausgabe interpretiert den Inhalt von &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; als Zahl, und gibt dager den ASCII-Wert von &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, also 65 aus. Das ist ein typisches Beispiel für das mögliche unterschiedliche Interpretieren einer  Variablen!&lt;br /&gt;
&lt;br /&gt;
===Tastatur-Eingabe===&lt;br /&gt;
&lt;br /&gt;
Um ein &amp;quot;gscheites&amp;quot; Programm schreiben zu können, muß man wissen, wie der Benutzer über die Tastatur Befehle eingeben kann. Die dafür notwendigen Funktionen stelle ich in diesem Kapitel vor.&lt;br /&gt;
Die wichtigste Funktion ist &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt;. Er liest Daten von der Tastatur. Die Syntax entspricht derer von &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int  zahl1;&lt;br /&gt;
char zeichen1;&lt;br /&gt;
&lt;br /&gt;
printf (&amp;quot;Bitte geben Sie eine Zahl ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl1);&lt;br /&gt;
printf (&amp;quot;Geben Sie einen Zeichen ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%c&amp;quot;, &amp;amp;zeichen1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Programm gibt eine Eingabeaufforderung aus. Dann erwartet es vom Benutzer, daß er eine Zahl eingibt, die mit [ENTER] bestätigt wird. Dieser Wert wird in &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; abgespeichert. Danach erfolgt wiederum eine Aufforderung zur Eingabe, diesmal eines einzelnen Zeichens. Dieses kann man nun eingeben und ebenfalls mit [ENTER] bestätigen.&lt;br /&gt;
&lt;br /&gt;
Macht man keine dem Datentyp der erwarteten Variable entsprechende Eingabe, dann bricht das Programm mit einer Fehlermeldung ab (wenn man z.B. &amp;quot;1_T2&amp;quot; eingibt, wenn eine Zahl erwartet wird)!&lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; vor den Parametern ist notwendig. Warum, das erfahren Sie im Kapitel &amp;quot;Unterprogramme&amp;quot;. Für die Profis eine Kurz-Erklärung: Das Unterprogramm &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; bekommt zwar einen Wert übergeben, kann aber keinen zurückliefern (&amp;quot;call by value&amp;quot;). Daher wird kein Wert, sondern ein Zeiger auf eine Variable übergeben. Mit dem &amp;amp; Zeichen bekommen Sie die Adresse einer Variablen (&amp;quot;call by reference&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=Parameter von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;=&lt;br /&gt;
Das Unterprogramm &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; kann, wie jede andere Funktion, Parameter besitzen. Doch keine selbst gewählten, sondern nur bestimmte. Doch warum braucht main Parameter? Denken Sie einmal an alle Betriebssystembefehle:&lt;br /&gt;
&amp;lt;tt&amp;gt;dir *.exe &amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;copy *.* a:&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;ls -la &amp;lt;/tt&amp;gt;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen!&lt;br /&gt;
&lt;br /&gt;
=Kurzreferenz=&lt;br /&gt;
==Syntax-Bausteine==&lt;br /&gt;
&lt;br /&gt;
Die Erklärung des Aufbaus von C-Befehlen erfolgt neben einfachen Beispielen auch durch ihren prinzipellen Aufbau. In diesen Syntax-Beschreibungen finden sich immer wieder die gleichen Bausteine, die hier näher erklärt werden sollen. Falls Dir solch ein Syntax-Baustein begegnet, kannst Du ihn anclicken und kommst dann zu seiner Erläuterung. &lt;br /&gt;
&lt;br /&gt;
In den Beispielen selbst gehören auch die spitzen Klammern zu dem Baustein (was daran zu erkennen ist, daß auch die Klammern eingefärbt sind). Die Klammern dürfen in einem konkreten C-Programm daher nicht eingetippt werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bezeichner&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Bezeichner in C dienen dazu, Variablen zu identifizieren und ihnen sprechende Namen zu geben, um die Quelle lesbarer zu machen. Man braucht Bezeichner auch, um selbstdefinierte Datentypen zu benennen und zum Benennen von Struct- und Union-Komponenten sowie als Namen für Funktionen und Sprungmarken (Labels).&lt;br /&gt;
&lt;br /&gt;
Bezeichner dürfen aus den Kleinbuchstaben &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;z&amp;lt;/tt&amp;gt;, den Großbuchstaben &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;Z&amp;lt;/tt&amp;gt;, dem Unterstrich&amp;amp;nbsp;&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt; und den Ziffern &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;9&amp;lt;/tt&amp;gt; aufgebaut werden, wobei an erster Stelle jedoch keine Ziffer stehen darf.&lt;br /&gt;
&lt;br /&gt;
Es wird zwischen Groß- und Kleinschreibung unterschieden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Ausdruck in C ist ein Konstrukt, das einen Wert hat. Ob dieser Wert eine ganze Zahl ist, eine Kommazahl oder ein Zeiger, etc. ist dabei egal. Die einfachsten Ausdrücke sind Konstanten wie&lt;br /&gt;
 2&lt;br /&gt;
oder Variablen wie&lt;br /&gt;
 ein_zahl&lt;br /&gt;
Mehrere Ausdrücke können durch [[#Liste der Operatoren|Operatoren]] zu komplexeren Ausdrücken kombiniert werden, etwa&lt;br /&gt;
 eine_zahl + andere_zahl == 2&lt;br /&gt;
oder &lt;br /&gt;
 eine_zahl = 2&lt;br /&gt;
Letzterer hat den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; und den Nebeneffekt, daß er diesen Wert an &amp;lt;tt&amp;gt;eine_zahl&amp;lt;/tt&amp;gt; zuweist.&lt;br /&gt;
&lt;br /&gt;
Auch der Aufruf einer Funktion, die einen Rückgabewert liefert, ist ein Ausdruck:&lt;br /&gt;
 sin (1.2)&lt;br /&gt;
und kann zum Aufbau komplexerer Ausdrüche verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bedingung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Bedingung ist ein Ausdruck, bei der nur interessiert, ob dieser zu&amp;amp;nbsp;0 (unwahr) auswertet oder zu ungleich&amp;amp;nbsp;0 (wahr). Solche Ausdrücke findet man in if-Anweisungen, in Schleifenbedingungen und bedingten Zuweisungen&lt;br /&gt;
 (ein_wert &amp;lt; 2) || (ein_wert &amp;gt; 40)&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Lvalue ist ein Ausdruck, dem etwas zugewiesen werden kann. Der Name ''Lvalue'' kommt aus dem Englischen. Das ''L'' steht abkürzend für left. Ein Lvalue ist damit ein Ausdruck, der auf der linken Seite eine Zuweisung in C stehen darf. Das &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; in den folgenden Beispiel-Ausdrücken muss ein Lvalue sein:&lt;br /&gt;
 x = y-1&lt;br /&gt;
&lt;br /&gt;
 x++&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Konstante&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Konstante ist ein Ausdruck, dessen Wert dem Compiler bekannt ist. Beispiele für Konstanten sind etwa&lt;br /&gt;
 7&lt;br /&gt;
 'B'&lt;br /&gt;
 -13.98e12&lt;br /&gt;
 1+(2*3)&lt;br /&gt;
und die Werte von [[#Enum|Enum]]s. &lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; aus dem folgenden Codestück definiert jedoch keine Konstante in diesem Sinne&lt;br /&gt;
 const double Pi = 3.14159256;&lt;br /&gt;
denn in einem anderen Quellmodul könnte durch die Deklaration&lt;br /&gt;
 extern const double Pi;&lt;br /&gt;
das Symbol &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; bekannt sein, ohne daß sein Wert bekannt ist!&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Adresse&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Adresse ist ein Ausdruck, der einen Speicherort (physikalisch oder virtuell) halten kann. Adressen erhält man dadurch, daß man einem Bezeichner den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt;voranstellt, Adressen durch Arithmetik berechnet oder Zahlen zu Adressen castet. Folgende Ausdrücke sind Adressen (eine sinnvolle Deklaration der auftretenden Variablen vorausgesetzt)&lt;br /&gt;
 &amp;amp; eine_zahl&lt;br /&gt;
 &amp;amp; ein_array[10]&lt;br /&gt;
 &amp;amp; ein_struct&lt;br /&gt;
 &amp;amp; ein_struct.komponente&lt;br /&gt;
 (int *) 0x1234&lt;br /&gt;
 (int *) eine_zahl&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Deklaration&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Anweisungen sind gewissermassen die Atome (oder Moleküle?), aus denen ein C-Programm besteht. Jedes C-Programm ist eine Abfolge von Deklarationen und Anweisungen. Einfache Anweisungen erhält man, in dem man einen Ausdruck nimmt und einen Strichpunkt dahinter schreibt:&lt;br /&gt;
 {{Ausdruck|}};&lt;br /&gt;
wie in&lt;br /&gt;
 x = x+1;&lt;br /&gt;
&lt;br /&gt;
Andere Anweisungen sind die unten aufgeführten Schleifen und die if- sowie die switch-Anweisung.&lt;br /&gt;
&lt;br /&gt;
Mehrere Deklarationen und Anweisungen können zu einem Block zusammengefasst werden. Dieser Block stellt dann wieder eine einzelne Anweisung dar und kann genau so gehandhabt werden!&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
In diesem Sinne ist auch z.B. die Syntax der if-Anweisung zu verstehen&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
besagt, daß der abhängig ausgeführte Code eine einzelne Anweisung sein darf oder eben ein kompletter Block oder die Verschachtelung mehrerer Blöcke etc.&lt;br /&gt;
&lt;br /&gt;
Eine Anweisung kann auch &amp;quot;leer&amp;quot; sein, also nichts tun. Diese Anweisungen sind der leere Block&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
und der Strichpunkt&lt;br /&gt;
 ;&lt;br /&gt;
die man gelegentlich in Schleifen findet:&lt;br /&gt;
 while (!timeout())&lt;br /&gt;
    {}&lt;br /&gt;
oder hinter Sprungmarken, die sonst direkt vor einer schliessenden Blockklammer stünden:&lt;br /&gt;
 {&lt;br /&gt;
    ...&lt;br /&gt;
    goto ein_label;&lt;br /&gt;
    ...&lt;br /&gt;
    {{Label|ein_label}}:;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Nicht jede Anweisung ist an jeder Stelle eines C-Programms erlaubt, so darf ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; nut innerhalb einer Schleife stehen. Gleiches gilt für &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;, das aber auch innerhalb eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; vorkommen darf.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Dies steht für einen Datentyp. Es kann ein elementarer Typ sein wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;, ein Zeiger darauf wie &amp;lt;tt&amp;gt;char*&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;void*&amp;lt;/tt&amp;gt;, und auch Qualifier enthalten wie das &amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt; im Typ &amp;lt;tt&amp;gt;unsigned long long&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Zu den Typen gehören auch zusammengesetzte Datentypen wie Strukturen und Unions, mit &amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt; selbst definierte Typen und natürlich Zeiger darauf, wie aus dem Abschnitt [[#Datentypen|Datentypen]]:&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person *&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;data32_t&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;&lt;br /&gt;
und Zeiger auf Funktionen.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Parameterliste&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
Die Parameterliste bei einer Funktionsdefinition gibt an, wieviel Übergabeparameter sie bekommt, wie diese heissen und welchen Typs diese sind. Der prinzipielle Aufbau ist&lt;br /&gt;
 {{Type}} {{Bezeichner}}, {{Type}} {{Bezeichner}}, ...&lt;br /&gt;
Falls die Funktion keine Parameter hat, dann ist die Parameterliste leer.&lt;br /&gt;
&lt;br /&gt;
Hier als Beispiel die zweiparametrige Funktion &amp;lt;tt&amp;gt;produkt&amp;lt;/tt&amp;gt;. Der erste Parameter heisst&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und ist ein &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;. Der zweite namens&amp;amp;nbsp;&amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; ist vom Typ &amp;quot;Zeiger auf double&amp;quot;, der Inhalt &amp;lt;tt&amp;gt;*b&amp;lt;/tt&amp;gt; ist also auch ein double.&lt;br /&gt;
&lt;br /&gt;
'''Definition der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b)&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
In älteren C-Quellen findet man noch eine andere Syntax für die Deklaration der Parameter, die aber heute praktisch nicht mehr verwendet wird:&lt;br /&gt;
'''alte Definition der Funktion:'''&lt;br /&gt;
 double produkt (a, b)&lt;br /&gt;
 double a, *b;&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Um die Funktion bekannt zu machen, werdendet man eine Deklaration bzw. den Prototypen, der dem Compiler nur mitteilt, welche Parameter die Funktion bekommt und was sie zurückliefert. Für den Aufruf der Funktion muss der Compiler nur diesen Prototyp kennen, ''was'' die Funktion im Endeffekt macht und wie sie implementiert wurde ist egal, sie wird als BlackBox angesehen.&lt;br /&gt;
&lt;br /&gt;
'''Prototyp der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b);&lt;br /&gt;
Hier dürfen die Bezeichner auch fehlen:&lt;br /&gt;
 double produkt (double, double*);&lt;br /&gt;
&lt;br /&gt;
==if==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==if-else==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==for==&lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Eine for-Schleife entspricht folgendem Konstrukt. Dabei sind die drei Ausdrücke optional. Fehlt die Bedingung, dann wird diese als &amp;quot;wahr&amp;quot; angenommen. Die beiden anderen Ausdrücke wird man als Ausdrücke mit Nebeneffekt wählen wie z.B. &amp;lt;tt&amp;gt;x=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;x=x-2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
 {&lt;br /&gt;
    {{Ausdruck|1}};&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_loop}}:&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
    else&lt;br /&gt;
       goto _break;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_continue}}:&lt;br /&gt;
    {{Ausdruck|2}};&lt;br /&gt;
    goto _loop;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_break}}:;&lt;br /&gt;
 }&lt;br /&gt;
Die Labels &amp;lt;tt&amp;gt;_break&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_continue&amp;lt;/tt&amp;gt; entsprechen den Sprungzielen einer &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Anweisung innerhalb von &amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==do-while==&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while  ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
==while==&lt;br /&gt;
 while  ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==switch==&lt;br /&gt;
 switch  ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    ...&lt;br /&gt;
  &lt;br /&gt;
    default:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#break-Anweisung|&amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Konstanten|&amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#continue-Anweisung|&amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#do-while-Schleife|&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Enum|&amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#for-Schleife|&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#goto-Anweisung|&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#return-Anweisung|&amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Liste der Operatoren|sizeof]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Strukturen|&amp;lt;tt&amp;gt;struct&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Eigene Datentypen|&amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Unions|&amp;lt;tt&amp;gt;union&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#while-Schleife|&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund2}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Arithmetische Operatoren&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Dies sind die &amp;quot;normalen&amp;quot; arithmetischen Operationen, wie man sie aus der Schule kennt. Man kann damit und allen anderen Operatoren auch komplexere Ausdrücke aufbauen. Die Prioritäten sind so, wie man sie kennt, also &amp;quot;Punktrechnung vor Strichrechnung&amp;quot;. Will man dies ändern, dann mit den runden Klammern:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;1+2*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 7&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(1+2)*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 9&amp;lt;br/&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}}&amp;amp;nbsp;+&amp;amp;nbsp;{{Ausdruck|}}&amp;lt;/tt&amp;gt; || Addition&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} - {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Subtraktion&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} * {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Multiplikation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} / {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Division&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} % {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Rest der Division (modulo)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;- {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Vorzeichenumkehr, Zweier-Komplement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Logische Operatoren und Vergleiche&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die logischen und die vergleichenden Operatoren liefern als Ergebnis den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (wahr) oder einen Wert ungleich&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (falsch, um genau zu sein den Wert &amp;lt;tt&amp;gt;!0&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Man kann das Ergebnis zwar einer Variablen zuweisen, in aller Regel wird man solche Ausdrücke jedoch in Bedingungen zu &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder in Abbruch-Bedingungen von Schleifen finden.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;&amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches AND: beides wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124;&amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches OR: mind. eines ist wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;! {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches NOT (0 &amp;amp;harr; ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} == {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} != {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist nicht gleich&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bitweise Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~ {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise NOT (Einser-Komplement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise AND&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise ODER&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} ^ {{Ausdruck|}}&amp;lt;/tt&amp;gt; ||bitweise XOR&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Shift-Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;lt;&amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Bits nach links schieben&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;gt;&amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Schieben nach rechts schieben&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Typen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Ein Cast in C kann dazu verwendet werden, den Typ eines Ausdruckes zu ändern oder den Ausdruck mit einer bestimmten Genauigkeit zu berechnen. Wird z.B. eine Berechnung standardmässig in 16 Bit ausgeführt, dann kann man mit einem Cast &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(long) &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
ausdrücken, daß die Berechnung in 32 Bit erfolgen soll. Des weiteren kann man Zeiger und ganze Zahlen und Gleitkommazahlen ineinander umwandeln.&lt;br /&gt;
&lt;br /&gt;
Casts können ''nicht'' dazu verwendet werden, um z.B. eine Zahl in einen String zu konvertieren, der diese Zahl darstellt! Dafür gibt es spezielle Funktionen wie &amp;lt;tt&amp;gt;itoa&amp;lt;/tt&amp;gt;!&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Type}}) {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Cast, Typwandlung&lt;br /&gt;
|-&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;| &amp;lt;tt&amp;gt;sizeof ({{Type}})&amp;lt;/tt&amp;gt; || Eine Konstante, deren Wert die Größe (in Bytes) des Typs ist. &amp;lt;tt&amp;gt;sizeof&amp;lt;/tt&amp;gt; ist auch auf Objekte anwendbar wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, Arrays bekannter Größe, Strukturen und Unions,  Array-, Struktur- und Union-Komponenten, Pointer, etc. Beispiel:&amp;lt;br/&amp;gt;&lt;br /&gt;
 int i, sum=0, array[] = { 1, -13, 4, 0, sizeof (int*) };&lt;br /&gt;
 &lt;br /&gt;
 for (i=0; i&amp;lt; sizeof (array) / sizeof (array[0]); i++)&lt;br /&gt;
    sum += array[i];&lt;br /&gt;
Alle Elemente des Arrays werden aufaddiert, ohne daß deren Anzahl explizit in der Schleife genannt ist.&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zeiger und Adressen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;* {{Adresse}}&amp;lt;/tt&amp;gt; || der Inhalt an Adresse&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp; {{Lvalue}}&amp;lt;/tt&amp;gt; || Adresse von&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Strukturen, Unions, Arrays&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Struct&amp;gt;}}.{{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Zeiger-auf-Struct&amp;gt;}} -&amp;gt; {{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union, deren Adresse man hat&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Adresse}}&amp;amp;#91;{{Ausdruck|}}&amp;amp;#93;&amp;lt;/tt&amp;gt; || Array-Element&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bedingte Auswertung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Bedingung}}) ? {{Ausdruck|}} : {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Auswahl des Wertes abhängig von der Bedingung&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zuweisung und Operatoren mit Nebeneffekt&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die Unterschiede der post- und pre-Varianten der Increment/Decrement kommen in Konstrukten wie &amp;lt;tt&amp;gt;x = *p++&amp;lt;/tt&amp;gt; zum tragen:&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *p++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; p = p+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *++p;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; p = p+1; x = *p;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = (*p)++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; *p = (*p)+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = ++(*p);&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; *p = (*p)+1; x = *p;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} = {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Zuweisung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++ {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-- {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Decrement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ++&amp;lt;/tt&amp;gt; || Post-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} --&amp;lt;/tt&amp;gt; || Post-Decrement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Kurzschreibweisen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Für ganz Faule gibt es anstatt&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a = a @ b&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
für viele Operatoren (hier dargestellt durch ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;@&amp;lt;/tt&amp;gt;) die abkürzende Schreibweise&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a @= b&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} += {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} -= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} *= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} /= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} %= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ^= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;lt;&amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;gt;&amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Autoren'''&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
* Kernighan und Ritchie - Buch&lt;br /&gt;
* Christian Wirth , C Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://wwwuser.gwdg.de/~kboehm/ebook/inhalt.html C-Programmieren unter Linux]&lt;br /&gt;
* [http://www.gdv.uni-hannover.de/documentation.php Skripte zum Selbststudium: C, C++, Java, etc]&lt;br /&gt;
* [http://info.baeumle.com/ansic.html Einführung in ANSI-C]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Quellcode C|!]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Inrfb2</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10401</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10401"/>
				<updated>2007-03-13T20:19:42Z</updated>
		
		<summary type="html">&lt;p&gt;Inrfb2: /* Parameter von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Programmiersprache C wurde 1971 als Gundlage für das Betriebssystem UNIX in den USA entwickelt (UNIX ist zu über 90% in C geschrieben). 1978 wurde von Brian Kernighan und Dennis Ritchie eine eindeutige Sprachdefinition entwickelt. Mittlerweile ist C von ANSI und ISO standardisiert.&lt;br /&gt;
&lt;br /&gt;
Heute sind C und ihr Nachfolger C++ die dominierenden Programmiersprachen. Sehr viele Anwendungen sind in C geschrieben, was inzwischen auch auf eingebettete Systeme zutrifft, die lange in Assembler programmiert werden mussten, da keine ausreichend leistungsfähigen Compiler zur Verfügung standen. &lt;br /&gt;
&lt;br /&gt;
Leider ist C nicht einfach zu lernen &amp;amp;ndash; es wurde weder von noch für Hobby-Programmierer entwickelt &amp;amp;ndash; und eignet sich daher nur bedingt für den Einsteiger. Mit etwas Übung und einem optimierenden Compiler kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
Vom Design her ist C eine Hardware-unabhängig Sprache. Das bedeutet, daß C-Programme mit vertretbarem Aufwand auf ein anderes System portiert werden können. Dazu benötigt man lediglich einen anderen Compiler, und Inline-Assembler-Anweisungen (Assembleranweisungen innerhalb eines C-Programmes) müssen der neuen Hardware (Prozessor) angepasst werden. &lt;br /&gt;
&lt;br /&gt;
==Geschichte==&lt;br /&gt;
;1971: C wird entwickelt&lt;br /&gt;
;1978: Kernighan und Ritchie definieren die Sprache.&lt;br /&gt;
;1983: ANSI und ISO standardisieren C.&lt;br /&gt;
;1992: Bjarne Stroustrup enwickelt die Nachfolgesprache C++.&lt;br /&gt;
&lt;br /&gt;
=Aufbau eines C-Programmes=&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
   C-Programme haben keinen fixen Aufbau wie z.B. Pascal. Es gibt zwar gewisse Regeln, aber sonst sind dem Programmierer alle Freiheiten überlassen. Der folgende &amp;quot;Beispiel-Aufbau&amp;quot; ist daher nicht zwingend und kann durchaus verändert werden.&lt;br /&gt;
&lt;br /&gt;
   Natürlich haben C-Programme einen fixen Aufbau! Ebenso wie Pascal-Programme auch unterliegen sie einer strikten Grammatik! &lt;br /&gt;
Auskommentiert --[[Benutzer:SprinterSB|SprinterSB]] 10:23, 17. Feb 2006 (CET)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Ein einfaches C-Programm könnte folgendermassen aussehen. Das Programm tut eigentlich nichts, aber das Beispiel zeigt den prinzipiellen Aufbau. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 int Zahl1;&lt;br /&gt;
 char Zeichen1;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int zahl2;&lt;br /&gt;
 &lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Beschreibung:'''&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndash; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
 {{comment|void-Definition von main ist nur beim Controller ueblich}}&lt;br /&gt;
 {{comment|spezielle Compilereinstellungen sind noetig, damit bei dieser Definition von main}}&lt;br /&gt;
 {{comment|kein Fehler/Warnung erzeugt wird.}}&lt;br /&gt;
 void main ()&lt;br /&gt;
 {&lt;br /&gt;
     ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
 int main (void)&lt;br /&gt;
 {  {{comment|der Block &amp;quot;main&amp;quot; beginnt}}&lt;br /&gt;
    int zahl;&lt;br /&gt;
    &lt;br /&gt;
    {   {{comment|ein Block beginnt}}&lt;br /&gt;
        {{comment|hier koennen Deklarationen und Anweisungen stehen}}&lt;br /&gt;
    }   {{comment|der Block endet}}&lt;br /&gt;
   &lt;br /&gt;
    return 0;&lt;br /&gt;
 }  {{comment|&amp;quot;main&amp;quot; endet}}&lt;br /&gt;
&lt;br /&gt;
=Datentypen=&lt;br /&gt;
==Elementare Datentypen==&lt;br /&gt;
Der Datentyp einer Variable gibt an, welche Werte eine Variable enthalten kann, welcher Art diese Daten sind und wie sie verarbeitet werden, etwa in arithmetischen Operationen wie einer Addition. So ist es zum Beispiel möglich, in eine Variable vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ganze Zahlen zwischen ca. -32000 und +32000 einzutragen. In einer char-Variable können ASCII-Zeichen gespeichert werden (alles, was Sie mit der Tastatur erzeugen können) oder ganze Zahlen von -128 bis 127.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da C plattformabhängig ist, hängt die Größe eines Datentypes zum Teil von der genutzten Hardware (z.B. 8, 16 oder 32 Bit-Controller) und dem Compiler und dessen Einstellungen ab!&lt;br /&gt;
&lt;br /&gt;
===int, char, short, long (ganze Zahlen)===&lt;br /&gt;
In Variable dieser Typen können Sie ganze Zahlen abspeichern, also z.B. 1, &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;2, 100, 12345. Jeden dieser Typen gibt es in zwei Ausprägungen: als &amp;quot;&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;quot;, also als vorzeichenbehafteten Typ, und als &amp;quot;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&amp;quot;, also ohne Vorzeichen, d.h. das Vorzeichen wird als 0 oder +1 genommen. &lt;br /&gt;
&lt;br /&gt;
Vorzeichenbehaftete Ganzzahl-Typen werden intern im &amp;lt;tt&amp;gt;n-1&amp;lt;/tt&amp;gt;-Komplement dargestellt, das Vorzeichen selbst findet sich also im höchstwertigen Bit. Werden zur Speicherung ''b'' Bits verwendet, dann reicht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;z.B. *zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==Enum==&lt;br /&gt;
&lt;br /&gt;
Über &amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt; können Aufzählungen definiert werden. Die Werte sind &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Werte und beginnen mit&amp;amp;nbsp;0. Der folgende enum hat einen um&amp;amp;nbsp;1 grösseren Wert. Mit einer Zuweisung können auch andere Werte zugeordnet werden. Klarer wird's im Beispiel:&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 enum Farben&lt;br /&gt;
 {&lt;br /&gt;
    ROT,&lt;br /&gt;
    GRUEN,&lt;br /&gt;
    BLAU,&lt;br /&gt;
    BRAUN = 5,&lt;br /&gt;
    SCHWARZ&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
Dies definiert die Konstanten &amp;lt;tt&amp;gt;ROT=0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;GRUEN=1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BLAU=2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BRAUN=5&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;SCHWARZ=6&amp;lt;/tt&amp;gt; und den Typ &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void foo (enum Farben farbe)&lt;br /&gt;
{&lt;br /&gt;
   switch (farbe)&lt;br /&gt;
   {&lt;br /&gt;
      case ROT:&lt;br /&gt;
         ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit kann man anstatt &amp;quot;magischer&amp;quot; Zahlen sprechende Namen im Code verwenden, etwa in Berechnungen und Zuweisungen, Vergleichen oder als Konstante hinter einem &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zusammengesetzte Datentypen==&lt;br /&gt;
===Arrays===&lt;br /&gt;
Oft muß man sehr viele Werte gleichzeitig abspeichern und betrachten, die alle der selben Aufgabe dienen. Man schreibt z.B. ein Programm, das 10 Zahlen einlesen und anschließend wieder ausgeben soll. Man könnte das natürlich mit 10 einzelnen Variablen bewerkstelligen, aber es ist sinnvoller, dabei Arrays &amp;amp;ndash; teilweise auch als ''Felder'' bezeichnet &amp;amp;ndash; zu verwenden.&lt;br /&gt;
&lt;br /&gt;
In einem Array werden mehrere Variablen gleichen Typs zusammengefasst und hintereinander im Speicher abgelegt. So kann man viele tausend Variablen anlegen mit nur einer Zeile Code. Doch es gibt noch größere Vorteile: Sie können das Array mit einer Schleife ganz einfach nach Werten durchsuchen. Stellen Sie sich vor, Sie müssten mit 100 verschiedenen Variablen &amp;lt;tt&amp;gt;Zahl_00&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;Zahl_99&amp;lt;/tt&amp;gt; arbeiten!&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}}&amp;amp;#91;{{Konstante}}&amp;amp;#93;;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 unsigned int werte[100];&lt;br /&gt;
&lt;br /&gt;
Der Name muß natürlich ein gültiger Bezeichner sein, als Datentyp kann jeder Typ genommen werden &amp;amp;ndash; sowohl elementare Datentypen als auch Zeiger, Strukturen, Unions oder selbst definierte Datentypen. In der eckigen Klammer wird die Anzahl der Elemente bekanntgegeben. Ein mit [3] definiertes Array hat Platz für drei Variablen. Da der Index immer bei 0 beginnt, greift man also mit &amp;lt;tt&amp;gt;[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;[1]&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;[2]&amp;lt;/tt&amp;gt; auf den jeweilige Inhalt zu. Um auf eine der im Array enthaltenen Variablen zugreifen zu können, müssen Sie den Variablennamen und in eckigen Klammern den Index (die &amp;quot;Nummer&amp;quot;) der Variablen angeben. Diese Variable verhält sich dann wie eine ganz normale Variable des jeweiligen Datentypes. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #define NZAHLEN 10&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int i;&lt;br /&gt;
    int zahlen[NZAHLEN];  {{comment|zahlen[0] ... zahlen[9]}}&lt;br /&gt;
  &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++)&lt;br /&gt;
    {&lt;br /&gt;
       printf (&amp;quot;Bitte Zahl %d eingeben: &amp;quot;, i);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; zahlen[i]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++) &lt;br /&gt;
       printf (&amp;quot;Zahl %d ist: %d\n&amp;quot;, i, zahlen[i]);&lt;br /&gt;
      &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 10 int-Variablen großes Array angelegt. &lt;br /&gt;
In dieses wird nun der Reihe nach 10 Zahlen eingelesen. &lt;br /&gt;
Anschließend werden alle 10 Zahlen ausgegeben. &lt;br /&gt;
&lt;br /&gt;
Dabei wird die Größe der Arrays und das Schleifenende über das Define &amp;quot;&amp;lt;tt&amp;gt;NZAHLEN&amp;lt;/tt&amp;gt;&amp;quot; angegeben. Dadurch muss nur ''eine Stelle'' im Code geändert werden, wenn die Größe des Arrays einmal einen anderer Wert als 10 haben soll &amp;amp;ndash; dies vermeidet Fehler die dadurch entstehen, wenn man beim Anpassen der Array-Größe eine Codestelle vergisst, zudem wird der Code lesbarer als wenn irgendwo die Zahl &amp;quot;10&amp;quot; auftaucht.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
:Wird ein ungültiger Index angeben (einer, der in der Deklaration nicht enthalten ist) können  undefinierte Dinge passieren, wenn dadurch andere Variableninhalte oder Programmcode überschrieben wird, der hinter oder vor dem Array im Speicher liegt. Schlimmstenfalls kann sogar der Computer/Controller abstürzen. Also darauf achten, daß keine ungültigen Werte als Index auftreten!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Strings (Zeichenketten)===&lt;br /&gt;
Ein String ist nichts anderes als ein Array, das aus einzelnen Zeichen (&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;) gebildet wird. Die Ausgabe auf dem Bildschirm funktioniert am einfachsten mittels Strings.&lt;br /&gt;
&lt;br /&gt;
Die Definition eines Strings erfolgt also genauso wie bei Arrays:&lt;br /&gt;
 char string[21];&lt;br /&gt;
&lt;br /&gt;
Nun haben Sie eine String, in dem Sie 21 Zeichen speichern können. Ganz richtig ist das jedoch nicht. C arbeitet mit &amp;quot;null-terminierten Strings&amp;quot;. Das beudeutet, dass die Länge des Strings nicht abgespeichert wird, sondern das Zeichen mit dem ASCII-Wert 0 das Stringende kennzeichnet. Daher auch die Bezeichnung  &amp;quot;null terminiert&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Das letzte Zeichen eines Strings muß daher immer das ASCII-Zeichen Nr. 0 sein. Ist es das nicht, hat der String kein definiertes Ende, und wenn Sie versuchen, ihn durch eine Standard-Funktion auszugeben zu lassen, könnte es eine Weile dauern, bis sich im Speicher zufällig irgendwo eine 0 befindet. Es stehen ihnen daher bei dem Beispiel nur 20 Zeichen zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
===Mehrdimensionale Arrays===&lt;br /&gt;
Manchmal benötigt man mehr als nur ein eindimensionales Array, wie Sie es bisher kennengelernt haben. Auch dies ist kein Problem. In der Deklaration geben Sie einfach mehrere eckige Klammern hintereinander an. Aber Vorsicht: der Speicherplatz ist begrenzt, ein &amp;quot;&amp;lt;tt&amp;gt;char feld[1024][1024]&amp;lt;/tt&amp;gt;&amp;quot; hat die Speicherplatzgrenzen vermutlich bereits weit überschritten, und der Compiler wird einen (bei gewissen Einstellung auch keinen) Fehler liefern.&lt;br /&gt;
Beim Zugriff auf mehrdimensionale Felder müssen auch mehrere Indizes angeben werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  int x,y;&lt;br /&gt;
  int feld[3][5];&lt;br /&gt;
 &lt;br /&gt;
  for (x=0; x&amp;lt;3; x++) &lt;br /&gt;
  {&lt;br /&gt;
     for (y=0; y&amp;lt;5; y++)&lt;br /&gt;
     {&lt;br /&gt;
       printf (&amp;quot;Feldwert x: %d,  y: %d &amp;quot;, x, y);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; feld[x][y]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  for(x=0; x&amp;lt;3; x++) &lt;br /&gt;
     for (y=0; y&amp;lt;5; y++) &lt;br /&gt;
        printf (&amp;quot;Wert: feld[%d][%d] = %d\n&amp;quot;, x, y, feld[x][y]);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 3 mal 5 &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array angelegt. &lt;br /&gt;
Dann werden die Werte eingegeben: zuerst &amp;lt;tt&amp;gt;feld[0][0]&amp;lt;/tt&amp;gt;, dann &amp;lt;tt&amp;gt;feld[0][1]&amp;lt;/tt&amp;gt;, usw. bis &amp;lt;tt&amp;gt;feld[2][4]&amp;lt;/tt&amp;gt;. &lt;br /&gt;
Zum Schluß werden alle Werte noch einmal ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===Strukturen===&lt;br /&gt;
In C können Sie sogenannte &amp;quot;Strukturen&amp;quot; definieren. Dabei handelt es sich um eine Zusammenfassung mehrerer Datentypen zu einem größeren. Im Unterschied zu Feldern können in Strukturen unterschiedliche Datentypen zusammengestellt und gespeichert werden: &lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 struct {{Bezeichner}}&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur 'Person'}}&lt;br /&gt;
 struct Person &lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;lt;tt&amp;gt;struct Person {&amp;lt;/tt&amp;gt;&amp;quot; leitet die Definition der Struktur mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;Person&amp;lt;/tt&amp;gt;&amp;quot; ein. &lt;br /&gt;
Dann werden in dieser Struktur fünf Komponenten definiert: drei Strings und zwei &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. &lt;br /&gt;
mit &amp;lt;tt&amp;gt;}&amp;lt;/tt&amp;gt; wird die Definition abgeschlossen. Sie haben damit einen Datentyp erstellt. Um eine Variable des Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach an&lt;br /&gt;
 struct Person {{Bezeichner}};&lt;br /&gt;
&lt;br /&gt;
Zum Zugriff auf eine Komponente der Struktur gibt man den Namen der Struktur-Variablen an (im folgenden Beispiel also &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;klaus&amp;lt;/tt&amp;gt;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
 {{comment|Definition zweier Struktur-Variablen}}&lt;br /&gt;
 struct Person hubert, klaus;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Zugriff auf Struktur-Komponenten}}&lt;br /&gt;
 hubert.alter = 32;&lt;br /&gt;
 klaus.alter = hubert.alter + 1;&lt;br /&gt;
&lt;br /&gt;
===Unions===&lt;br /&gt;
Eine Union wird ganz analog zu einer Struktur deklariert und verwendet. Sie unterscheidet sich von einer Struktur jedoch dadurch, daß ihre Elemente nicht nacheinander im Speicher abgelegt werden, sondern sich überlagern. Auf die in einer Union enthaltenen Daten gibt es also verschiedene Sichten: je nachdem, welche Sicht bzw. Interpretation der Daten man gerne hätte, wählt man den gewünschten Zugriff.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
union Daten &lt;br /&gt;
{&lt;br /&gt;
   int id;&lt;br /&gt;
&lt;br /&gt;
   struct Person u_person;&lt;br /&gt;
&lt;br /&gt;
   struct u_double&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      double wert;&lt;br /&gt;
   };&lt;br /&gt;
&lt;br /&gt;
   struct u_pointer&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      union Daten * p1;&lt;br /&gt;
      union Daten * p2;&lt;br /&gt;
   };&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
union Daten data;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies definiert eine Union mit den vier Zugriffsmöglichkeiten &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_double&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Größe der Union richtet sich dabei nach der grössten Komponente. In diesem Beispiel sind alle Komponenten so angelegt worden, daß sie an erster Stelle ein &amp;lt;tt&amp;gt;int id&amp;lt;/tt&amp;gt; enthalten. In &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; könnte man sich also merken, wie die Daten in der Union zu interpretieren sind. Würde &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; nicht dieses &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; enthalten, so würde sich &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; mit &amp;lt;tt&amp;gt;data.u_person.vname&amp;lt;/tt&amp;gt; überlagern. Ein Ändern der ersten Buchstaben von &amp;lt;tt&amp;gt;vname&amp;lt;/tt&amp;gt; hätte also ein Ändern von &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; zur Folge, und man könnte es nicht mehr als Merker verwenden. Mit diesem Feld überlagert das &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; die &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;-Felder der anderen Sichten, z.B. ist &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; der selbe Zugriff wie auf &amp;lt;tt&amp;gt;data.u_person.id&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein anderes Beispiel ist eine Union, die es ermöglicht, auf die einzelnen Bytes eines &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; zuzugreifen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef union&lt;br /&gt;
{&lt;br /&gt;
   unsigned long  as_long;&lt;br /&gt;
   unsignen short as_short[2];&lt;br /&gt;
   unsignen char  as_byte[4];&lt;br /&gt;
} data32_t;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies überlagert einen &amp;lt;tt&amp;gt;unsigned long&amp;lt;/tt&amp;gt; &amp;amp;ndash; also eine 32-Bit-Zahl &amp;amp;ndash; mit vier Bytes bzw. zwei Shorts.&lt;br /&gt;
 data32_t wert;&lt;br /&gt;
 &lt;br /&gt;
 wert.as_long = 0x12345678;&lt;br /&gt;
 wert.as_byte[0] = 0xab;&lt;br /&gt;
 {{comment|nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform)}}&lt;br /&gt;
&lt;br /&gt;
==Eigene Datentypen==&lt;br /&gt;
&lt;br /&gt;
=Variablen=&lt;br /&gt;
Eine Variable ist ein Synonym (=anderer Name) für eine Speicherstelle in einem Computer. Einfacher gesagt, eine Variable bietet Raum, um Daten wie Zahlen oder Zeichen zu speichern und wieder zu lesen.&lt;br /&gt;
&lt;br /&gt;
==Variablennamen==&lt;br /&gt;
Ein Variablenname kann zusammengesetzt werden aus den Buchstaben &amp;lt;tt&amp;gt;'''A'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''Z'''&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;'''a'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''z'''&amp;lt;/tt&amp;gt;, den Ziffern &amp;lt;tt&amp;gt;'''0'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''9'''&amp;lt;/tt&amp;gt;, sowie dem Sonderzeichen &amp;quot;Unterstrich&amp;quot; (underscore) &amp;lt;tt&amp;gt;'''_'''&amp;lt;/tt&amp;gt;. Dabei darf an erster Stelle keine Ziffer stehen. Die Bezeichner &amp;lt;tt&amp;gt;hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALLO&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALL0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;_123&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_HALLO&amp;lt;/tt&amp;gt; sind also alle gültige und unterschiedliche Variablennamen.&lt;br /&gt;
&lt;br /&gt;
==Anlegen von Variablen==&lt;br /&gt;
Um eine Variable verwenden zu können, muss sie zuerst vereinbart (&amp;quot;erzeugt&amp;quot;) werden. Dies wird auch als &amp;quot;''Definition der Variablen''&amp;quot; bezeichnet und geht so: Schreiben Sie zuerst den Datentyp, dann den Namen der Variablen. Zum Schluß kommt noch der Strichpunkt, wie nach jeder C-Anweisung oder Deklaration. Und nicht vergessen: C unterscheidet zwischen  Groß- und Kleinschreibung! &lt;br /&gt;
 int Zahl1, Zahl2;&lt;br /&gt;
 char Zeichen;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    float gleitZahl;&lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:'''&lt;br /&gt;
In einer Zeile können auch mehrere Variablen gleichen Types vereinbart werden, wenn man ein Komma dazwischen setzt. Variablen können in jedem Block vereinbart werden. Siehe [[#Gültigkeitsbereich|Gültigkeitsbereich]].&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen==&lt;br /&gt;
Man kann einer vereinbarten Variable Werte [[#Zuweisungen|zuweisen]]. Dazu schreibt man zuerst den Variablennamen, ein Gleichheitszeichen &amp;quot;&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;&amp;quot; und anschliessend den zuzuweisenden [[#Ausdrücke|Ausdruck]]. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, zahl2 = 12;&lt;br /&gt;
  char zeichen1 = 'A';&lt;br /&gt;
&lt;br /&gt;
  zahl1 = 52;&lt;br /&gt;
  zeichen1 = zeichen1 + 1; &lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Zuerst werden drei Variablen angelegt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;: wird gleich bei der Vereinbarung der Wert 12 zugewiesen. &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl1 = 52&amp;lt;/tt&amp;gt;: Hier wird der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; der Wert 52 zugewiesen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;: wird um 1 erhöht. Da in der Variablen &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; gespeichert ist, gibt sich ihr neuer Wert aus &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt;. Weil &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; dem Wert 65 entspricht, ist &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt; gleich 66, was dem Wert für &amp;lt;tt&amp;gt;'B'&amp;lt;/tt&amp;gt; entspricht.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei float==&lt;br /&gt;
Das funktioniert genau wie bei normale Zuweisungen. Nachkommastellen werden durch einen Punkt abgegrenzt: &lt;br /&gt;
 floatVariable = 3.14;&lt;br /&gt;
Zusätzlich kann eine Zehnerpotenz angegeben werden:&lt;br /&gt;
 floatVariable2 = -1.234E-6;&lt;br /&gt;
Dadurch wird der erst Wert mit 10&amp;lt;sup&amp;gt;&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;6&amp;lt;/sup&amp;gt; multipliziert, der Wert der Variablen ist also &lt;br /&gt;
:&amp;lt;math&amp;gt;-1{,}234\cdot10^{-6} = -0.000001234&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei logischen Variablen==&lt;br /&gt;
Wie bereits erwähnt, besitzt C keinen logischen Datentyp. Es müssen also &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; dafür genutzt werden. Die Zuweisung entpricht der Standard-Zuweisung. Wird der Wert 0 zugewiesen, dann ist die Variable &amp;quot;unwahr&amp;quot;, ansonsten ist sie &amp;quot;wahr&amp;quot;. &lt;br /&gt;
 intVariable = !0;   /* entspricht &amp;quot;wahr&amp;quot;   */&lt;br /&gt;
 intVariable = 0;    /* entspricht &amp;quot;unwahr&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
==Konstanten==&lt;br /&gt;
Konstanten können als Variable angesehen werden, die nicht beschrieben, sondern nur gelesen werden können. Ein typisches Beispiel dafür ist die Zahl &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; (rund 3,141592654). Niemand würde in der realen Welt versuchen, ihr einen anderen Wert zuzuweisen. Würde man &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; jedoch wie eine normale Variable anlegen, wäre dies ohne weiteres möglich. Um dies zu verhindern, gibt es das Schlüsselwort &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in C:&lt;br /&gt;
 const {{Type}} {{Bezeichner}} = {{Konstante}};  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Wichtig dabei ist, dass man Konstanten nur bei der Vereinbarung einen Wert zuweisen kann. &lt;br /&gt;
Da Konstanten gewöhnlich im gesamten Programm, zumindest einer Quelldatei genutzt werden, definiert man diese allerdings gewöhnlich außerhalb des main-Blockes entweder am Anfang eines Programmes, oder in einer sogenannten Header-Datei, die per &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; eingebunden wird.&lt;br /&gt;
 const float PI = 3.141592;  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Es sei jedoch erwähnt, daß auch einer Konstanten nachträglich ein anderer Wert zugewieden werden kann. Im obigen Beispiel könnte mit&lt;br /&gt;
 * ((float*) &amp;amp;PI) = 2;&lt;br /&gt;
der Wert von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; im Nachhinein verändert werden. Es wird die Adresse von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; genommen und diese Adresse durch den Cast in eine ganz normale &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;-Adresse umgewandelt, über welche der Wert geändert wird. Die sei der Vollständigkeit halber erwähnt.&lt;br /&gt;
&lt;br /&gt;
Je nachdem, an welcher Stelle sich das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; bei einer Pointer-Deklaration befindet, markiert es den Pointer als konstant oder das Objekt, auf das dieser Pointer zeigt. Eine häufige Parameterdeklaration in Ausgabe-Funktionen, die einen String erhalten, ist&lt;br /&gt;
 void foo (const char * str, ...);&lt;br /&gt;
Dadurch ist &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; der Zeiger auf eine Zeichenkette, die innerhalt der Funktion nicht verändert wird bzw. verändert werden darf. Eine Zuweisung wie &amp;lt;tt&amp;gt;*str = 'a'&amp;lt;/tt&amp;gt; ergibt also einen Fehler. &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; selbst kann aber sehr wohl verändert werden, etwa mit &amp;lt;tt&amp;gt;str++&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Soll ausgedrückt werden, daß &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; unveränderlich ist, dann so:&lt;br /&gt;
 void foo (char * const str, ...);&lt;br /&gt;
Jetzt wäre eine Änderung des Strings in Ordnung, etwa durch &amp;lt;tt&amp;gt;str[10] = 'a'&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Um sich zu merken, worauf das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; wirkt, trennt man die Deklaration in Gedanken beim&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf: Steht das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; links vom&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, dann gehört es zum &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, steht es rechts davon, dann gehört es zum Pointer. Natürlich ist es auch denkbar, beides &amp;amp;ndash; also den Zeiger und sein Ziel &amp;amp;ndash; als konstant zu markieren.&lt;br /&gt;
&lt;br /&gt;
==Gültigkeitsbereich==&lt;br /&gt;
In C können mehrere Variablen den gleichen Namen haben, solange eindeutig ist, welche in welchen Block gültig ist. Dabei gelten folgende Regeln: &lt;br /&gt;
&lt;br /&gt;
;Lokale Variablen: sind Variablen, die innerhalb eines Blockes definiert werden. Jede Variable ist nur in dem Block gültig, in dem sie vereinbart wurde, sowie in allen darin enthaltenen Blöcken; es sei denn, in einem Unter-Block wird eine Variable gleichen Namens definiert. Dann bezieht sich in diesem Unter-Block der Bezeichner auf die im Unter-Block angelegte Variable.&lt;br /&gt;
;Globale Variablen: werden ausserhalb jedes Blockes definiert und gelten ab der Stelle, an der sie deklariert werden, siehe auch [[#Deklaration und Definition|Deklaration und Definition]]. Wird jedoch in einem Block eine Variable gleichen Namens angelegt, gilt ab hier bis zum Ende des Blocks nicht mehr die globale Variable, sondern die im Block deklarierte. Das Spiel kann man weiterspielen: wird in einem Unter-Block wieder eine namensgleiche Variable angelegt, gilt diese in dem Unterblock.&lt;br /&gt;
&lt;br /&gt;
==Speicherklassen==&lt;br /&gt;
Jede Variable in C gehört zu einer bestimmten Speicherklasse&lt;br /&gt;
;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;: Lokale Variablen sind in aller Regal sogenannte ''automatische Variablen''. Das bedeutet, sie werden automatisch angelegt, wenn ein Block bzw. eine Funktion betreten wird und danach wieder entfernt. Das Schlüsselwort &amp;quot;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;&amp;quot; wird praktisch nie hingeschrieben, denn lokale Variablen ohne die ausdrückliche Angabe einer Speicherklasse, sind automatisch automatische Variablen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;: Eine externes Symbol ist im ganzen Programm bekannt bzw. in dem Block, in der die Deklaration steht. In unterschiedlichen Blöcken stehende Deklarationen beziehen sich auf das gleiche Symbol! Obgleich das Datum global zugreifbar ist, ist der Gültigkeitsbereich auf den deklarierenden Block begrenzt bzw. auf das deklarierende Quell-Modul, sofern das Symbol ausserhalb jedes Blocks des Moduls deklariert wird. Siehe auch [[#Deklaration und Definition|Deklaration und Definition]].&lt;br /&gt;
;&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;: Die Variable ist im Block gültig bzw. im Quell-Modul (also in der C-Datei, in der die angelegt wurde), wenn sie nicht innerhalb eines Blockes angelegt wurde. Statische Variablen werden nicht in Registern oder im Frame der Funktion angelegt, sondern im selben Speicherbereich, in dem auch die globalen Variablen liegen; Konstanten evtl. auch im Flash. Eine lokale Variable, die als &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; angelegt wird, &amp;quot;überlebt&amp;quot; also das Verlassen des Blocks und hat beim neuerlichen Betreten des Blockes ihren bisherigen Wert. In unterschiedlichen Blöcken angelegte lokale statische Variablen beziehen sich auf unterschiedliche Speicherstellen, genau wie bei lokalen Variablen auch.&lt;br /&gt;
;&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;: Durch diese Speicherklasse wird eine Variable &amp;amp;ndash; falls möglich &amp;amp;ndash; als Registervariable angelegt, also in einem Maschinenregister des Computer/Controllers gehalten. Dadurch kann auf solche Variablen besonders schnell zugegriffen werden. Dieses Schlüsselwort ist bei modernen Compilern weitgehend überflüssig, da die entsprechenden Optimierungen selbständig vorgenommen werden, wenn ausreichend Register vorhanden sind. Auch globale Variablen können als Register angelegt werden, davon ist dem Anfänger aber dringend abzuraten, weil leicht schwerauffindbare Fehler und Abstürze auftreten, wenn man nicht genau weiss, welche Implikationen in einer solchen Definition stecken!&lt;br /&gt;
;&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;: (FIXME: volatile ist ein Qualifier und keine Speicherklasse) Dies ist das genaue Gegenteil von &amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt; und bewirkt, dass die Variable auf keinen Fall in einem Register zwischengespeichert werden darf, sondern immer aus dem RAM gelesen und ins RAM geschrieben werden soll. &amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt; müssen alle ''globalen'' Variablen markiert werden, die in [[ISR | Interrupt-Handlern]] verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Ausdrücke=&lt;br /&gt;
Eine Variable oder eine Konstante in C stellen einfache Ausdrücke dar.&lt;br /&gt;
Diese elementaren Ausdrücke können durch Operatoren miteinander verknüpft werden und so zu neuen, komplexeren Ausdrücken zusammen gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Einfache Beispiele für Ausdrücke sind also z.B.:&lt;br /&gt;
 1&lt;br /&gt;
 a&lt;br /&gt;
 'a'&lt;br /&gt;
 1 + a&lt;br /&gt;
 a == 1&lt;br /&gt;
&lt;br /&gt;
Auch Funktionen können einen Wert zurückliefern und in Ausdrücken weiter benutzt werden.&lt;br /&gt;
In den folgenden Abschnitten wird gezeigt, welche Operatoren in C vorhanden sind,&lt;br /&gt;
und wei man damit neue Ausdrücke aufbauen kann.&lt;br /&gt;
&lt;br /&gt;
==Lvalues==&lt;br /&gt;
&lt;br /&gt;
Ein Lvalue in C ist ein Ausdruck, dem ein anderer Ausdruck zugewiesen werden kann, dessen Wert also durch eine Zuweisung verändert werden kann.&lt;br /&gt;
das 'L' leitet sich ab von 'left' bwz. 'links' und das 'value' bedeutet Wert: Ein Lvalue ist ein Ausdruck, der auf der linken Seite einer Zuweisung stehen darf. Ein Lvalue ist also immer auch ein gültiger Ausdruck, aber die Umkehrung gilt in alles Regel nicht.&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für einen Lvalue ist eine &amp;quot;normale&amp;quot; Variable, die nicht mit &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; als Konstante markiert ist:&lt;br /&gt;
 a = 1;&lt;br /&gt;
Hingegen ist der Ausdruck &amp;lt;tt&amp;gt;a+1&amp;lt;/tt&amp;gt; kein Lvalue, denn eine Zuweisung wie&lt;br /&gt;
 a+1 = 2;&lt;br /&gt;
die mathematisch durchaus sinnvoll ist, erzeugt einen Compilerfehler, der etwa lauten könnte &amp;quot;illegal lvalue in assignment&amp;quot;:&lt;br /&gt;
&amp;quot;ungültiger Wert in Zuweisung&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Andere Beipiele für Lvalues sind die Komponenten von (nicht-konstanten) [[#Strukturen|Strukturen]] und [[#Unions|Unions]], [[#Arrays|Array]]-Elemente und die Dereferenzierungen von Pointern: Die Konstante&amp;amp;nbsp;4 wird durch den Cast in eine Adresse umgewandelt. Über die Dereferenzierung&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; wird an die Adresse&amp;amp;nbsp;4 im Speicher eine&amp;amp;nbsp;3 geschrieben. Ob das erlaubt bzw. sinnvoll ist, ist abhängig von der jeweiligen Architektur.&lt;br /&gt;
 * ((unsigned int *) 4) = 3;&lt;br /&gt;
Hier ist der gesamte &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;-Ausdruck ein Lvalue&lt;br /&gt;
&lt;br /&gt;
==Logische (boolsche) Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp;amp;&amp;amp;amp; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr oder &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; || gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; || ungleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;= b&amp;lt;/tt&amp;gt; || kleiner oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt; b&amp;lt;/tt&amp;gt; || kleiner als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt;= b&amp;lt;/tt&amp;gt; || glösser oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt; b&amp;lt;/tt&amp;gt; || grösser als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; nicht wahr und vice versa&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine interessante Eigenschaft der Operatoren &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;amp;amp;&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; ist, dass&lt;br /&gt;
sie die Auswertung abbrechen, sobald das Ergebnis feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet. Ein oft anzutreffendes Codestück sieht so aus, dabei sei &amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
  if (p &amp;amp;&amp;amp; *p == 5)&lt;br /&gt;
  {&lt;br /&gt;
     {{comment|mach was}}&lt;br /&gt;
  }&lt;br /&gt;
Zuerst wird in der Bedinung geprüft, ob Zeiger&amp;amp;nbsp;&amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; einen Wert ungleich Null hat, also ob er überhaupt einen gültigen Wert enthält. Es ist weit verbreitete Konvention in C, daß Zeiger, die keinen gültigen Wert haben, die Adresse&amp;amp;nbsp;0 enthalten. '''Nur dann, wenn ein Zeiger nicht ein Null-Pointer ist, darf überhaupt ein Zugriff über ihn erfolgen!'''&lt;br /&gt;
&lt;br /&gt;
==Vergleich von Variablen==&lt;br /&gt;
Skalare Variablen (also ganze Zahlen, Gleitkommazahlen, Zeiger) können miteinander verglichen werden. Dazu gibt es die folgenden Operatoren in C: &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; || ist nicht gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;=&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;=&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das Ergebnis der Auswertung ist eine ganze Zahl. Ist die Bedingung erfüllt, dann ist der Wert ungleich&amp;amp;nbsp;0. Ist die Bedingung nicht erfüllt, dann ist ihr Wert gleich&amp;amp;nbsp;0.&lt;br /&gt;
Meistens wird man diese Operatoren in &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Konstrukten finden wie zum Beispiel&lt;br /&gt;
 if (x &amp;gt;= 10)&lt;br /&gt;
    x = 10;&lt;br /&gt;
oder in Abbruchbedingungen von Schleifen, wie sie weiter unten erklärt werden.&lt;br /&gt;
&lt;br /&gt;
Es ist auch möglich, das Ergebnis der Auswertung in einer &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Variablen zu speichern:&lt;br /&gt;
 int i;&lt;br /&gt;
 int z1, z2;&lt;br /&gt;
 &lt;br /&gt;
 z1 = 5;&lt;br /&gt;
 z2 = 100;&lt;br /&gt;
 i = z1 &amp;lt;= z2;  {{comment|Ein Vergleich. i wird &amp;quot;wahr&amp;quot;, da z1 kleinergleich z2 ist}}&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich&amp;amp;nbsp;0 (&amp;quot;wahr&amp;quot;), wenn &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; kleiner oder gleich &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt; ist. Ist &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; jedoch größer als &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt;, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich&amp;amp;nbsp;0 (&amp;quot;unwahr&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
==Arithmetische Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a + b&amp;lt;/tt&amp;gt; || Summe (Addition)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a - b&amp;lt;/tt&amp;gt; || Differenz (Subtraktion)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a * b&amp;lt;/tt&amp;gt; || Produkt (Multiplikation)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a / b&amp;lt;/tt&amp;gt; || Quotient (Division, evtl. mit Rest)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a % b&amp;lt;/tt&amp;gt; || Rest bei Division (Modulo)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;-a&amp;lt;/tt&amp;gt; || Vorzeichenumkehr (Zweierkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Bit-Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp; b&amp;lt;/tt&amp;gt; || bitweise und (and)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || bitweise oder (or)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a ^ b&amp;lt;/tt&amp;gt; || bitweise exclusiv-oder (xor, exor)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;~a&amp;lt;/tt&amp;gt; || jedes Bit in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; invertieren (not, Einerkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Index-Operator bei Arrays==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a[b]&amp;lt;/tt&amp;gt; || das (b+1)ste Element des Feldes a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Folgendes gilt es bei der Verwendung des Indexoperators zu beachten:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; muss ein [[C-Tutorial#Felder | Feld]] oder [[C-Tutorial#Zeiger | Zeiger]] sein&lt;br /&gt;
# &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; muss ein Integer sein oder ein Datentyp, der sich in einen int umwandeln läßt (z.B. char)&lt;br /&gt;
# Es wird nicht geprüft, ob der Index &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; im Feld &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gültig ist!&lt;br /&gt;
# Der erste Index eines Feldes ist immer 0. Daher ''(b+1)stes Element'' in der Beschreibung&lt;br /&gt;
&lt;br /&gt;
==Komponenten-Auswahl bei Structs und Unions==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a.b&amp;lt;/tt&amp;gt; || Element b der [[C-Tutorial#Strukturen | Struktur]] oder des Unions a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adress-Operator und Dereferenzierung==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&amp;amp;amp;a&amp;lt;/tt&amp;gt; || Speicheradresse der Variablen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;*a&amp;lt;/tt&amp;gt; || Wert, der an der Adresse &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a-&amp;amp;gt;b&amp;lt;/tt&amp;gt; || Wert des Elements &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; der Struktur, deren Adresse in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Adressoperator &amp;amp; kann auf Variablen angewendet werden und&lt;br /&gt;
gibt die Startadresse der Variablen im Speicher zurück.&lt;br /&gt;
&lt;br /&gt;
Handelt es sich bei einer Variable um einen [[C-Tutorial#Zeiger | Zeiger]], so enthält&lt;br /&gt;
sie eine Speicheradresse. Um an den '''Wert''' zu gelangen, der&lt;br /&gt;
an dieser Adresse steht, wird der Operator * vorangestellt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
&lt;br /&gt;
 {{comment|x ist eine Integervariable und hat den Wert 5}}&lt;br /&gt;
 int x = 5;&lt;br /&gt;
     &lt;br /&gt;
 {{comment|z ist ein Zeiger auf eine Integer-Variable und enthaelt somit}}&lt;br /&gt;
 {{comment|die Speicheradresse einer Integer-Variablen}}&lt;br /&gt;
 int *z;       &lt;br /&gt;
  &lt;br /&gt;
 {{comment|Verwendung des Adress-Operators: weist an z die Adresse von x zu}}&lt;br /&gt;
 z = &amp;amp;x;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Verwendung der Dereferenzierung}}&lt;br /&gt;
 {{comment|erhoehe den Wert, der bei Adresse z steht, um eins}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|da z auf x zeigt, hat x jetzt den Wert 6}}&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff auf Struktir- und Union-Elemente eine abkürzende Schreibweise möglich:&lt;br /&gt;
&lt;br /&gt;
Statt &lt;br /&gt;
  (*strukturZeiger).element&lt;br /&gt;
kann geschrieben werden&lt;br /&gt;
  strukturZeiger-&amp;gt;element&lt;br /&gt;
Beide Schreibweisen sind absolut gleichbedeutend, die Klammern bei der ersteren sind notwendig.&lt;br /&gt;
&lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
:Bei der Dereferenzierung durch &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; findet keine Prüfung statt, ob der Zeiger auch auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu einer Änderung '''irgendeiner''' Speicherstelle!&lt;br /&gt;
&lt;br /&gt;
 int *z; {{comment|z ist ein Zeiger auf einen int}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.}}&lt;br /&gt;
 {{comment|z enthaelt irgendeine ungueltige Adresse!!}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|&amp;quot;Erhoehe einen Integer _irgendwo_ im Speicher um 1&amp;quot; -&amp;gt; CRASH !!!}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
&lt;br /&gt;
==Cast-Operator==&lt;br /&gt;
&lt;br /&gt;
Der Cast Operator dient dazu, den Datentyp eines Wertes zu ändern. Dafür wird einfach der neue Datentyp in Klammern vor den Wert geschrieben.&lt;br /&gt;
&lt;br /&gt;
Um zum Beispiel aus einem Float ein Integer zu machen:&lt;br /&gt;
 var  = (int) 5.60;&lt;br /&gt;
Dabei wird der Wert aber auch gerundet, und es findet somit ein Informationsverlust statt.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Umwandeln einer ganzen Zahl in eine Adresse:&lt;br /&gt;
 int * addr;&lt;br /&gt;
 addr = (int*) 0x1234;&lt;br /&gt;
Damit ist &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; an Adresse 0x1234.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
Der Cast-Operator selbst führt ''keine Konvertierung'' von Darstellungen durch, etwa die Umwandlung der ganzen Zahl 123 ein den String &amp;lt;tt&amp;gt;&amp;quot;123&amp;quot;&amp;lt;/tt&amp;gt;, der diese Zahl darstellt! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
  int main(int argc, char ** argv)&lt;br /&gt;
  {&lt;br /&gt;
        char text[] = &amp;quot;5.6&amp;quot;;&lt;br /&gt;
        int zahl = (int) text;&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, zahl);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Anfangsadresse des Strings &amp;lt;tt&amp;gt;&amp;quot;5.6&amp;quot;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Komma-Operator==&lt;br /&gt;
Mit einem &amp;lt;tt&amp;gt;,&amp;lt;/tt&amp;gt; können mehrere Ausdrücke nacheinander ausgewertet werden.&lt;br /&gt;
Die Auswertung erfolgt von links nach rechts.&lt;br /&gt;
&lt;br /&gt;
Solche Konstrukte sieht man manchmal in Abfragen wie&lt;br /&gt;
 FILE  *file;&lt;br /&gt;
 if (file = fopen (&amp;quot;foo.exe&amp;quot;, &amp;quot;r&amp;quot;), file != NULL)&lt;br /&gt;
was erst an &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; einen Wert zuweist und den &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Block nur betritt,&lt;br /&gt;
wenn &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; nicht der Nullpointer ist.&lt;br /&gt;
&lt;br /&gt;
Bequem kann das auch in einer [[#for-Schleife|for-Schleife]] sein, wenn man zwei (oder mehr) Laufvariablen hat oder so:&lt;br /&gt;
 for (i=0, j=0; i &amp;lt; 10; i++, j += 2)&lt;br /&gt;
    &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Zuweisung===&lt;br /&gt;
=== ++ und -- ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; stellen einfachere Schreibweisen dar zum Addieren bzw. Subtrahieren von&amp;amp;nbsp;1.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; (Inkrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo++; &lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo + 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; 3}}&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; (Dekrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo--;&lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo - 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; -1}}&lt;br /&gt;
&lt;br /&gt;
Die beiden Operatoren können sowohl in der Präfix-Schreibweise (vor der Variablen) als auch als Postfix-Schreibweise (hinter der Variablen) notiert werden. &lt;br /&gt;
Der Unterschied liegt darin, dass beim Präfix der Wert zuerst neu berechnet wird und die Variable dann verwendet wird. Beim Postfix wird die Variable zuerst verwendet und erst nach Auswertung des Ausdrucks, in dem sie enthalten ist, neu berechnet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 int ausgabe1, ausgabe2, var1 = 10, var2 = 10;&lt;br /&gt;
 ausgabe1 = 3 * ++var1; {{comment|ausgabe1 &amp;amp;#61; 33; var1 &amp;amp;#61; 11;}}&lt;br /&gt;
 ausgabe2 = 3 * var2++; {{comment|ausgabe2 &amp;amp;#61; 30; var2 &amp;amp;#61; 11;}}&lt;br /&gt;
&lt;br /&gt;
Für Zeiger arbeiten diese Operatoren etwas anders, siehe dazu [[#Zeiger-Arithmetik|Zeiger-Arithmetik]].&lt;br /&gt;
&lt;br /&gt;
===Bedingter Ausdruck===&lt;br /&gt;
 ({{Bedingung}}) ? {{Ausdruck|1}} : {{Ausdruck|2}}&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; erfüllt ist, dann wertet dieser Ausdruck aus zu &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt;. Ist er nicht erfüllt, dann wertet er aus zu &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 x = (x &amp;gt;= 3) ? 0 : x+1;&lt;br /&gt;
Startet man &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; mit dem Wert 0, dann nimmt es bei mehrfacher Anwendung dieser Zeile (z.B. in einer Schleife) nacheinander die folgende Werte an:&lt;br /&gt;
:&amp;lt;tt&amp;gt;1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, ...&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&lt;br /&gt;
Wie auch in der Mathematik gibt es auch in C genaue Regeln über die Abarbeitungsreihenfolge (precedence)&lt;br /&gt;
der Operatoren. Dass sich alle C-Compiler genau an diesen ANSI-Vorschlag halten, ist leider nicht sicher.&lt;br /&gt;
Sicher jedoch ist, dass nicht jeder Programmierer diese Regel jederzeit im Kopf hat. &lt;br /&gt;
Daher ist es sinnvoll, Ausdrücke durch runde Klammern eindeutig zu kennzeichnen. &lt;br /&gt;
Nebenbei stören sich Compiler nicht an überflüssigen Klammerpaaren.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Priorität ||Operator||Assoziativität&lt;br /&gt;
|-&lt;br /&gt;
  &lt;br /&gt;
|&amp;lt;tt&amp;gt;15&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ( ) [ ] -&amp;gt; . &amp;lt;/tt&amp;gt;                      ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;14&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;! ~ ++ -- + - (TYP) * &amp;amp; sizeof &amp;lt;/tt&amp;gt;    ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;13&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; * / % (Rechenoperationen) &amp;lt;/tt&amp;gt;         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;12&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; + - (binär) &amp;lt;/tt&amp;gt;                       ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;11&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;&amp;lt; &amp;gt;&amp;gt; &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;10&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt; &amp;lt;= &amp;gt; &amp;gt;= &amp;lt;/tt&amp;gt;                         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 9&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; == != &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 8&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp; (bit-AND-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 7&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ^ (bit-XOR-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 6&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; (bit-OR-Operator)&amp;lt;/tt&amp;gt;   ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 5&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp;&amp;amp; &amp;lt;/tt&amp;gt;                                ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 4&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; &amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 3&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;? : &amp;lt;/tt&amp;gt;                               ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 2&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; = += -= /= *= %= &amp;gt;&amp;gt;= &amp;lt;&amp;lt;= &amp;amp;= &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;= ^= &amp;lt;/tt&amp;gt; ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 1&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; , (Sequenz-Operator) &amp;lt;/tt&amp;gt;              ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
&lt;br /&gt;
Peter Baeumle-Courth, ANSI-C im Überblick &amp;lt;p&amp;gt;&lt;br /&gt;
W. Alex, Einführung in C/C++&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
Eine Kontrollanweisung ist eine Anweisung, die Einfluss auf den Programmfluss hat. Normalerweise werden Anweisungen so ausgeführt, wie sie in der Quelldatei stehen: Von links nach rechts (falls mehrere Anweisungen in einer Zeile stehen sollten, wovon i.A. abzuraten ist) und von oben nach unten. Mit einer Kontrollanweisung kann dieser lineare Programmfluss durchbrochen werden: Die Codeausführung kann kann abhängig von einer Bedingung gemacht werden (&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;), kann wiederholt werden (Schleife) oder an einer anderen Stelle der Funktion fortgesetzt werden (&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==if-Anweisung==&lt;br /&gt;
Mit Hilfe des if-Befehls kann man Codeteile abhängig davon einer Bedingung ausführen lassen:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
oder mit else-Teil&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 if (x &amp;gt; 100)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;gt; 100 ist: Fehlerausgabe}}&lt;br /&gt;
    printf (&amp;quot;x = %d ist zu gross fuer die Berechnung!\n&amp;quot;, x);&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;lt;&amp;amp;#61; 100 ist: Berechne Summe der Zahlen 1...x}}&lt;br /&gt;
    {{comment|Die lokale Variable x2 lebt nur innerhalb dieses alse-Blocks}}&lt;br /&gt;
    int x2 = x;&lt;br /&gt;
 &lt;br /&gt;
    for (x = 0; x2 &amp;gt; 0; x2--)&lt;br /&gt;
       x += x2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Wenn die Bedingung wahr ist (&amp;lt;tt&amp;gt;x &amp;gt; 100&amp;lt;/tt&amp;gt;), dann wird eine Meldung ausgegeben; danach ist die if-Anweisung beendet. Der else-Block wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung nicht erfüllt (&amp;lt;tt&amp;gt;x &amp;amp;le; 100&amp;lt;/tt&amp;gt;), dann wird gleich zum else-Teil gesprungen, und nach dessen Ausführung der if-Befehl beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Ein häufiger Fehler ist es, statt &amp;lt;tt&amp;gt;if (a &amp;amp;#61;&amp;amp;#61; 23)&amp;lt;/tt&amp;gt; etwas wie &amp;lt;tt&amp;gt;if (a &amp;amp;#61; 23)&amp;lt;/tt&amp;gt; zu schreiben. &lt;br /&gt;
Dann wird allerdings nicht geprüft, ob die Variable&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gleich 23 ist, sondern der Variablen&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wird der Wert 23 zugewiesen. Der Ausdruck &amp;lt;tt&amp;gt;a &amp;amp;#61; 23&amp;lt;/tt&amp;gt; hat den Wert&amp;amp;nbsp;23 und ist damit immer &amp;quot;wahr&amp;quot;! Daher ist diese if-Bedingung immer erfüllt!&lt;br /&gt;
&lt;br /&gt;
Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken sondern bestenfalls eine Warnung. Damit ist dieser Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise &amp;lt;tt&amp;gt;if (23 &amp;amp;#61;&amp;amp;#61; a)&amp;lt;/tt&amp;gt;. Wenn man dort anstatt des Vergleichsoperators '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;amp;#61;&amp;lt;/tt&amp;gt;' den Zuweisungsoperator '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;lt;/tt&amp;gt;' verwendet, spuckt der Compiler sehr wohl einen Fehler aus! Ist die Zuweisung jedoch erwünscht und eine Compiler-Warnung lästig, dann wählt man eine Schreibweise wie &amp;lt;tt&amp;gt;if ((a &amp;amp;#61; b))&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;if (a &amp;amp;#61; b, a)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist zu schreiben &amp;lt;tt&amp;gt;if (Bedingung);&amp;lt;/tt&amp;gt; Richtig muss es heissen &amp;quot;&amp;lt;tt&amp;gt;if(Bedingung)&amp;lt;/tt&amp;gt;&amp;quot; Das Semikolon im ersten Fall ist eine leere Anweisung, die im if-Falle ausgeführt wird &amp;amp;ndash; sie bleibt also ohne Resultet. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt; ein auf das Semikolon folgende Anweisung die eigentlich zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören soll wird immer ausgeführt, die sie nicht mehr zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; dazu gehört.&lt;br /&gt;
}}&lt;br /&gt;
Bei verschachtelten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Konstrukten gehört ein &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zu letzten &amp;quot;freien&amp;quot; &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;. Soll in einer &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Folge das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zum ersten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören, dann ist das so zu hinzuschreiben:&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Ohne die geschweiften Klammern um das zweite &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehörte das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; dort hinzu.&lt;br /&gt;
&lt;br /&gt;
==switch-Anweisung==&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
&lt;br /&gt;
 switch ({{Ausdruck|}}) &lt;br /&gt;
 {&lt;br /&gt;
     case konstante1:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
    &lt;br /&gt;
     case konstante2:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 &lt;br /&gt;
     {{comment|weitere case-Marken}}&lt;br /&gt;
 &lt;br /&gt;
     default:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 } {{comment|Ende von switch}} &lt;br /&gt;
&lt;br /&gt;
Der Ausdruck muss ein skalarer Typ sein, er wird in die nächste ganze Zahl gewandelt und mit den Werten hinter den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Marken verglichen. Bei einer Übereinstimmung werden alle Befehle ab dem zutreffenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; ausgeführt. Stimmt der Ausdruck mit keinem der Werte überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt falls vorhanden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der nachfolgenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;- und des &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitts werden ausgeführt, wenn die Anweisungen des &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitts nicht mit dem Befehl &amp;lt;tt&amp;gt;break;&amp;lt;/tt&amp;gt; beendet werden!&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es dürfen beliebig viele &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitte angegeben werden, pro Vergleichswert jedoch nur einer.&lt;br /&gt;
Der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ist optional. Die Reihenfolge, in der &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt; angegeben werden, ist unerheblich.&lt;br /&gt;
&lt;br /&gt;
==Schleifen==&lt;br /&gt;
Um Anweisungen mehrmals hintereinander auszuführen, benötigt man Schleifen. Diese führen Anweisungen aus, bis oder solange Bedingungen erfüllt sind.&amp;lt;br&amp;gt; &lt;br /&gt;
Wichtig ist also, ob die Bedingung '''vor''' oder '''nach''' den Schleifen-Anweisungen geprüft wird. &lt;br /&gt;
&lt;br /&gt;
===while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 while ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Die while-Schleife wird solange durchlaufen, wie die Bedingung erfüllt ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Die Anweisung kann natürlich auch ein Block sein, der aus mehreren Deklarationen und Anweisungen besteht. &lt;br /&gt;
&lt;br /&gt;
 int zahl1 = 0;&lt;br /&gt;
 int zahl2 = 1;&lt;br /&gt;
 &lt;br /&gt;
 while (zahl1 &amp;lt; 3)&lt;br /&gt;
 {&lt;br /&gt;
    zahl1 = zahl1 + 1;&lt;br /&gt;
    zahl2 = zahl2 * 2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife drei mal durchlaufen. Zu Beginn des vierten Durchlaufs ist die Bedingung nicht mehr erfüllt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
&lt;br /&gt;
===do-while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
Die do-while-Schleife wird auf jeden Fall einmal durchlaufen und dann solange wiederholt, wie die Bedingung erfüllt ist.&lt;br /&gt;
 int i = 2;&lt;br /&gt;
 &lt;br /&gt;
 do &lt;br /&gt;
 {&lt;br /&gt;
     i = i*i;   {{comment|i quadrieren}}&lt;br /&gt;
     printf (&amp;quot;i = %d\n&amp;quot;, i);&lt;br /&gt;
 }&lt;br /&gt;
 while (i &amp;lt; 20);&lt;br /&gt;
&lt;br /&gt;
Die Schleife wird durchlaufen und wiederholt, solange &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; kleiner als 20 ist. Es werden also nacheinander die Werte 2, 4 und 16 ausgegeben. Nach der Schleife hat&amp;amp;nbsp;&amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; den Wert 256.&lt;br /&gt;
&lt;br /&gt;
===for-Schleife===&lt;br /&gt;
'''Syntax:''' &lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Bei den Ausdrücken wird es sich um einen Ausdrücke mit Nebeneffekt handeln wie etwa &amp;lt;tt&amp;gt;i=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;i=i+2&amp;lt;/tt&amp;gt;. Es werden folgende Aktionen ausgeführt:&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# falls die Bedingung wahr ist, dann führe &amp;lt;tt&amp;gt;Anweisung&amp;lt;/tt&amp;gt; aus.&lt;br /&gt;
# falls die Bedingung unwahr ist, dann sprinte zu 7 (Ende).&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# gehe zu 2&lt;br /&gt;
# nächste Anweisung nach der for-Schleife&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int lauf, summe;&lt;br /&gt;
 &lt;br /&gt;
 for (lauf=1, summe=0; lauf &amp;lt;= 10; lauf += 2) &lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel ist &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; ein [[#Komma-Operator|Komma-Ausdruck]], der zwei Anweisungen kombiniert und daher sogar zwei Nebeneffente hat: er setzt &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;1 und &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;0.&lt;br /&gt;
&lt;br /&gt;
Das Äquivalent als while-Schleife:&lt;br /&gt;
&lt;br /&gt;
 int lauf  = 1;                 {{comment|Anfangswerte}}&lt;br /&gt;
 int summe = 0;&lt;br /&gt;
 &lt;br /&gt;
 while (lauf &amp;lt;= 10)             {{comment|Bedingung}}&lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
    lauf  += 2;                 {{comment|Inkrement}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; in jedem Schleifendurchlauf um die Laufvariable &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; erhöht. Da &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nacheinander die ungeraden Werte von&amp;amp;nbsp;1 bis&amp;amp;nbsp;10 annimmt, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von&amp;amp;nbsp;1 bis kleinergleich 10 gespeichert, also der Wert&amp;amp;nbsp;25. &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; hat nach der Schleife den Wert&amp;amp;nbsp;11.&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf = 1&amp;lt;/tt&amp;gt; bedeutet, dass der Variablen &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; vor dem ersten Schleifendurchlauf der Wert&amp;amp;nbsp;1 zugewiesen wird. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf &amp;lt;= 10&amp;lt;/tt&amp;gt; ist die Schleifenbedingung; ist sie nicht erfüllt, wird die Schleife beendet. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf += 2&amp;lt;/tt&amp;gt; bedeutet, dass &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nach jedem Durchlauf um&amp;amp;nbsp;2 erhöht wird.&lt;br /&gt;
&lt;br /&gt;
===continue-Anweisung===&lt;br /&gt;
Innerhalb einer Schleife darf die &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die nachfolgenden Anweisungen übersprungen werden und mit dem nächsten Schleifendurchlauf fortgesetzt wird &amp;amp;ndash; vorausgesetzt die Schleifenbedingung ist noch erfüllt. Ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; etc. stehen, wenn dieses innerhalb einer Schleife steht.&lt;br /&gt;
&lt;br /&gt;
==break-Anweisung==&lt;br /&gt;
Innerhalb einer Schleife oder eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; darf die &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die Schleifen-/Switch-Anweisung sofort verlassen wird und das Programm dahinter weiter macht. Bei mehrfach geschachtelten Schleifen wird nur die innere verlassen. Ein &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; stehen, wenn dieses innerhalb einer Schleife/Switch-Anweisung steht.&lt;br /&gt;
&lt;br /&gt;
==goto-Anweisung==&lt;br /&gt;
&lt;br /&gt;
Innerhalb ein und derselben Funktion kann mit &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; an eine andere Stelle gesprungen werden. Dazu gibt man hinter dem &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einen Bezeichner an, der dadurch als Label fungiert:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 goto {{Bezeichner}};&lt;br /&gt;
Die Bezeichner selbst steht irgendwo in der Funktion und wird dadurch zur Sprungmarke (Label), daß er von einem Doppelpunkt (und mindestens einer C-Anweisung, die auch leer sein darf) gefolgt wird.&lt;br /&gt;
&lt;br /&gt;
Das Beispiel durchsucht das 2-dimensionale &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array &amp;lt;tt&amp;gt;feld&amp;lt;/tt&amp;gt; mit den &amp;lt;tt&amp;gt;SIZE_X &amp;amp;times; SIZE_Y&amp;lt;/tt&amp;gt; Werten nach dem Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;. Wird er gefunden, dann wird die 2-fach geschachtelte Suchschleife verlassen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int x, y;&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y; y++)&lt;br /&gt;
       if (feld[x][y] == 0)&lt;br /&gt;
          goto done;&lt;br /&gt;
 {{Label|done:}};&lt;br /&gt;
&lt;br /&gt;
Der folgende Code hat die gleiche Funktion, arbeitet jedoch ohne &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int x, y;&lt;br /&gt;
 int found = 0; {{comment|FALSE}}&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X &amp;amp;&amp;amp; !found; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y &amp;amp;&amp;amp; !found; y++)&lt;br /&gt;
       found = (0 == feld[x][y]);&lt;br /&gt;
Der Nachteil der &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-losen Variante ist, daß man eine Variable, die merkt, ob das Suchziel gefunden wurde, mitschleppen und in ''jedem'' Schleifendurchlauf abtesten muss. Dies bedeutet einen höheren Programmier- und Laufzeitaufwand und ist nicht so klar formuliert wie das &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-Beispiel.&lt;br /&gt;
&lt;br /&gt;
Gleichwohl sei angemerkt, daß die Verwendung von &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einem gewissen Dogmatismus unterliegt, der sich wie folgt subsummieren liesse:&lt;br /&gt;
:''goto ist böse und sollte keinesfalls verwendet werden! Wer es dennoch tut, offenbart dadurch seinen schlechten Geschmach sowie mangelhafte C-Kenntnis.'' &amp;lt;div align=&amp;quot;right&amp;quot;&amp;gt;http://www.roboternetz.de/phpBB2/images/smiles/icon_wink.gif&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Funktionen=&lt;br /&gt;
Stellen Dir vor, Du hast eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben &amp;amp;ndash; was Dich Zeit beim Erstellen des Programms und Speicherplatz im ausführbaren Programm kostet &amp;amp;ndash; kannst Du den Code-Abschnitt in eine Funktion schreiben und diese von jeder Stelle des Programms aus verwenden. Die Hauptgründe, um Funktionen zu verwenden, sind:&lt;br /&gt;
;Wiederverwendung von Code: Mehrfach verwendete Codestücke müssen nicht mehrfach implementiert werden. Oft unterscheiden sich die Codesequenzen nur in Kleinigkeiten, die man der Funktion über Parameter mitteilen kann.&lt;br /&gt;
;Übersichtlichkeit: Ein gut gegliedertes C-Programm implementiert klar umrissene Aufgaben in einer Funktion, auch wenn diese Funktion nur einmal im Code aufgerufen wird! Dadurch bleibt der Code um die Aufrufstelle besser verständlich, und man kann auf verschiedenen &amp;quot;Ebenen&amp;quot; denken. Eine Funktion wie &amp;quot;Datei öffnen&amp;quot; kann recht komplex sein. Auf höherer Ebene interessieren die Innereien nicht mehr, man möchte sich um andere Dinge kümmern und will den Code an der Stelle garnicht sehen...&lt;br /&gt;
;Rekursive Funktionen: Eine Funktion kann sich auch selbst aufrufen. In dem Falle nennt man die Funktion ''rekursiv''. Zwar lässt sich das, was eine rekursive Funktion tut, auch mit anderen Mitteln formulieren, die keine rekursiven Funktionen brauchen, aber oft ist der rekursive Weg knackiger und klarer formulierbar als eine nicht-rekursiven Ansatz, auch wenn es etwas mehr Resourcen verbraucht.&lt;br /&gt;
;Modulare Programmierung: Funktionen können anhand ihres Aufgabenbereichs auf verschiedene C-Quellen &amp;amp;ndash; sogenannte ''Module'' &amp;amp;ndash; verteilt werden. Funktionen, die etwas mit dem USB-Bus anstellen, werden in einem anderen Modul sein als mathematische Funktionen. Dies erhöht die Übersichtlichkeit und vereinfacht die Entwicklung im Team.&lt;br /&gt;
;Bibliotheken: Standard-Funktionen wie das hier oft auftauchende &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; sind in Bibliotheken gespeichert. Wenn das eigene Programm übersetzt wird, dann müssen nicht mehr alle Standard-Funktionen übersetzt werden, sondern werden nur noch aus der Bibliothek gelesen und ihr Code zum Programm dazugelinkt. Die Bibliotheks-Funktionen wurden schon zu einem früheren Zeitpunkt compiliert und liegen in dieser compilerten Form in der Bibliothek. Das spart mächtig Entwicklungszeit. Man kann auch selbst solche Bibliotheken erstellen und in diversen Projekten wiederverwenden.&lt;br /&gt;
;Generische Programmierung: In C ist es möglich, einer Funktion eine andere Funktion zu übergeben. (Damit ist nicht gemeint, ihr deren ''Rückgabewert'' zu übergeben (was auch ginge), sondern ''die Funktion selbst'' wird als Parameter übergeben und kann aufgerufen werden.) Ein typisches Beispiel dafür sind Sortieralgorithmen. Einem Sortieralgorithmus kann es egal sein, ''was'' er sortiert. Er muss lediglich wissen, ''wie'' er das Zeug zu sortieren hat: aufsteigend, absteigend, als Zahl, in lexikographischer Ordnung, nach der Quersumme, Körper nach Oberfläche, Durchmesser, Gewicht oder Volumen... Diese Vergleichsfunktion, die für zwei Objekte entscheidet, welches davon &amp;quot;kleiner&amp;quot; ist, kann man dem Sortierer übergeben. Will er zwei Werte vergleichen, dann muss er nur die Vergleichsfunktion aufrufen, ohne zu wissen, was diese tut. Damit kann der Sortieralgorithmus unanhängig von den Objekten gehalten werden, mit denen er hantieren soll.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Definition==&lt;br /&gt;
&lt;br /&gt;
In der ''Definition'' der Funktion wird gesagt, welche Werte sie liefern kann, wie sie heisst (Bezeichner) und wieviele und welche Parameter sie hat. Danach folgt ihre Implementierung:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}} ({{Parameterliste}})&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 &lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
Für Funktionen, die keinen Wert zurückliefern, gibt es den speziellen Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der besagt, daß die Funktion nichts zurückgibt. Die einfachste denkbare Funktion ist eine solch void-Funktion. Sie bekommt keine Parameter, gibt nicht zurück und ihr Body ist leer:&lt;br /&gt;
 void dummy()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==return-Anweisung==&lt;br /&gt;
An jeder Stelle des Programmflusses einer Funktion kann diese mit &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; beendet werden.&lt;br /&gt;
&lt;br /&gt;
'''bei void-Funktionen:'''&lt;br /&gt;
 return;&lt;br /&gt;
'''Funktionen mit Rückgabe-Wert:'''&lt;br /&gt;
 return {{Ausdruck|}};&lt;br /&gt;
Die zweite Variante gibt an, welcher Wert zurückgegeben wird.&lt;br /&gt;
 int main (int argc, char * argv[])&lt;br /&gt;
 {&lt;br /&gt;
    if (argc &amp;lt; 2)&lt;br /&gt;
       return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
Falls die letzte Anweisung einer void-Funktion ein &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; ist, kann es auch weggelassen werden wie oben bei der Funktion &amp;lt;tt&amp;gt;dummy&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Aufruf==&lt;br /&gt;
Um die Funktion aufzurufen gibt man ihren Namen an, gefolgt von den durch Komma getrennten Argumenten in runden Klammern wie im Beispiel unten das&lt;br /&gt;
 quadrat (5) &lt;br /&gt;
Da &amp;lt;tt&amp;gt;quadrat&amp;lt;/tt&amp;gt; einen Wert liefert, kann man damit weiter rechnen wie mit einem normalen Ausdruck:&lt;br /&gt;
 if (quadrat (a) + quadrat (b) == quadrat (c))&lt;br /&gt;
    c = quadrat (quadrat (a)); {{comment|c &amp;amp;#61; a hoch 4}}&lt;br /&gt;
&lt;br /&gt;
;Ein Hinweis am Rande: &lt;br /&gt;
Der Name einer Funktion ohne die beiden runden Klammern ist der Pointer/Zeiger auf ihren Anfang.&lt;br /&gt;
Damit kann ein Funktionsname überall dort verwendet werden, wo Pointer/Zeiger &lt;br /&gt;
zulässig sind. Insbesondere kann er als Argument einer weiteren Funktion dienen. &lt;br /&gt;
&lt;br /&gt;
'''Quelle:'''&lt;br /&gt;
W. Alex, Einführung in C/C++&lt;br /&gt;
&lt;br /&gt;
==Rekursive Funktionen==&lt;br /&gt;
Eine Funktion die sich selbst &amp;amp;ndash; möglicheweise auch über andere Zwischenfunktionen &amp;amp;ndash; wieder selbst aufruft, wird als ''rekursive Funktion'' bezeichnet. In der Definition ist nichts besonderes zu beachten. Ist die Verschachtelungstiefe im laufenden Programm zu tief, dann gibt das natürlich Probleme, aber das gilt bei tief verschachtelten 'normalen' Funktionen abenso...&lt;br /&gt;
&lt;br /&gt;
Das Beispiel berechnet den Größten Gemeinsamen Teiler zweier Zahlen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int ggT (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
     if (0 == a)&lt;br /&gt;
        return b;&lt;br /&gt;
 &lt;br /&gt;
    return ggT (b % a, a);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Ein komplettes kleines Programm:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int quadrat (int param1)&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  zahl = param1 * param1;&lt;br /&gt;
  return zahl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl, ergebnis;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Bitte Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = quadrat (zahl);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, zahl, ergebnis);&lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, 5, quadrat (5));&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur ausserhalb von Blöcken. Geschachtelte Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen beim Aufruf die Klammern angeben werden:&lt;br /&gt;
 dummy();&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Prototypen==&lt;br /&gt;
Wie oben erwähnt, kann ein Unterprogramm an jeder beliebigen Stelle im Programm stehen. Damit ist jedoch eine Bedingung verknüpft: Das Unterprogramm muß in der Datei oberhalb des ersten Aufrufes definiert worden sein. Wenn Sie ein Unterprogramm in Zeile 10 zum ersten mal aufrufen, müssen Sie die Deklaration davor erledigt haben. Verstanden?&lt;br /&gt;
Um dies zu erreichen, gibt es zwei Möglichkeiten: &lt;br /&gt;
&lt;br /&gt;
Entweder Sie schreiben alle Unterprogramme vor &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; in die Datei. Dies muß jedoch wiederum so geschehen, dass Funktionen zum Zeitpunkt ihres Aufrufes bereits bekannt sind! &lt;br /&gt;
Wo dies nicht möglich ist (z.B. sich gegenseitig aufrufende Unterprogramme), oder wenn Sie das stört, müssen Sie Prototypen verwenden. &lt;br /&gt;
Wie definiert man nun Prototypen? Sie kopieren einfach die erste Zeile des Unterprogrammes (z.B. &amp;quot;&amp;lt;tt&amp;gt;void ausgeben (int zahl)&amp;lt;/tt&amp;gt;&amp;quot;), fügen einen Strichpunkt&amp;amp;nbsp;&amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;an und fügen es an einer geeigneten Stelle ein (so, dass alle Aufrufe später in der Datei kommen). &lt;br /&gt;
Solche Definitionen stehen gewöhnlich am Anfang der Quelldatei oder in einer Header-Datei, die eingebunden wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl);  /* Der Prototyp */&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
   ausgeben (12);&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl)   /* Die eigentliche Prozedur */&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Ausgabe: %d\n&amp;quot;, zahl);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Parameterübergabe==&lt;br /&gt;
&lt;br /&gt;
Alle Werte, die an Prozeduren und Funktionen übergeben werden, werden grundsätzlich '''kopiert'''.&lt;br /&gt;
Das hat folgende Auswirkungen:&lt;br /&gt;
&lt;br /&gt;
# Änderungen an einem Parameter in einer Funktion erscheinen ''nicht'' beim Aufrufer!&lt;br /&gt;
# Möchte man, dass eine Funktion einen Wert trotzdem dauerhaft ändern soll, so muss die Adresse des Wertes via [[#Zeiger|Zeiger]] übergeben werden.&lt;br /&gt;
# Werden [[#Strukturen|Strukturen]] übergeben, so wird von ihnen eine Kopie erstellt, was bei großen Strukturen viel Zeit und Arbeitsspeicher kostet. Deshalb wird häufig nur die Adresse von Strukturen übergeben, da die Adresse viel schneller und platzsparender als die Struktur selbst kopiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele:'''&lt;br /&gt;
 void erhoehe (int x)&lt;br /&gt;
 {&lt;br /&gt;
    x = x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe(a);&lt;br /&gt;
    {{comment|a ist immer noch 0}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Beim Aufruf von &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; wird eine Kopie des Wertes von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; (im Beispiel also 0) erstellt und der Prozedur als Parameter &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; übergeben. Weil dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat dies keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|erhoehe den Wert an der Adresse x um eins}}&lt;br /&gt;
    *x = *x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe (&amp;amp;a);&lt;br /&gt;
    {{comment|a ist jetzt 1}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Jetzt wird im Hauptprogramm mittels [[#Adress-Operator und Dereferenzierung|Adress-Operator]] &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; die Speicheradresse von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; bestimmt. Dann wird eine ''Kopie der Adresse'' an das Unterprogramm &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; übergeben. Jetzt kennt das Unterprogramm die&lt;br /&gt;
Adresse des Originals &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und kann direkt mit dem Inhalts-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&lt;br /&gt;
'''Besonderheit bei Feldern'''&lt;br /&gt;
&lt;br /&gt;
Bei der Übergabe von [[#Felder|Feldern]] gibt es eine Besonderheit. Schreibt man nämlich den Namen eines Feldes, so ist das nichts anderes als die '''Speicheradresse des ersten Elements'''.&lt;br /&gt;
Bei der Übergabe eines Feldes wird also eine Kopie der Startadresse übergeben. Somit kann das Unterprogramm auf den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 void erhoehe (int x[])&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
   int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
   erhoehe (a);&lt;br /&gt;
   {{comment|a hat jetzt folgenden Inhalte: 11, 23, 35}}&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Dass die Übergabe einer Adresse erfolgt, sieht man an folgendem Beispiel, das von der Funktionsweise '''absolut identisch''' mit dem vorhergehenden ist:&lt;br /&gt;
&lt;br /&gt;
 {{comment|Bei Parametern gibt es keinen Unterschied zwischen Zeiger und Feld}}&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
    int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
    erhoehe (a);&lt;br /&gt;
 &lt;br /&gt;
    {{comment|a hat jetzt folgenden Inhalt: 11, 23, 35}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
Die Länge des Feldes wird nicht automatisch übergeben. Dafür ist ggf. ein zusätzlicher Parameter notwendig.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Variable Argumentanzahl==&lt;br /&gt;
== Funktionen indirekt aufrufen ==&lt;br /&gt;
Siehe [[#Zeiger auf Funktionen|Zeiger auf Funktionen]]&lt;br /&gt;
&lt;br /&gt;
=Zeiger II=&lt;br /&gt;
&lt;br /&gt;
Zeiger haben wir bereits weiter oben kennen gelernt. Zeiger sind ein zentrales Konzept in C und sollen hier etwas eingehender behandelt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger-Arithmetik==&lt;br /&gt;
In C kann man den Wert eines Zeigers verändern. Betrachten wir dazu die Funktion &amp;lt;tt&amp;gt;suche_0&amp;lt;/tt&amp;gt;, die einen Zeiger auf einen &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; erhält. Die Funktion soll ab der gegebenen Adresse nach dem ersten long-Wert suchen, der 0 ist, und dessen Adresse zurückgeben:&lt;br /&gt;
 long * suche_0 (long * addr)&lt;br /&gt;
 {&lt;br /&gt;
    while (*addr != 0)&lt;br /&gt;
       addr = addr + 1;&lt;br /&gt;
 &lt;br /&gt;
    return addr;&lt;br /&gt;
 }&lt;br /&gt;
In der Bedingung der while-Schleife wird der Inhalt an der Speicherstelle &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf 0 getestet. Ist der Wert 0, dann wird die Schleife beendet und die Adresse zurückgeliefert. Ist der Wert ungleich 0, dann wird &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf den nächste long gesetzt, &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; also um 4 Bytes weitergezählt. &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ist ja ein Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, und ein &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; ist 4 Bytes lang.&lt;br /&gt;
&lt;br /&gt;
Die Bedeutung von&lt;br /&gt;
 address + n&lt;br /&gt;
ist also, die Adresse um das &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;-fache der Größe des Typs, auf den &amp;lt;tt&amp;gt;address&amp;lt;/tt&amp;gt; zeigt, zu erhöhen. Dabei ist &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; eine ganze Zahl und darf auch negativ sein.&lt;br /&gt;
&lt;br /&gt;
Hier noch ein Beispiel einer Funktion, die nach einer Person mit einer bestimmten ID sucht (für die Definition von &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; siehe [[#Strukturen|Strukturen]]). Der Parameter &amp;lt;tt&amp;gt;person&amp;lt;/tt&amp;gt; ist dabei ein Array von Strukturen. Eine Person mit der gesuchten ID muss existieren, ansonsten hat die Suchfunktion kein definiertes Verhalten.&lt;br /&gt;
 {{comment|Sucht nach einer Person mit der ID person_id}}&lt;br /&gt;
 struct Person * &lt;br /&gt;
 suche_person_id (struct Person * person, int person_id)&lt;br /&gt;
 {&lt;br /&gt;
    while (person-&amp;gt;id != person_id)&lt;br /&gt;
       person++;&lt;br /&gt;
 &lt;br /&gt;
    return person;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:1em; padding:1em; border:solid 2px #FF0040;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- Vorlage:FarbigerRahmen funzt hier net --&amp;gt;&lt;br /&gt;
Beachte, daß es nicht sinnvoll ist, zwei Zeiger zu addieren oder zu multiplizieren. Ausserdem ist das &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt; der Zeiger-Arithmetik nicht kommutativ. Eine Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, der an Adresse 1 im Speicher zeigt, wird man schreiben als&lt;br /&gt;
 (long *) 1&lt;br /&gt;
Addiert man darauf eine ganze Zahl, dann haben die entstehenden Ausdrücke unterschiedliche Werte:&lt;br /&gt;
 (long *) 1 + 2    {{comment|zeigt zu Adresse 9}}&lt;br /&gt;
 (long *) 2 + 1    {{comment|zeigt zu Adresse 6}}&lt;br /&gt;
 (long *) (1 + 2)  {{comment|zeigt zu Adresse 3}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==void-Pointer==&lt;br /&gt;
Eine besondere Art von Zeiger ist der void-Pointer&lt;br /&gt;
 void * addr;&lt;br /&gt;
Ein void-Pointer ist ein &amp;quot;Zeiger auf irgendwas&amp;quot;, dementsprechend kann er nicht dereferenziert werden, Anwenden von &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf einen solchen Zeiger gibt also einen Fehler. Ausserdem ist es nicht möglich, mit einem void-Pointer Zeigerarithmetik zu machen, weil er nicht auf eine definierte Art von Objekt zeigt. Der Vorteil eines void-Pointers ist, daß er jede Art von Zeiger aufnehmen kann.&lt;br /&gt;
&lt;br /&gt;
Dazu betrachten wir die Funktion &amp;lt;tt&amp;gt;send_buf&amp;lt;/tt&amp;gt;, die eine Adresse erhält und ab dieser Adresse &amp;lt;tt&amp;gt;num&amp;lt;/tt&amp;gt; Bytes versenden soll. Wir könnten die Funktion so schreiben:&lt;br /&gt;
 void send_buf (unsigned char * buf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   ...&lt;br /&gt;
Das ist jedoch hässlich, wenn wir damit etwas anderes verschicken wollen als &amp;lt;tt&amp;gt; unsigned char&amp;lt;/tt&amp;gt;, etwa eine Struktur wie &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; (vom Typ &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;):&lt;br /&gt;
 send_buf ((unsigned char*) &amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
Ohne den Cast der Adresse von &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; zu einem Zeiger auf &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt; bekommt man eine Warnung oder gar einen Compilerfehler.&lt;br /&gt;
Dieses Zeiger gecaste ist mühsam und hässlich, es muss bei jedem Aufruf der Funktion explizit hingeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Besser ist es, den ersten Parameter der Funktion als void-Pointer zu definieren und den Cast in der Funktion zu machen:&lt;br /&gt;
 void send_buf (void * vbuf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   unsigned char *buf = (unsigned char*) vbuf;&lt;br /&gt;
   ...&lt;br /&gt;
Durch den Cast in der Funktion kann auf den Inhalt des Zeigers zugegriffen werden. Man muss nur festlegen, ''wie'' man zugreifen will, nämlich als &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Der Aufruf kann jetzt ohne Pointer-Cast erfolgen: &lt;br /&gt;
 send_buf (&amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
&lt;br /&gt;
==Null-Pointer==&lt;br /&gt;
==Zeiger als Parameter==&lt;br /&gt;
Wenn Sie ein Unterprogramm aufrufen, können Sie diesem Parameter übergeben, aber keine Werte zurückgekommen (außer den Funktionswert bei Funktionen). Dies hat einen guten Grund: beim Aufruf werden nicht die aufgerufenen Parameter benutzt, sondern es werden deren Werte in neue Variablen kopiert. Diese Variablen werden am Ende des Unterprogrammes &amp;quot;zerstört&amp;quot;, ohne ihre Werte an die aufrufenden Parameter zu übergeben. Jede Veränderung eines Parameters hat daher keine Auswirkung auf den Parameter.&lt;br /&gt;
&lt;br /&gt;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der C-Compiler legt dann immer noch Kopien an. In dieser Kopie steht aber kein Wert, sondern die Adresse einer Varaiblen. Und auf diese können Sie dann zugreifen. Denken Sie nur an &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; &amp;amp;ndash; da übergeben Sie ja auch die Adresse einer Variablen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void erhoehe (int *zeiger)&lt;br /&gt;
{&lt;br /&gt;
  *zeiger = 1 + *zeiger;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  erhoehe (&amp;amp;zahl);&lt;br /&gt;
  printf (&amp;quot;\nDie erhoehte Zahl lautet: %d\n&amp;quot;, zahl);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Zeiger auf Funktionen==&lt;br /&gt;
&lt;br /&gt;
Stell dir vor, du willst einen Sortieralgorithmus wie Bubble-Sort oder Quick-Sort oder wie sie alle heissen implementieren. Für den Sortieralgorithmus ist eigentlich egal, ''was'' er zu sortieren hat. Ihm ist es egal, ob er Zahlen aufwärts sortieren soll oder Strings in lexikographischer Reihenfolge, ob Objekte nach Größe oder Gewicht, Personen nach Alter oder Adressen nach Postleitzahl. Das einzige, was der Algorithmus wissen muss, ist ''wie'' er zwei Objekte zu vergleichen hat und wann eines davon &amp;quot;kleiner&amp;quot; (im Sinne der Ordnung, nach der sortiert werden soll) ist. &lt;br /&gt;
&lt;br /&gt;
Eine einfache Sortierfunktion, die nur zwei Zahlen sortiert, könnte man also so schreiben: &lt;br /&gt;
 {{comment|Sortiert ein Array von 2 int-Zeigern nach den Inhalten &lt;br /&gt;
  * an den Zeiger-Adressen}}&lt;br /&gt;
 void sort2_a (int * p[])&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Inhalte vergleichen...}}&lt;br /&gt;
    if (*p[0] &amp;gt; *p[1])&lt;br /&gt;
    {&lt;br /&gt;
       {{comment|... und ggf. Dreieckstausch der 2 Zeiger}}&lt;br /&gt;
       int * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Die Funktion bekommt ein Array der Länge&amp;amp;nbsp;2. In diesem Array stehen Zeiger auf die zu sortierenden Zahlen. Ein Array mit Zeigern zu verwenden und nicht ein Array von &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; scheint recht umständlich, und das ist es hier auch. Aber stell dir vor, du willst Strukturen wie &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; sortieren. Das Tauschen zweier Strukturen würde bedeuten, ihre kompletten Inhalte umzukopieren! Das wäre sehr aufwändig. Viel einfacher ist das Kopieren, wenn nur die Adressen zu kopieren sind.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; könnte dann so aussehen:&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void sortiere (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|p[] enthält 2 int-Zeiger: die Adressen von a und b}}&lt;br /&gt;
    int * p[2];&lt;br /&gt;
    p[0] = &amp;amp;a; &lt;br /&gt;
    p[1] = &amp;amp;b; &lt;br /&gt;
 &lt;br /&gt;
    {{comment|Sortiere die Zeiger}} &lt;br /&gt;
    sort2_a (p);&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Sortiert: %d, %d\n&amp;quot;, *p[0], *p[1]);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Für den nächsten Schritt überlegen wir uns, daß das Array in &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; ebensogut void-Pointer enthalten kann. Die einzige Stelle, an der wir auf die endgültigen int-Objekte zugreifen, ist der Vergleich. Diesen Vergleich lagern wir in die Funktion &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; aus:&lt;br /&gt;
 {{comment|Bekommt zwei void-Pointer und vergleicht die Inhalte.&lt;br /&gt;
  * Liefert 0 bei Gleichheit,&lt;br /&gt;
  * -1 wenn der erste Wert kleiner ist als der zweite und&lt;br /&gt;
  * 1  wenn der erste Wert größer ist als der zweite}}&lt;br /&gt;
 int compare_int (void * p0, void * p1)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Um über die Zeiger zugreifen zu können müssen wir diese&lt;br /&gt;
     * erst zu int-Zeigern casten}}&lt;br /&gt;
    int a0 = * (int*) p0;&lt;br /&gt;
    int a1 = * (int*) p1;&lt;br /&gt;
 &lt;br /&gt;
    if (a0 &amp;gt; a1)  return  1;&lt;br /&gt;
    if (a0 &amp;lt; a1)  return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void sort2_b (void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare_int (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Ein Aufruf von &amp;lt;tt&amp;gt;sort2_b&amp;lt;/tt&amp;gt; sieht dann genauso aus wie ein Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt definieren wir uns den neuen Datentyp &amp;lt;tt&amp;gt;comparator_t&amp;lt;/tt&amp;gt;. Dieser ist ein Zeiger auf eine Funktion, die zwei void-Pointer erhält und einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; zurückliefert, also analog arbeitet zu &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; von oben. &lt;br /&gt;
&lt;br /&gt;
Unsere Sortierfunktion bekommt nun neben dem zu sortierenden Zeiger-Array auch eine Vergleichsfunktion &amp;lt;tt&amp;gt;compare&amp;lt;/tt&amp;gt; mitgeliefert, die sie aufruft, wenn sie zwei Objekte vergleichen will&lt;br /&gt;
 {{comment|comparator_t sind Zeiger auf Funktionen, die 2 void-Pointer&lt;br /&gt;
  * erhalten und einen int zurückliefern}}&lt;br /&gt;
 typedef int (*comparator_t) (void*, void*);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Der Sortierer bekommt einen Funktionszeiger auf den Vergleicher.&lt;br /&gt;
  * Der Aufruf vom compare geht so als wäre es eine &amp;quot;normale&amp;quot; Funktion&lt;br /&gt;
  * (ist es im Endeffekt ja auch)}}&lt;br /&gt;
 void sort2_c (comparator_t compare, void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Bei einem Aufruf von &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; muss man dann einen Komparator mit angeben. In einem Beispiel analog zu &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; von oben ist das:&lt;br /&gt;
 sort2_c (compare_int, p);&lt;br /&gt;
Um zwei Strings lexikographisch zu sortieren nehmen wie die Standard-Funktion &amp;lt;tt&amp;gt;strcmp&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void foo()&lt;br /&gt;
 {&lt;br /&gt;
    char * worte[] = { &amp;quot;Wort1&amp;quot;, &amp;quot;Wort2&amp;quot; };&lt;br /&gt;
 &lt;br /&gt;
    sort2_c ((comparator_t) strcmp, (void**) worte);&lt;br /&gt;
 }&lt;br /&gt;
Die Casts sind hier erforderlich. Alternativ könnte man &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; mit reinen void-Pointern versorgen und diese dann dort umcasten.&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
&lt;br /&gt;
Die Syntax zur Definition/Deklaration von Funktionszeigern ist etwas verzwackt. Zur Verdeutlichung ein paar Beispiele. Dabei legt das linke &amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt; jeweils den Return-Typ fest.&lt;br /&gt;
 {{comment|definiert einen neuen Funktionszeiger-Typ}}&lt;br /&gt;
 typedef {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert einen Funktionszeiger}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert ein Array von Funktionszeigern (mit Initializer)}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}[]) ({{type}}, {{type}}, ...) = { wert1, wert2, ... };&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer}}&lt;br /&gt;
 ({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer und ruft die Funktion auf}}&lt;br /&gt;
 (({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}) (arg1, arg2, ...);&lt;br /&gt;
&lt;br /&gt;
=Standard-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==String-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===strcpy===&lt;br /&gt;
Bei vielen Compilern können sie einem String nicht direkt einen Wert (Text) zuweisen. Dazu müssen Sie dann die Prozedur strcpy() benutzen. Diese erwartet als ersten Parameter den Namen einer String-Variablen (ohne eckige Klammern) und als zweiten Parameter den eines (anderen) Strings. Letzterer kann auch ein in doppelten Hochkommas (&amp;quot;) eingeschlossener Text sein. Die Funktion fügt am Ende automatisch ein 0-Zeichen ein. Um diese Funktion nutzen zu können, müssen Sie die Datei string.h includieren! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri1[21], eingabe[21];&lt;br /&gt;
&lt;br /&gt;
  strcpy (stri1, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Der 1. String: %s\n&amp;quot;, stri1);&lt;br /&gt;
  printf (&amp;quot;Bitte geben Sie maximal 20 Zeichen ein: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%s&amp;quot;, eingabe);&lt;br /&gt;
  strcpy (stri1, eingabe);&lt;br /&gt;
  printf (&amp;quot;\n%s = %s&amp;quot;, stri1, eingabe);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis:''' &lt;br /&gt;
Da ein String, wie jedes Feld, eigentlich ein Zeiger ist, dürfen Sie kein &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; bei &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; angeben!&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
Es werden zwei gleich große Strings definiert: &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;eingabe&amp;lt;/tt&amp;gt;, mit je 20 &amp;quot;nutzbaren&amp;quot; Zeichen. &lt;br /&gt;
In &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; wird die Zeichenkette &amp;lt;tt&amp;gt;&amp;quot;hallo&amp;quot;&amp;lt;/tt&amp;gt; hineinkopiert. Das 0-Zeichen am Ende wird automatisch angefügt. &lt;br /&gt;
Der String wird ausgegeben. Als neues &amp;quot;Sonderzeichen&amp;quot; kommt &amp;lt;tt&amp;gt;%s&amp;lt;/tt&amp;gt; ins Spiel. Es hat die gleiche Aufgabe wie &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt;, nur für Strings. &lt;br /&gt;
Sie werden gebeten, eine String einzugeben. &lt;br /&gt;
Dieser String wird danach in die Variable &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; kopiert. &lt;br /&gt;
Beide Strings, die ja nun die gleiche Zeichenkette enthalten, werden ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===strlen===&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;strlen&amp;lt;/tt&amp;gt;, die als Parameter eine String-Variable erwartet, liefert die Länge diese Strings zurück. Sie werden jetzt vermutlich sagen: &amp;quot;Das ist doch klar, wie lang der String ist. Ich habe es ja bei der Deklaratin angegeben&amp;quot;. Das stimmt schon, aber denken Sie noch einmal an die null-terminierten Strings. Das 0-Zeichen steht am Ende des Strings (am Ende der gültigen Zeichenfolge), aber nicht unbedingt am Ende des reservierten Speicherplatzes. Haben Sie eine Variable &amp;quot;char Variable[21];&amp;quot;, und ihr den Wert &amp;quot;hallo&amp;quot; zugewiesen, dann steht das null-Zeichen in Variable[5]. Der &amp;quot;gültige&amp;quot; String ist also 5 Zeichen (0-4) lang. Und genau das (5) würde strlen zurück liefern. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri[21];&lt;br /&gt;
  &lt;br /&gt;
  strcpy (stri, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
  printf (&amp;quot;Der String ist %d Zeichen lang&amp;quot;, strlen (stri));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird vor allem gebraucht, wenn Sie direkt auf den String zugreifen, mittels &amp;lt;tt&amp;gt;stri[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;stri[1]&amp;lt;/tt&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
==Ein- und Ausgabe-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===Bildschirm-Ausgabe===&lt;br /&gt;
Bisher war das Tutorial trotz aller Beispiele reine Theorie. Sie konnten zwar Programme schreiben, aber die Funktion nicht testen. Hier lernen Sie nun, wie Sie etwas am Bildschirm ausgeben.&lt;br /&gt;
&lt;br /&gt;
Die dazu notwendige Funktione heisst &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (das '&amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt;' ist kein Fehler!). Diese Anweisung gibt die ihr übergebenen Parameter auf das Standard-Ausgabegerät aus, in der Regel also auf den Bildschirm. Sie kann beliebig viele Parameter übernehmen. Es müssen jedoch Standard-Datentypen (z.B. &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;...) sein! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
    int zahl1 = 12;&lt;br /&gt;
    char zeichen1 = 'A';&lt;br /&gt;
    &lt;br /&gt;
    printf (&amp;quot;Das ist Text, und er wird als solcher ausgegeben. \n&amp;quot;);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zahl1' ist: %d \n&amp;quot;, zahl1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %c \n&amp;quot;, zeichen1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %d \n&amp;quot;, zeichen1);&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt Text aus. Das Zeichen am Ende (&amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;) bedeutet &amp;quot;New Line&amp;quot;, es bewegt den Cursor an den Anfang der nächsten Zeile. &lt;br /&gt;
&lt;br /&gt;
Der zweite &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt auch Text aus, am Ende befindet sich wieder das &amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;, um einen Zeilenvorschub zu erreichen. Das &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; wird vom Compiler durch den ersten Parameter ersetzt, der nach dem Text angegeben wird. In diesem Fall wird &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; also durch den Wert der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ersetzt. Das &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; im &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; bedeutet &amp;quot;Dezimalzahl&amp;quot;, der Computer gibt also eine ganze Zahl aus. &lt;br /&gt;
&lt;br /&gt;
In der dritten Ausgabe wird ein Zeichen ausgegeben. Diesmal bedeutet &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; &amp;quot;char&amp;quot; (Zeichen). Es wird also &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; durch ein &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt; ersetzt, denn die Variable &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; wird als Character interpretiert. &lt;br /&gt;
&lt;br /&gt;
Die letzte Ausgabe interpretiert den Inhalt von &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; als Zahl, und gibt dager den ASCII-Wert von &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, also 65 aus. Das ist ein typisches Beispiel für das mögliche unterschiedliche Interpretieren einer  Variablen!&lt;br /&gt;
&lt;br /&gt;
===Tastatur-Eingabe===&lt;br /&gt;
&lt;br /&gt;
Um ein &amp;quot;gscheites&amp;quot; Programm schreiben zu können, muß man wissen, wie der Benutzer über die Tastatur Befehle eingeben kann. Die dafür notwendigen Funktionen stelle ich in diesem Kapitel vor.&lt;br /&gt;
Die wichtigste Funktion ist &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt;. Er liest Daten von der Tastatur. Die Syntax entspricht derer von &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int  zahl1;&lt;br /&gt;
char zeichen1;&lt;br /&gt;
&lt;br /&gt;
printf (&amp;quot;Bitte geben Sie eine Zahl ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl1);&lt;br /&gt;
printf (&amp;quot;Geben Sie einen Zeichen ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%c&amp;quot;, &amp;amp;zeichen1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Programm gibt eine Eingabeaufforderung aus. Dann erwartet es vom Benutzer, daß er eine Zahl eingibt, die mit [ENTER] bestätigt wird. Dieser Wert wird in &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; abgespeichert. Danach erfolgt wiederum eine Aufforderung zur Eingabe, diesmal eines einzelnen Zeichens. Dieses kann man nun eingeben und ebenfalls mit [ENTER] bestätigen.&lt;br /&gt;
&lt;br /&gt;
Macht man keine dem Datentyp der erwarteten Variable entsprechende Eingabe, dann bricht das Programm mit einer Fehlermeldung ab (wenn man z.B. &amp;quot;1_T2&amp;quot; eingibt, wenn eine Zahl erwartet wird)!&lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; vor den Parametern ist notwendig. Warum, das erfahren Sie im Kapitel &amp;quot;Unterprogramme&amp;quot;. Für die Profis eine Kurz-Erklärung: Das Unterprogramm &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; bekommt zwar einen Wert übergeben, kann aber keinen zurückliefern (&amp;quot;call by value&amp;quot;). Daher wird kein Wert, sondern ein Zeiger auf eine Variable übergeben. Mit dem &amp;amp; Zeichen bekommen Sie die Adresse einer Variablen (&amp;quot;call by reference&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=Parameter von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;=&lt;br /&gt;
Das Unterprogramm &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; kann, wie jede andere Funktion, Parameter besitzen. Doch keine selbst gewählten, sondern nur bestimmte. Doch warum braucht main Parameter? Denken Sie einmal an alle Betriebssystembefehle:&lt;br /&gt;
&amp;lt;tt&amp;gt;dir *.exe &amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;copy *.* a:&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;ls -la &amp;lt;/tt&amp;gt;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen!&lt;br /&gt;
&lt;br /&gt;
=Kurzreferenz=&lt;br /&gt;
==Syntax-Bausteine==&lt;br /&gt;
&lt;br /&gt;
Die Erklärung des Aufbaus von C-Befehlen erfolgt neben einfachen Beispielen auch durch ihren prinzipellen Aufbau. In diesen Syntax-Beschreibungen finden sich immer wieder die gleichen Bausteine, die hier näher erklärt werden sollen. Falls die solch ein Syntax-Baustein begegnet, kannst Du ihn anclicken und kommst dann zu seiner Erläuterung. &lt;br /&gt;
&lt;br /&gt;
In den Beispielen selbst gehören auch die spitzen Klammern zu dem Baustein (was daran zu erkennen ist, daß auch die Klammern eingefärbt sind). Die Klammern dürfen in einem konkreten C-Programm daher nicht eingetippt werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bezeichner&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Bezeichner in C dienen dazu, Variablen zu identifizieren und ihnen sprechende Namen zu geben, um die Quelle lesbarer zu machen. Man braucht Bezeichner auch, um selbstdefinierte Datentypen zu benennen und zum Benennen von Struct- und Union-Komponenten sowie als Namen für Funktionen und Sprungmarken (Labels).&lt;br /&gt;
&lt;br /&gt;
Bezeichner dürfen aus den Kleinbuchstaben &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;z&amp;lt;/tt&amp;gt;, den Großbuchstaben &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;Z&amp;lt;/tt&amp;gt;, dem Unterstrich&amp;amp;nbsp;&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt; und den Ziffern &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;9&amp;lt;/tt&amp;gt; aufgebaut werden, wobei an erster Stelle jedoch keine Ziffer stehen darf.&lt;br /&gt;
&lt;br /&gt;
Es wird zwischen Groß- und Kleinschreibung unterschieden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Ausdruck in C ist ein Konstrukt, das einen Wert hat. Ob dieser Wert eine ganze Zahl ist, eine Kommazahl oder ein Zeiger, etc. ist dabei egal. Die einfachsten Ausdrücke sind Konstanten wie&lt;br /&gt;
 2&lt;br /&gt;
oder Variablen wie&lt;br /&gt;
 ein_zahl&lt;br /&gt;
Mehrere Ausdrücke können durch [[#Liste der Operatoren|Operatoren]] zu komplexeren Ausdrücken kombiniert werden, etwa&lt;br /&gt;
 eine_zahl + andere_zahl == 2&lt;br /&gt;
oder &lt;br /&gt;
 eine_zahl = 2&lt;br /&gt;
Letzterer hat den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; und den Nebeneffekt, daß er diesen Wert an &amp;lt;tt&amp;gt;eine_zahl&amp;lt;/tt&amp;gt; zuweist.&lt;br /&gt;
&lt;br /&gt;
Auch der Aufruf einer Funktion, die einen Rückgabewert liefert, ist ein Ausdruck:&lt;br /&gt;
 sin (1.2)&lt;br /&gt;
und kann zum Aufbau komplexerer Ausdrüche verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bedingung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Bedingung ist ein Ausdruck, bei der nur interessiert, ob dieser zu&amp;amp;nbsp;0 (unwahr) auswertet oder zu ungleich&amp;amp;nbsp;0 (wahr). Solche Ausdrücke findet man in if-Anweisungen, in Schleifenbedingungen und bedingten Zuweisungen&lt;br /&gt;
 (ein_wert &amp;lt; 2) || (ein_wert &amp;gt; 40)&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Lvalue ist ein Ausdruck, dem etwas zugewiesen werden kann. Der Name ''Lvalue'' kommt aus dem Englischen. Das ''L'' steht abkürzend für left. Ein Lvalue ist damit ein Ausdruck, der auf der linken Seite eine Zuweisung in C stehen darf. Das &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; in den folgenden Beispiel-Ausdrücken muss ein Lvalue sein:&lt;br /&gt;
 x = y-1&lt;br /&gt;
&lt;br /&gt;
 x++&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Konstante&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Konstante ist ein Ausdruck, dessen Wert dem Compiler bekannt ist. Beispiele für Konstanten sind etwa&lt;br /&gt;
 7&lt;br /&gt;
 'B'&lt;br /&gt;
 -13.98e12&lt;br /&gt;
 1+(2*3)&lt;br /&gt;
und die Werte von [[#Enum|Enum]]s. &lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; aus dem folgenden Codestück definiert jedoch keine Konstante in diesem Sinne&lt;br /&gt;
 const double Pi = 3.14159256;&lt;br /&gt;
denn in einem anderen Quellmodul könnte durch die Deklaration&lt;br /&gt;
 extern const double Pi;&lt;br /&gt;
das Symbol &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; bekannt sein, ohne daß sein Wert bekannt ist!&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Adresse&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Adresse ist ein Ausdruck, der einen Speicherort (physikalisch oder virtuell) halten kann. Adressen erhält man dadurch, daß man einem Bezeichner den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt;voranstellt, Adressen durch Arithmetik berechnet oder Zahlen zu Adressen castet. Folgende Ausdrücke sind Adressen (eine sinnvolle Deklaration der auftretenden Variablen vorausgesetzt)&lt;br /&gt;
 &amp;amp; eine_zahl&lt;br /&gt;
 &amp;amp; ein_array[10]&lt;br /&gt;
 &amp;amp; ein_struct&lt;br /&gt;
 &amp;amp; ein_struct.komponente&lt;br /&gt;
 (int *) 0x1234&lt;br /&gt;
 (int *) eine_zahl&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Deklaration&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Anweisungen sind gewissermassen die Atome (oder Moleküle?), aus denen ein C-Programm besteht. Jedes C-Programm ist eine Abfolge von Deklarationen und Anweisungen. Einfache Anweisungen erhält man, in dem man einen Ausdruck nimmt und einen Strichpunkt dahinter schreibt:&lt;br /&gt;
 {{Ausdruck|}};&lt;br /&gt;
wie in&lt;br /&gt;
 x = x+1;&lt;br /&gt;
&lt;br /&gt;
Andere Anweisungen sind die unten aufgeführten Schleifen und die if- sowie die switch-Anweisung.&lt;br /&gt;
&lt;br /&gt;
Mehrere Deklarationen und Anweisungen können zu einem Block zusammengefasst werden. Dieser Block stellt dann wieder eine einzelne Anweisung dar und kann genau so gehandhabt werden!&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
In diesem Sinne ist auch z.B. die Syntax der if-Anweisung zu verstehen&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
besagt, daß der abhängig ausgeführte Code eine einzelne Anweisung sein darf oder eben ein kompletter Block oder die Verschachtelung mehrerer Blöcke etc.&lt;br /&gt;
&lt;br /&gt;
Eine Anweisung kann auch &amp;quot;leer&amp;quot; sein, also nichts tun. Diese Anweisungen sind der leere Block&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
und der Strichpunkt&lt;br /&gt;
 ;&lt;br /&gt;
die man gelegentlich in Schleifen findet:&lt;br /&gt;
 while (!timeout())&lt;br /&gt;
    {}&lt;br /&gt;
oder hinter Sprungmarken, die sonst direkt vor einer schliessenden Blockklammer stünden:&lt;br /&gt;
 {&lt;br /&gt;
    ...&lt;br /&gt;
    goto ein_label;&lt;br /&gt;
    ...&lt;br /&gt;
    {{Label|ein_label}}:;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Nicht jede Anweisung ist an jeder Stelle eines C-Programms erlaubt, so darf ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; nut innerhalb einer Schleife stehen. Gleiches gilt für &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;, das aber auch innerhalb eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; vorkommen darf.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Dies steht für einen Datentyp. Es kann ein elementarer Typ sein wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;, ein Zeiger darauf wie &amp;lt;tt&amp;gt;char*&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;void*&amp;lt;/tt&amp;gt;, und auch Qualifier enthalten wie das &amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt; im Typ &amp;lt;tt&amp;gt;unsigned long long&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Zu den Typen gehören auch zusammengesetzte Datentypen wie Strukturen und Unions, mit &amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt; selbst definierte Typen und natürlich Zeiger darauf, wie aus dem Abschnitt [[#Datentypen|Datentypen]]:&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person *&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;data32_t&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;&lt;br /&gt;
und Zeiger auf Funktionen.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Parameterliste&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
Die Parameterliste bei einer Funktionsdefinition gibt an, wieviel Übergabeparameter sie bekommt, wie diese heissen und welchen Typs diese sind. Der prinzipielle Aufbau ist&lt;br /&gt;
 {{Type}} {{Bezeichner}}, {{Type}} {{Bezeichner}}, ...&lt;br /&gt;
Falls die Funktion keine Parameter hat, dann ist die Parameterliste leer.&lt;br /&gt;
&lt;br /&gt;
Hier als Beispiel die zweiparametrige Funktion &amp;lt;tt&amp;gt;produkt&amp;lt;/tt&amp;gt;. Der erste Parameter heisst&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und ist ein &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;. Der zweite namens&amp;amp;nbsp;&amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; ist vom Typ &amp;quot;Zeiger auf double&amp;quot;, der Inhalt &amp;lt;tt&amp;gt;*b&amp;lt;/tt&amp;gt; ist also auch ein double.&lt;br /&gt;
&lt;br /&gt;
'''Definition der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b)&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
In älteren C-Quellen findet man noch eine andere Syntax für die Deklaration der Parameter, die aber heute praktisch nicht mehr verwendet wird:&lt;br /&gt;
'''alte Definition der Funktion:'''&lt;br /&gt;
 double produkt (a, b)&lt;br /&gt;
 double a, *b;&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Um die Funktion bekannt zu machen, werdendet man eine Deklaration bzw. den Prototypen, der dem Compiler nur mitteilt, welche Parameter die Funktion bekommt und was sie zurückliefert. Für den Aufruf der Funktion muss der Compiler nur diesen Prototyp kennen, ''was'' die Funktion im Endeffekt macht und wie sie implementiert wurde ist egal, sie wird als BlackBox angesehen.&lt;br /&gt;
&lt;br /&gt;
'''Prototyp der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b);&lt;br /&gt;
Hier dürfen die Bezeichner auch fehlen:&lt;br /&gt;
 double produkt (double, double*);&lt;br /&gt;
&lt;br /&gt;
==if==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==if-else==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==for==&lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Eine for-Schleife entspricht folgendem Konstrukt. Dabei sind die drei Ausdrücke optional. Fehlt die Bedingung, dann wird diese als &amp;quot;wahr&amp;quot; angenommen. Die beiden anderen Ausdrücke wird man als Ausdrücke mit Nebeneffekt wählen wie z.B. &amp;lt;tt&amp;gt;x=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;x=x-2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
 {&lt;br /&gt;
    {{Ausdruck|1}};&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_loop}}:&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
    else&lt;br /&gt;
       goto _break;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_continue}}:&lt;br /&gt;
    {{Ausdruck|2}};&lt;br /&gt;
    goto _loop;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_break}}:;&lt;br /&gt;
 }&lt;br /&gt;
Die Labels &amp;lt;tt&amp;gt;_break&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_continue&amp;lt;/tt&amp;gt; entsprechen den Sprungzielen einer &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Anweisung innerhalb von &amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==do-while==&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while  ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
==while==&lt;br /&gt;
 while  ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==switch==&lt;br /&gt;
 switch  ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    ...&lt;br /&gt;
  &lt;br /&gt;
    default:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#break-Anweisung|&amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Konstanten|&amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#continue-Anweisung|&amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#do-while-Schleife|&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Enum|&amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#for-Schleife|&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#goto-Anweisung|&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#return-Anweisung|&amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Liste der Operatoren|sizeof]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Strukturen|&amp;lt;tt&amp;gt;struct&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Eigene Datentypen|&amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Unions|&amp;lt;tt&amp;gt;union&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#while-Schleife|&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund2}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Arithmetische Operatoren&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Dies sind die &amp;quot;normalen&amp;quot; arithmetischen Operationen, wie man sie aus der Schule kennt. Man kann damit und allen anderen Operatoren auch komplexere Ausdrücke aufbauen. Die Prioritäten sind so, wie man sie kennt, also &amp;quot;Punktrechnung vor Strichrechnung&amp;quot;. Will man dies ändern, dann mit den runden Klammern:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;1+2*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 7&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(1+2)*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 9&amp;lt;br/&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}}&amp;amp;nbsp;+&amp;amp;nbsp;{{Ausdruck|}}&amp;lt;/tt&amp;gt; || Addition&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} - {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Subtraktion&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} * {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Multiplikation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} / {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Division&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} % {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Rest der Division (modulo)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;- {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Vorzeichenumkehr, Zweier-Komplement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Logische Operatoren und Vergleiche&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die logischen und die vergleichenden Operatoren liefern als Ergebnis den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (wahr) oder einen Wert ungleich&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (falsch, um genau zu sein den Wert &amp;lt;tt&amp;gt;!0&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Man kann das Ergebnis zwar einer Variablen zuweisen, in aller Regel wird man solche Ausdrücke jedoch in Bedingungen zu &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder in Abbruch-Bedingungen von Schleifen finden.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;&amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches AND: beides wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124;&amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches OR: mind. eines ist wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;! {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches NOT (0 &amp;amp;harr; ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} == {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} != {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist nicht gleich&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bitweise Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~ {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise NOT (Einser-Komplement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise AND&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise ODER&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} ^ {{Ausdruck|}}&amp;lt;/tt&amp;gt; ||bitweise XOR&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Shift-Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;lt;&amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Bits nach links schieben&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;gt;&amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Schieben nach rechts schieben&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Typen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Ein Cast in C kann dazu verwendet werden, den Typ eines Ausdruckes zu ändern oder den Ausdruck mit einer bestimmten Genauigkeit zu berechnen. Wird z.B. eine Berechnung standardmässig in 16 Bit ausgeführt, dann kann man mit einem Cast &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(long) &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
ausdrücken, daß die Berechnung in 32 Bit erfolgen soll. Des weiteren kann man Zeiger und ganze Zahlen und Gleitkommazahlen ineinander umwandeln.&lt;br /&gt;
&lt;br /&gt;
Casts können ''nicht'' dazu verwendet werden, um z.B. eine Zahl in einen String zu konvertieren, der diese Zahl darstellt! Dafür gibt es spezielle Funktionen wie &amp;lt;tt&amp;gt;itoa&amp;lt;/tt&amp;gt;!&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Type}}) {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Cast, Typwandlung&lt;br /&gt;
|-&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;| &amp;lt;tt&amp;gt;sizeof ({{Type}})&amp;lt;/tt&amp;gt; || Eine Konstante, deren Wert die Größe (in Bytes) des Typs ist. &amp;lt;tt&amp;gt;sizeof&amp;lt;/tt&amp;gt; ist auch auf Objekte anwendbar wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, Arrays bekannter Größe, Strukturen und Unions,  Array-, Struktur- und Union-Komponenten, Pointer, etc. Beispiel:&amp;lt;br/&amp;gt;&lt;br /&gt;
 int i, sum=0, array[] = { 1, -13, 4, 0, sizeof (int*) };&lt;br /&gt;
 &lt;br /&gt;
 for (i=0; i&amp;lt; sizeof (array) / sizeof (array[0]); i++)&lt;br /&gt;
    sum += array[i];&lt;br /&gt;
Alle Elemente des Arrays werden aufaddiert, ohne daß deren Anzahl explizit in der Schleife genannt ist.&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zeiger und Adressen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;* {{Adresse}}&amp;lt;/tt&amp;gt; || der Inhalt an Adresse&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp; {{Lvalue}}&amp;lt;/tt&amp;gt; || Adresse von&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Strukturen, Unions, Arrays&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Struct&amp;gt;}}.{{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Zeiger-auf-Struct&amp;gt;}} -&amp;gt; {{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union, deren Adresse man hat&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Adresse}}&amp;amp;#91;{{Ausdruck|}}&amp;amp;#93;&amp;lt;/tt&amp;gt; || Array-Element&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bedingte Auswertung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Bedingung}}) ? {{Ausdruck|}} : {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Auswahl des Wertes abhängig von der Bedingung&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zuweisung und Operatoren mit Nebeneffekt&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die Unterschiede der post- und pre-Varianten der Increment/Decrement kommen in Konstrukten wie &amp;lt;tt&amp;gt;x = *p++&amp;lt;/tt&amp;gt; zum tragen:&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *p++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; p = p+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *++p;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; p = p+1; x = *p;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = (*p)++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; *p = (*p)+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = ++(*p);&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; *p = (*p)+1; x = *p;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} = {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Zuweisung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++ {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-- {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Decrement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ++&amp;lt;/tt&amp;gt; || Post-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} --&amp;lt;/tt&amp;gt; || Post-Decrement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Kurzschreibweisen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Für ganz Faule gibt es anstatt&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a = a @ b&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
für viele Operatoren (hier dargestellt durch ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;@&amp;lt;/tt&amp;gt;) die abkürzende Schreibweise&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a @= b&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} += {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} -= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} *= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} /= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} %= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ^= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;lt;&amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;gt;&amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Autoren'''&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
* Kernighan und Ritchie - Buch&lt;br /&gt;
* Christian Wirth , C Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://wwwuser.gwdg.de/~kboehm/ebook/inhalt.html C-Programmieren unter Linux]&lt;br /&gt;
* [http://www.gdv.uni-hannover.de/documentation.php Skripte zum Selbststudium: C, C++, Java, etc]&lt;br /&gt;
* [http://info.baeumle.com/ansic.html Einführung in ANSI-C]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Quellcode C|!]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Inrfb2</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10400</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10400"/>
				<updated>2007-03-13T19:13:39Z</updated>
		
		<summary type="html">&lt;p&gt;Inrfb2: /* Reihenfolge der Auswertung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Programmiersprache C wurde 1971 als Gundlage für das Betriebssystem UNIX in den USA entwickelt (UNIX ist zu über 90% in C geschrieben). 1978 wurde von Brian Kernighan und Dennis Ritchie eine eindeutige Sprachdefinition entwickelt. Mittlerweile ist C von ANSI und ISO standardisiert.&lt;br /&gt;
&lt;br /&gt;
Heute sind C und ihr Nachfolger C++ die dominierenden Programmiersprachen. Sehr viele Anwendungen sind in C geschrieben, was inzwischen auch auf eingebettete Systeme zutrifft, die lange in Assembler programmiert werden mussten, da keine ausreichend leistungsfähigen Compiler zur Verfügung standen. &lt;br /&gt;
&lt;br /&gt;
Leider ist C nicht einfach zu lernen &amp;amp;ndash; es wurde weder von noch für Hobby-Programmierer entwickelt &amp;amp;ndash; und eignet sich daher nur bedingt für den Einsteiger. Mit etwas Übung und einem optimierenden Compiler kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
Vom Design her ist C eine Hardware-unabhängig Sprache. Das bedeutet, daß C-Programme mit vertretbarem Aufwand auf ein anderes System portiert werden können. Dazu benötigt man lediglich einen anderen Compiler, und Inline-Assembler-Anweisungen (Assembleranweisungen innerhalb eines C-Programmes) müssen der neuen Hardware (Prozessor) angepasst werden. &lt;br /&gt;
&lt;br /&gt;
==Geschichte==&lt;br /&gt;
;1971: C wird entwickelt&lt;br /&gt;
;1978: Kernighan und Ritchie definieren die Sprache.&lt;br /&gt;
;1983: ANSI und ISO standardisieren C.&lt;br /&gt;
;1992: Bjarne Stroustrup enwickelt die Nachfolgesprache C++.&lt;br /&gt;
&lt;br /&gt;
=Aufbau eines C-Programmes=&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
   C-Programme haben keinen fixen Aufbau wie z.B. Pascal. Es gibt zwar gewisse Regeln, aber sonst sind dem Programmierer alle Freiheiten überlassen. Der folgende &amp;quot;Beispiel-Aufbau&amp;quot; ist daher nicht zwingend und kann durchaus verändert werden.&lt;br /&gt;
&lt;br /&gt;
   Natürlich haben C-Programme einen fixen Aufbau! Ebenso wie Pascal-Programme auch unterliegen sie einer strikten Grammatik! &lt;br /&gt;
Auskommentiert --[[Benutzer:SprinterSB|SprinterSB]] 10:23, 17. Feb 2006 (CET)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Ein einfaches C-Programm könnte folgendermassen aussehen. Das Programm tut eigentlich nichts, aber das Beispiel zeigt den prinzipiellen Aufbau. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 int Zahl1;&lt;br /&gt;
 char Zeichen1;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int zahl2;&lt;br /&gt;
 &lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Beschreibung:'''&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndash; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
 {{comment|void-Definition von main ist nur beim Controller ueblich}}&lt;br /&gt;
 {{comment|spezielle Compilereinstellungen sind noetig, damit bei dieser Definition von main}}&lt;br /&gt;
 {{comment|kein Fehler/Warnung erzeugt wird.}}&lt;br /&gt;
 void main ()&lt;br /&gt;
 {&lt;br /&gt;
     ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
 int main (void)&lt;br /&gt;
 {  {{comment|der Block &amp;quot;main&amp;quot; beginnt}}&lt;br /&gt;
    int zahl;&lt;br /&gt;
    &lt;br /&gt;
    {   {{comment|ein Block beginnt}}&lt;br /&gt;
        {{comment|hier koennen Deklarationen und Anweisungen stehen}}&lt;br /&gt;
    }   {{comment|der Block endet}}&lt;br /&gt;
   &lt;br /&gt;
    return 0;&lt;br /&gt;
 }  {{comment|&amp;quot;main&amp;quot; endet}}&lt;br /&gt;
&lt;br /&gt;
=Datentypen=&lt;br /&gt;
==Elementare Datentypen==&lt;br /&gt;
Der Datentyp einer Variable gibt an, welche Werte eine Variable enthalten kann, welcher Art diese Daten sind und wie sie verarbeitet werden, etwa in arithmetischen Operationen wie einer Addition. So ist es zum Beispiel möglich, in eine Variable vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ganze Zahlen zwischen ca. -32000 und +32000 einzutragen. In einer char-Variable können ASCII-Zeichen gespeichert werden (alles, was Sie mit der Tastatur erzeugen können) oder ganze Zahlen von -128 bis 127.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da C plattformabhängig ist, hängt die Größe eines Datentypes zum Teil von der genutzten Hardware (z.B. 8, 16 oder 32 Bit-Controller) und dem Compiler und dessen Einstellungen ab!&lt;br /&gt;
&lt;br /&gt;
===int, char, short, long (ganze Zahlen)===&lt;br /&gt;
In Variable dieser Typen können Sie ganze Zahlen abspeichern, also z.B. 1, &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;2, 100, 12345. Jeden dieser Typen gibt es in zwei Ausprägungen: als &amp;quot;&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;quot;, also als vorzeichenbehafteten Typ, und als &amp;quot;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&amp;quot;, also ohne Vorzeichen, d.h. das Vorzeichen wird als 0 oder +1 genommen. &lt;br /&gt;
&lt;br /&gt;
Vorzeichenbehaftete Ganzzahl-Typen werden intern im &amp;lt;tt&amp;gt;n-1&amp;lt;/tt&amp;gt;-Komplement dargestellt, das Vorzeichen selbst findet sich also im höchstwertigen Bit. Werden zur Speicherung ''b'' Bits verwendet, dann reicht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;z.B. *zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==Enum==&lt;br /&gt;
&lt;br /&gt;
Über &amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt; können Aufzählungen definiert werden. Die Werte sind &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Werte und beginnen mit&amp;amp;nbsp;0. Der folgende enum hat einen um&amp;amp;nbsp;1 grösseren Wert. Mit einer Zuweisung können auch andere Werte zugeordnet werden. Klarer wird's im Beispiel:&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 enum Farben&lt;br /&gt;
 {&lt;br /&gt;
    ROT,&lt;br /&gt;
    GRUEN,&lt;br /&gt;
    BLAU,&lt;br /&gt;
    BRAUN = 5,&lt;br /&gt;
    SCHWARZ&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
Dies definiert die Konstanten &amp;lt;tt&amp;gt;ROT=0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;GRUEN=1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BLAU=2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BRAUN=5&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;SCHWARZ=6&amp;lt;/tt&amp;gt; und den Typ &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void foo (enum Farben farbe)&lt;br /&gt;
{&lt;br /&gt;
   switch (farbe)&lt;br /&gt;
   {&lt;br /&gt;
      case ROT:&lt;br /&gt;
         ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit kann man anstatt &amp;quot;magischer&amp;quot; Zahlen sprechende Namen im Code verwenden, etwa in Berechnungen und Zuweisungen, Vergleichen oder als Konstante hinter einem &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zusammengesetzte Datentypen==&lt;br /&gt;
===Arrays===&lt;br /&gt;
Oft muß man sehr viele Werte gleichzeitig abspeichern und betrachten, die alle der selben Aufgabe dienen. Man schreibt z.B. ein Programm, das 10 Zahlen einlesen und anschließend wieder ausgeben soll. Man könnte das natürlich mit 10 einzelnen Variablen bewerkstelligen, aber es ist sinnvoller, dabei Arrays &amp;amp;ndash; teilweise auch als ''Felder'' bezeichnet &amp;amp;ndash; zu verwenden.&lt;br /&gt;
&lt;br /&gt;
In einem Array werden mehrere Variablen gleichen Typs zusammengefasst und hintereinander im Speicher abgelegt. So kann man viele tausend Variablen anlegen mit nur einer Zeile Code. Doch es gibt noch größere Vorteile: Sie können das Array mit einer Schleife ganz einfach nach Werten durchsuchen. Stellen Sie sich vor, Sie müssten mit 100 verschiedenen Variablen &amp;lt;tt&amp;gt;Zahl_00&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;Zahl_99&amp;lt;/tt&amp;gt; arbeiten!&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}}&amp;amp;#91;{{Konstante}}&amp;amp;#93;;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 unsigned int werte[100];&lt;br /&gt;
&lt;br /&gt;
Der Name muß natürlich ein gültiger Bezeichner sein, als Datentyp kann jeder Typ genommen werden &amp;amp;ndash; sowohl elementare Datentypen als auch Zeiger, Strukturen, Unions oder selbst definierte Datentypen. In der eckigen Klammer wird die Anzahl der Elemente bekanntgegeben. Ein mit [3] definiertes Array hat Platz für drei Variablen. Da der Index immer bei 0 beginnt, greift man also mit &amp;lt;tt&amp;gt;[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;[1]&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;[2]&amp;lt;/tt&amp;gt; auf den jeweilige Inhalt zu. Um auf eine der im Array enthaltenen Variablen zugreifen zu können, müssen Sie den Variablennamen und in eckigen Klammern den Index (die &amp;quot;Nummer&amp;quot;) der Variablen angeben. Diese Variable verhält sich dann wie eine ganz normale Variable des jeweiligen Datentypes. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #define NZAHLEN 10&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int i;&lt;br /&gt;
    int zahlen[NZAHLEN];  {{comment|zahlen[0] ... zahlen[9]}}&lt;br /&gt;
  &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++)&lt;br /&gt;
    {&lt;br /&gt;
       printf (&amp;quot;Bitte Zahl %d eingeben: &amp;quot;, i);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; zahlen[i]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++) &lt;br /&gt;
       printf (&amp;quot;Zahl %d ist: %d\n&amp;quot;, i, zahlen[i]);&lt;br /&gt;
      &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 10 int-Variablen großes Array angelegt. &lt;br /&gt;
In dieses wird nun der Reihe nach 10 Zahlen eingelesen. &lt;br /&gt;
Anschließend werden alle 10 Zahlen ausgegeben. &lt;br /&gt;
&lt;br /&gt;
Dabei wird die Größe der Arrays und das Schleifenende über das Define &amp;quot;&amp;lt;tt&amp;gt;NZAHLEN&amp;lt;/tt&amp;gt;&amp;quot; angegeben. Dadurch muss nur ''eine Stelle'' im Code geändert werden, wenn die Größe des Arrays einmal einen anderer Wert als 10 haben soll &amp;amp;ndash; dies vermeidet Fehler die dadurch entstehen, wenn man beim Anpassen der Array-Größe eine Codestelle vergisst, zudem wird der Code lesbarer als wenn irgendwo die Zahl &amp;quot;10&amp;quot; auftaucht.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
:Wird ein ungültiger Index angeben (einer, der in der Deklaration nicht enthalten ist) können  undefinierte Dinge passieren, wenn dadurch andere Variableninhalte oder Programmcode überschrieben wird, der hinter oder vor dem Array im Speicher liegt. Schlimmstenfalls kann sogar der Computer/Controller abstürzen. Also darauf achten, daß keine ungültigen Werte als Index auftreten!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Strings (Zeichenketten)===&lt;br /&gt;
Ein String ist nichts anderes als ein Array, das aus einzelnen Zeichen (&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;) gebildet wird. Die Ausgabe auf dem Bildschirm funktioniert am einfachsten mittels Strings.&lt;br /&gt;
&lt;br /&gt;
Die Definition eines Strings erfolgt also genauso wie bei Arrays:&lt;br /&gt;
 char string[21];&lt;br /&gt;
&lt;br /&gt;
Nun haben Sie eine String, in dem Sie 21 Zeichen speichern können. Ganz richtig ist das jedoch nicht. C arbeitet mit &amp;quot;null-terminierten Strings&amp;quot;. Das beudeutet, dass die Länge des Strings nicht abgespeichert wird, sondern das Zeichen mit dem ASCII-Wert 0 das Stringende kennzeichnet. Daher auch die Bezeichnung  &amp;quot;null terminiert&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Das letzte Zeichen eines Strings muß daher immer das ASCII-Zeichen Nr. 0 sein. Ist es das nicht, hat der String kein definiertes Ende, und wenn Sie versuchen, ihn durch eine Standard-Funktion auszugeben zu lassen, könnte es eine Weile dauern, bis sich im Speicher zufällig irgendwo eine 0 befindet. Es stehen ihnen daher bei dem Beispiel nur 20 Zeichen zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
===Mehrdimensionale Arrays===&lt;br /&gt;
Manchmal benötigt man mehr als nur ein eindimensionales Array, wie Sie es bisher kennengelernt haben. Auch dies ist kein Problem. In der Deklaration geben Sie einfach mehrere eckige Klammern hintereinander an. Aber Vorsicht: der Speicherplatz ist begrenzt, ein &amp;quot;&amp;lt;tt&amp;gt;char feld[1024][1024]&amp;lt;/tt&amp;gt;&amp;quot; hat die Speicherplatzgrenzen vermutlich bereits weit überschritten, und der Compiler wird einen (bei gewissen Einstellung auch keinen) Fehler liefern.&lt;br /&gt;
Beim Zugriff auf mehrdimensionale Felder müssen auch mehrere Indizes angeben werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  int x,y;&lt;br /&gt;
  int feld[3][5];&lt;br /&gt;
 &lt;br /&gt;
  for (x=0; x&amp;lt;3; x++) &lt;br /&gt;
  {&lt;br /&gt;
     for (y=0; y&amp;lt;5; y++)&lt;br /&gt;
     {&lt;br /&gt;
       printf (&amp;quot;Feldwert x: %d,  y: %d &amp;quot;, x, y);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; feld[x][y]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  for(x=0; x&amp;lt;3; x++) &lt;br /&gt;
     for (y=0; y&amp;lt;5; y++) &lt;br /&gt;
        printf (&amp;quot;Wert: feld[%d][%d] = %d\n&amp;quot;, x, y, feld[x][y]);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 3 mal 5 &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array angelegt. &lt;br /&gt;
Dann werden die Werte eingegeben: zuerst &amp;lt;tt&amp;gt;feld[0][0]&amp;lt;/tt&amp;gt;, dann &amp;lt;tt&amp;gt;feld[0][1]&amp;lt;/tt&amp;gt;, usw. bis &amp;lt;tt&amp;gt;feld[2][4]&amp;lt;/tt&amp;gt;. &lt;br /&gt;
Zum Schluß werden alle Werte noch einmal ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===Strukturen===&lt;br /&gt;
In C können Sie sogenannte &amp;quot;Strukturen&amp;quot; definieren. Dabei handelt es sich um eine Zusammenfassung mehrerer Datentypen zu einem größeren. Im Unterschied zu Feldern können in Strukturen unterschiedliche Datentypen zusammengestellt und gespeichert werden: &lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 struct {{Bezeichner}}&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur 'Person'}}&lt;br /&gt;
 struct Person &lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;lt;tt&amp;gt;struct Person {&amp;lt;/tt&amp;gt;&amp;quot; leitet die Definition der Struktur mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;Person&amp;lt;/tt&amp;gt;&amp;quot; ein. &lt;br /&gt;
Dann werden in dieser Struktur fünf Komponenten definiert: drei Strings und zwei &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. &lt;br /&gt;
mit &amp;lt;tt&amp;gt;}&amp;lt;/tt&amp;gt; wird die Definition abgeschlossen. Sie haben damit einen Datentyp erstellt. Um eine Variable des Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach an&lt;br /&gt;
 struct Person {{Bezeichner}};&lt;br /&gt;
&lt;br /&gt;
Zum Zugriff auf eine Komponente der Struktur gibt man den Namen der Struktur-Variablen an (im folgenden Beispiel also &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;klaus&amp;lt;/tt&amp;gt;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
 {{comment|Definition zweier Struktur-Variablen}}&lt;br /&gt;
 struct Person hubert, klaus;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Zugriff auf Struktur-Komponenten}}&lt;br /&gt;
 hubert.alter = 32;&lt;br /&gt;
 klaus.alter = hubert.alter + 1;&lt;br /&gt;
&lt;br /&gt;
===Unions===&lt;br /&gt;
Eine Union wird ganz analog zu einer Struktur deklariert und verwendet. Sie unterscheidet sich von einer Struktur jedoch dadurch, daß ihre Elemente nicht nacheinander im Speicher abgelegt werden, sondern sich überlagern. Auf die in einer Union enthaltenen Daten gibt es also verschiedene Sichten: je nachdem, welche Sicht bzw. Interpretation der Daten man gerne hätte, wählt man den gewünschten Zugriff.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
union Daten &lt;br /&gt;
{&lt;br /&gt;
   int id;&lt;br /&gt;
&lt;br /&gt;
   struct Person u_person;&lt;br /&gt;
&lt;br /&gt;
   struct u_double&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      double wert;&lt;br /&gt;
   };&lt;br /&gt;
&lt;br /&gt;
   struct u_pointer&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      union Daten * p1;&lt;br /&gt;
      union Daten * p2;&lt;br /&gt;
   };&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
union Daten data;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies definiert eine Union mit den vier Zugriffsmöglichkeiten &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_double&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Größe der Union richtet sich dabei nach der grössten Komponente. In diesem Beispiel sind alle Komponenten so angelegt worden, daß sie an erster Stelle ein &amp;lt;tt&amp;gt;int id&amp;lt;/tt&amp;gt; enthalten. In &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; könnte man sich also merken, wie die Daten in der Union zu interpretieren sind. Würde &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; nicht dieses &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; enthalten, so würde sich &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; mit &amp;lt;tt&amp;gt;data.u_person.vname&amp;lt;/tt&amp;gt; überlagern. Ein Ändern der ersten Buchstaben von &amp;lt;tt&amp;gt;vname&amp;lt;/tt&amp;gt; hätte also ein Ändern von &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; zur Folge, und man könnte es nicht mehr als Merker verwenden. Mit diesem Feld überlagert das &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; die &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;-Felder der anderen Sichten, z.B. ist &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; der selbe Zugriff wie auf &amp;lt;tt&amp;gt;data.u_person.id&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein anderes Beispiel ist eine Union, die es ermöglicht, auf die einzelnen Bytes eines &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; zuzugreifen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef union&lt;br /&gt;
{&lt;br /&gt;
   unsigned long  as_long;&lt;br /&gt;
   unsignen short as_short[2];&lt;br /&gt;
   unsignen char  as_byte[4];&lt;br /&gt;
} data32_t;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies überlagert einen &amp;lt;tt&amp;gt;unsigned long&amp;lt;/tt&amp;gt; &amp;amp;ndash; also eine 32-Bit-Zahl &amp;amp;ndash; mit vier Bytes bzw. zwei Shorts.&lt;br /&gt;
 data32_t wert;&lt;br /&gt;
 &lt;br /&gt;
 wert.as_long = 0x12345678;&lt;br /&gt;
 wert.as_byte[0] = 0xab;&lt;br /&gt;
 {{comment|nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform)}}&lt;br /&gt;
&lt;br /&gt;
==Eigene Datentypen==&lt;br /&gt;
&lt;br /&gt;
=Variablen=&lt;br /&gt;
Eine Variable ist ein Synonym (=anderer Name) für eine Speicherstelle in einem Computer. Einfacher gesagt, eine Variable bietet Raum, um Daten wie Zahlen oder Zeichen zu speichern und wieder zu lesen.&lt;br /&gt;
&lt;br /&gt;
==Variablennamen==&lt;br /&gt;
Ein Variablenname kann zusammengesetzt werden aus den Buchstaben &amp;lt;tt&amp;gt;'''A'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''Z'''&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;'''a'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''z'''&amp;lt;/tt&amp;gt;, den Ziffern &amp;lt;tt&amp;gt;'''0'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''9'''&amp;lt;/tt&amp;gt;, sowie dem Sonderzeichen &amp;quot;Unterstrich&amp;quot; (underscore) &amp;lt;tt&amp;gt;'''_'''&amp;lt;/tt&amp;gt;. Dabei darf an erster Stelle keine Ziffer stehen. Die Bezeichner &amp;lt;tt&amp;gt;hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALLO&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALL0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;_123&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_HALLO&amp;lt;/tt&amp;gt; sind also alle gültige und unterschiedliche Variablennamen.&lt;br /&gt;
&lt;br /&gt;
==Anlegen von Variablen==&lt;br /&gt;
Um eine Variable verwenden zu können, muss sie zuerst vereinbart (&amp;quot;erzeugt&amp;quot;) werden. Dies wird auch als &amp;quot;''Definition der Variablen''&amp;quot; bezeichnet und geht so: Schreiben Sie zuerst den Datentyp, dann den Namen der Variablen. Zum Schluß kommt noch der Strichpunkt, wie nach jeder C-Anweisung oder Deklaration. Und nicht vergessen: C unterscheidet zwischen  Groß- und Kleinschreibung! &lt;br /&gt;
 int Zahl1, Zahl2;&lt;br /&gt;
 char Zeichen;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    float gleitZahl;&lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:'''&lt;br /&gt;
In einer Zeile können auch mehrere Variablen gleichen Types vereinbart werden, wenn man ein Komma dazwischen setzt. Variablen können in jedem Block vereinbart werden. Siehe [[#Gültigkeitsbereich|Gültigkeitsbereich]].&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen==&lt;br /&gt;
Man kann einer vereinbarten Variable Werte [[#Zuweisungen|zuweisen]]. Dazu schreibt man zuerst den Variablennamen, ein Gleichheitszeichen &amp;quot;&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;&amp;quot; und anschliessend den zuzuweisenden [[#Ausdrücke|Ausdruck]]. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, zahl2 = 12;&lt;br /&gt;
  char zeichen1 = 'A';&lt;br /&gt;
&lt;br /&gt;
  zahl1 = 52;&lt;br /&gt;
  zeichen1 = zeichen1 + 1; &lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Zuerst werden drei Variablen angelegt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;: wird gleich bei der Vereinbarung der Wert 12 zugewiesen. &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl1 = 52&amp;lt;/tt&amp;gt;: Hier wird der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; der Wert 52 zugewiesen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;: wird um 1 erhöht. Da in der Variablen &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; gespeichert ist, gibt sich ihr neuer Wert aus &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt;. Weil &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; dem Wert 65 entspricht, ist &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt; gleich 66, was dem Wert für &amp;lt;tt&amp;gt;'B'&amp;lt;/tt&amp;gt; entspricht.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei float==&lt;br /&gt;
Das funktioniert genau wie bei normale Zuweisungen. Nachkommastellen werden durch einen Punkt abgegrenzt: &lt;br /&gt;
 floatVariable = 3.14;&lt;br /&gt;
Zusätzlich kann eine Zehnerpotenz angegeben werden:&lt;br /&gt;
 floatVariable2 = -1.234E-6;&lt;br /&gt;
Dadurch wird der erst Wert mit 10&amp;lt;sup&amp;gt;&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;6&amp;lt;/sup&amp;gt; multipliziert, der Wert der Variablen ist also &lt;br /&gt;
:&amp;lt;math&amp;gt;-1{,}234\cdot10^{-6} = -0.000001234&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei logischen Variablen==&lt;br /&gt;
Wie bereits erwähnt, besitzt C keinen logischen Datentyp. Es müssen also &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; dafür genutzt werden. Die Zuweisung entpricht der Standard-Zuweisung. Wird der Wert 0 zugewiesen, dann ist die Variable &amp;quot;unwahr&amp;quot;, ansonsten ist sie &amp;quot;wahr&amp;quot;. &lt;br /&gt;
 intVariable = !0;   /* entspricht &amp;quot;wahr&amp;quot;   */&lt;br /&gt;
 intVariable = 0;    /* entspricht &amp;quot;unwahr&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
==Konstanten==&lt;br /&gt;
Konstanten können als Variable angesehen werden, die nicht beschrieben, sondern nur gelesen werden können. Ein typisches Beispiel dafür ist die Zahl &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; (rund 3,141592654). Niemand würde in der realen Welt versuchen, ihr einen anderen Wert zuzuweisen. Würde man &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; jedoch wie eine normale Variable anlegen, wäre dies ohne weiteres möglich. Um dies zu verhindern, gibt es das Schlüsselwort &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in C:&lt;br /&gt;
 const {{Type}} {{Bezeichner}} = {{Konstante}};  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Wichtig dabei ist, dass man Konstanten nur bei der Vereinbarung einen Wert zuweisen kann. &lt;br /&gt;
Da Konstanten gewöhnlich im gesamten Programm, zumindest einer Quelldatei genutzt werden, definiert man diese allerdings gewöhnlich außerhalb des main-Blockes entweder am Anfang eines Programmes, oder in einer sogenannten Header-Datei, die per &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; eingebunden wird.&lt;br /&gt;
 const float PI = 3.141592;  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Es sei jedoch erwähnt, daß auch einer Konstanten nachträglich ein anderer Wert zugewieden werden kann. Im obigen Beispiel könnte mit&lt;br /&gt;
 * ((float*) &amp;amp;PI) = 2;&lt;br /&gt;
der Wert von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; im Nachhinein verändert werden. Es wird die Adresse von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; genommen und diese Adresse durch den Cast in eine ganz normale &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;-Adresse umgewandelt, über welche der Wert geändert wird. Die sei der Vollständigkeit halber erwähnt.&lt;br /&gt;
&lt;br /&gt;
Je nachdem, an welcher Stelle sich das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; bei einer Pointer-Deklaration befindet, markiert es den Pointer als konstant oder das Objekt, auf das dieser Pointer zeigt. Eine häufige Parameterdeklaration in Ausgabe-Funktionen, die einen String erhalten, ist&lt;br /&gt;
 void foo (const char * str, ...);&lt;br /&gt;
Dadurch ist &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; der Zeiger auf eine Zeichenkette, die innerhalt der Funktion nicht verändert wird bzw. verändert werden darf. Eine Zuweisung wie &amp;lt;tt&amp;gt;*str = 'a'&amp;lt;/tt&amp;gt; ergibt also einen Fehler. &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; selbst kann aber sehr wohl verändert werden, etwa mit &amp;lt;tt&amp;gt;str++&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Soll ausgedrückt werden, daß &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; unveränderlich ist, dann so:&lt;br /&gt;
 void foo (char * const str, ...);&lt;br /&gt;
Jetzt wäre eine Änderung des Strings in Ordnung, etwa durch &amp;lt;tt&amp;gt;str[10] = 'a'&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Um sich zu merken, worauf das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; wirkt, trennt man die Deklaration in Gedanken beim&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf: Steht das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; links vom&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, dann gehört es zum &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, steht es rechts davon, dann gehört es zum Pointer. Natürlich ist es auch denkbar, beides &amp;amp;ndash; also den Zeiger und sein Ziel &amp;amp;ndash; als konstant zu markieren.&lt;br /&gt;
&lt;br /&gt;
==Gültigkeitsbereich==&lt;br /&gt;
In C können mehrere Variablen den gleichen Namen haben, solange eindeutig ist, welche in welchen Block gültig ist. Dabei gelten folgende Regeln: &lt;br /&gt;
&lt;br /&gt;
;Lokale Variablen: sind Variablen, die innerhalb eines Blockes definiert werden. Jede Variable ist nur in dem Block gültig, in dem sie vereinbart wurde, sowie in allen darin enthaltenen Blöcken; es sei denn, in einem Unter-Block wird eine Variable gleichen Namens definiert. Dann bezieht sich in diesem Unter-Block der Bezeichner auf die im Unter-Block angelegte Variable.&lt;br /&gt;
;Globale Variablen: werden ausserhalb jedes Blockes definiert und gelten ab der Stelle, an der sie deklariert werden, siehe auch [[#Deklaration und Definition|Deklaration und Definition]]. Wird jedoch in einem Block eine Variable gleichen Namens angelegt, gilt ab hier bis zum Ende des Blocks nicht mehr die globale Variable, sondern die im Block deklarierte. Das Spiel kann man weiterspielen: wird in einem Unter-Block wieder eine namensgleiche Variable angelegt, gilt diese in dem Unterblock.&lt;br /&gt;
&lt;br /&gt;
==Speicherklassen==&lt;br /&gt;
Jede Variable in C gehört zu einer bestimmten Speicherklasse&lt;br /&gt;
;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;: Lokale Variablen sind in aller Regal sogenannte ''automatische Variablen''. Das bedeutet, sie werden automatisch angelegt, wenn ein Block bzw. eine Funktion betreten wird und danach wieder entfernt. Das Schlüsselwort &amp;quot;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;&amp;quot; wird praktisch nie hingeschrieben, denn lokale Variablen ohne die ausdrückliche Angabe einer Speicherklasse, sind automatisch automatische Variablen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;: Eine externes Symbol ist im ganzen Programm bekannt bzw. in dem Block, in der die Deklaration steht. In unterschiedlichen Blöcken stehende Deklarationen beziehen sich auf das gleiche Symbol! Obgleich das Datum global zugreifbar ist, ist der Gültigkeitsbereich auf den deklarierenden Block begrenzt bzw. auf das deklarierende Quell-Modul, sofern das Symbol ausserhalb jedes Blocks des Moduls deklariert wird. Siehe auch [[#Deklaration und Definition|Deklaration und Definition]].&lt;br /&gt;
;&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;: Die Variable ist im Block gültig bzw. im Quell-Modul (also in der C-Datei, in der die angelegt wurde), wenn sie nicht innerhalb eines Blockes angelegt wurde. Statische Variablen werden nicht in Registern oder im Frame der Funktion angelegt, sondern im selben Speicherbereich, in dem auch die globalen Variablen liegen; Konstanten evtl. auch im Flash. Eine lokale Variable, die als &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; angelegt wird, &amp;quot;überlebt&amp;quot; also das Verlassen des Blocks und hat beim neuerlichen Betreten des Blockes ihren bisherigen Wert. In unterschiedlichen Blöcken angelegte lokale statische Variablen beziehen sich auf unterschiedliche Speicherstellen, genau wie bei lokalen Variablen auch.&lt;br /&gt;
;&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;: Durch diese Speicherklasse wird eine Variable &amp;amp;ndash; falls möglich &amp;amp;ndash; als Registervariable angelegt, also in einem Maschinenregister des Computer/Controllers gehalten. Dadurch kann auf solche Variablen besonders schnell zugegriffen werden. Dieses Schlüsselwort ist bei modernen Compilern weitgehend überflüssig, da die entsprechenden Optimierungen selbständig vorgenommen werden, wenn ausreichend Register vorhanden sind. Auch globale Variablen können als Register angelegt werden, davon ist dem Anfänger aber dringend abzuraten, weil leicht schwerauffindbare Fehler und Abstürze auftreten, wenn man nicht genau weiss, welche Implikationen in einer solchen Definition stecken!&lt;br /&gt;
;&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;: (FIXME: volatile ist ein Qualifier und keine Speicherklasse) Dies ist das genaue Gegenteil von &amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt; und bewirkt, dass die Variable auf keinen Fall in einem Register zwischengespeichert werden darf, sondern immer aus dem RAM gelesen und ins RAM geschrieben werden soll. &amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt; müssen alle ''globalen'' Variablen markiert werden, die in [[ISR | Interrupt-Handlern]] verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Ausdrücke=&lt;br /&gt;
Eine Variable oder eine Konstante in C stellen einfache Ausdrücke dar.&lt;br /&gt;
Diese elementaren Ausdrücke können durch Operatoren miteinander verknüpft werden und so zu neuen, komplexeren Ausdrücken zusammen gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Einfache Beispiele für Ausdrücke sind also z.B.:&lt;br /&gt;
 1&lt;br /&gt;
 a&lt;br /&gt;
 'a'&lt;br /&gt;
 1 + a&lt;br /&gt;
 a == 1&lt;br /&gt;
&lt;br /&gt;
Auch Funktionen können einen Wert zurückliefern und in Ausdrücken weiter benutzt werden.&lt;br /&gt;
In den folgenden Abschnitten wird gezeigt, welche Operatoren in C vorhanden sind,&lt;br /&gt;
und wei man damit neue Ausdrücke aufbauen kann.&lt;br /&gt;
&lt;br /&gt;
==Lvalues==&lt;br /&gt;
&lt;br /&gt;
Ein Lvalue in C ist ein Ausdruck, dem ein anderer Ausdruck zugewiesen werden kann, dessen Wert also durch eine Zuweisung verändert werden kann.&lt;br /&gt;
das 'L' leitet sich ab von 'left' bwz. 'links' und das 'value' bedeutet Wert: Ein Lvalue ist ein Ausdruck, der auf der linken Seite einer Zuweisung stehen darf. Ein Lvalue ist also immer auch ein gültiger Ausdruck, aber die Umkehrung gilt in alles Regel nicht.&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für einen Lvalue ist eine &amp;quot;normale&amp;quot; Variable, die nicht mit &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; als Konstante markiert ist:&lt;br /&gt;
 a = 1;&lt;br /&gt;
Hingegen ist der Ausdruck &amp;lt;tt&amp;gt;a+1&amp;lt;/tt&amp;gt; kein Lvalue, denn eine Zuweisung wie&lt;br /&gt;
 a+1 = 2;&lt;br /&gt;
die mathematisch durchaus sinnvoll ist, erzeugt einen Compilerfehler, der etwa lauten könnte &amp;quot;illegal lvalue in assignment&amp;quot;:&lt;br /&gt;
&amp;quot;ungültiger Wert in Zuweisung&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Andere Beipiele für Lvalues sind die Komponenten von (nicht-konstanten) [[#Strukturen|Strukturen]] und [[#Unions|Unions]], [[#Arrays|Array]]-Elemente und die Dereferenzierungen von Pointern: Die Konstante&amp;amp;nbsp;4 wird durch den Cast in eine Adresse umgewandelt. Über die Dereferenzierung&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; wird an die Adresse&amp;amp;nbsp;4 im Speicher eine&amp;amp;nbsp;3 geschrieben. Ob das erlaubt bzw. sinnvoll ist, ist abhängig von der jeweiligen Architektur.&lt;br /&gt;
 * ((unsigned int *) 4) = 3;&lt;br /&gt;
Hier ist der gesamte &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;-Ausdruck ein Lvalue&lt;br /&gt;
&lt;br /&gt;
==Logische (boolsche) Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp;amp;&amp;amp;amp; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr oder &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; || gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; || ungleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;= b&amp;lt;/tt&amp;gt; || kleiner oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt; b&amp;lt;/tt&amp;gt; || kleiner als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt;= b&amp;lt;/tt&amp;gt; || glösser oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt; b&amp;lt;/tt&amp;gt; || grösser als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; nicht wahr und vice versa&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine interessante Eigenschaft der Operatoren &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;amp;amp;&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; ist, dass&lt;br /&gt;
sie die Auswertung abbrechen, sobald das Ergebnis feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet. Ein oft anzutreffendes Codestück sieht so aus, dabei sei &amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
  if (p &amp;amp;&amp;amp; *p == 5)&lt;br /&gt;
  {&lt;br /&gt;
     {{comment|mach was}}&lt;br /&gt;
  }&lt;br /&gt;
Zuerst wird in der Bedinung geprüft, ob Zeiger&amp;amp;nbsp;&amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; einen Wert ungleich Null hat, also ob er überhaupt einen gültigen Wert enthält. Es ist weit verbreitete Konvention in C, daß Zeiger, die keinen gültigen Wert haben, die Adresse&amp;amp;nbsp;0 enthalten. '''Nur dann, wenn ein Zeiger nicht ein Null-Pointer ist, darf überhaupt ein Zugriff über ihn erfolgen!'''&lt;br /&gt;
&lt;br /&gt;
==Vergleich von Variablen==&lt;br /&gt;
Skalare Variablen (also ganze Zahlen, Gleitkommazahlen, Zeiger) können miteinander verglichen werden. Dazu gibt es die folgenden Operatoren in C: &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; || ist nicht gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;=&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;=&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das Ergebnis der Auswertung ist eine ganze Zahl. Ist die Bedingung erfüllt, dann ist der Wert ungleich&amp;amp;nbsp;0. Ist die Bedingung nicht erfüllt, dann ist ihr Wert gleich&amp;amp;nbsp;0.&lt;br /&gt;
Meistens wird man diese Operatoren in &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Konstrukten finden wie zum Beispiel&lt;br /&gt;
 if (x &amp;gt;= 10)&lt;br /&gt;
    x = 10;&lt;br /&gt;
oder in Abbruchbedingungen von Schleifen, wie sie weiter unten erklärt werden.&lt;br /&gt;
&lt;br /&gt;
Es ist auch möglich, das Ergebnis der Auswertung in einer &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Variablen zu speichern:&lt;br /&gt;
 int i;&lt;br /&gt;
 int z1, z2;&lt;br /&gt;
 &lt;br /&gt;
 z1 = 5;&lt;br /&gt;
 z2 = 100;&lt;br /&gt;
 i = z1 &amp;lt;= z2;  {{comment|Ein Vergleich. i wird &amp;quot;wahr&amp;quot;, da z1 kleinergleich z2 ist}}&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich&amp;amp;nbsp;0 (&amp;quot;wahr&amp;quot;), wenn &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; kleiner oder gleich &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt; ist. Ist &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; jedoch größer als &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt;, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich&amp;amp;nbsp;0 (&amp;quot;unwahr&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
==Arithmetische Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a + b&amp;lt;/tt&amp;gt; || Summe (Addition)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a - b&amp;lt;/tt&amp;gt; || Differenz (Subtraktion)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a * b&amp;lt;/tt&amp;gt; || Produkt (Multiplikation)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a / b&amp;lt;/tt&amp;gt; || Quotient (Division, evtl. mit Rest)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a % b&amp;lt;/tt&amp;gt; || Rest bei Division (Modulo)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;-a&amp;lt;/tt&amp;gt; || Vorzeichenumkehr (Zweierkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Bit-Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp; b&amp;lt;/tt&amp;gt; || bitweise und (and)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || bitweise oder (or)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a ^ b&amp;lt;/tt&amp;gt; || bitweise exclusiv-oder (xor, exor)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;~a&amp;lt;/tt&amp;gt; || jedes Bit in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; invertieren (not, Einerkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Index-Operator bei Arrays==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a[b]&amp;lt;/tt&amp;gt; || das (b+1)ste Element des Feldes a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Folgendes gilt es bei der Verwendung des Indexoperators zu beachten:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; muss ein [[C-Tutorial#Felder | Feld]] oder [[C-Tutorial#Zeiger | Zeiger]] sein&lt;br /&gt;
# &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; muss ein Integer sein oder ein Datentyp, der sich in einen int umwandeln läßt (z.B. char)&lt;br /&gt;
# Es wird nicht geprüft, ob der Index &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; im Feld &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gültig ist!&lt;br /&gt;
# Der erste Index eines Feldes ist immer 0. Daher ''(b+1)stes Element'' in der Beschreibung&lt;br /&gt;
&lt;br /&gt;
==Komponenten-Auswahl bei Structs und Unions==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a.b&amp;lt;/tt&amp;gt; || Element b der [[C-Tutorial#Strukturen | Struktur]] oder des Unions a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adress-Operator und Dereferenzierung==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&amp;amp;amp;a&amp;lt;/tt&amp;gt; || Speicheradresse der Variablen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;*a&amp;lt;/tt&amp;gt; || Wert, der an der Adresse &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a-&amp;amp;gt;b&amp;lt;/tt&amp;gt; || Wert des Elements &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; der Struktur, deren Adresse in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Adressoperator &amp;amp; kann auf Variablen angewendet werden und&lt;br /&gt;
gibt die Startadresse der Variablen im Speicher zurück.&lt;br /&gt;
&lt;br /&gt;
Handelt es sich bei einer Variable um einen [[C-Tutorial#Zeiger | Zeiger]], so enthält&lt;br /&gt;
sie eine Speicheradresse. Um an den '''Wert''' zu gelangen, der&lt;br /&gt;
an dieser Adresse steht, wird der Operator * vorangestellt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
&lt;br /&gt;
 {{comment|x ist eine Integervariable und hat den Wert 5}}&lt;br /&gt;
 int x = 5;&lt;br /&gt;
     &lt;br /&gt;
 {{comment|z ist ein Zeiger auf eine Integer-Variable und enthaelt somit}}&lt;br /&gt;
 {{comment|die Speicheradresse einer Integer-Variablen}}&lt;br /&gt;
 int *z;       &lt;br /&gt;
  &lt;br /&gt;
 {{comment|Verwendung des Adress-Operators: weist an z die Adresse von x zu}}&lt;br /&gt;
 z = &amp;amp;x;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Verwendung der Dereferenzierung}}&lt;br /&gt;
 {{comment|erhoehe den Wert, der bei Adresse z steht, um eins}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|da z auf x zeigt, hat x jetzt den Wert 6}}&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff auf Struktir- und Union-Elemente eine abkürzende Schreibweise möglich:&lt;br /&gt;
&lt;br /&gt;
Statt &lt;br /&gt;
  (*strukturZeiger).element&lt;br /&gt;
kann geschrieben werden&lt;br /&gt;
  strukturZeiger-&amp;gt;element&lt;br /&gt;
Beide Schreibweisen sind absolut gleichbedeutend, die Klammern bei der ersteren sind notwendig.&lt;br /&gt;
&lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
:Bei der Dereferenzierung durch &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; findet keine Prüfung statt, ob der Zeiger auch auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu einer Änderung '''irgendeiner''' Speicherstelle!&lt;br /&gt;
&lt;br /&gt;
 int *z; {{comment|z ist ein Zeiger auf einen int}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.}}&lt;br /&gt;
 {{comment|z enthaelt irgendeine ungueltige Adresse!!}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|&amp;quot;Erhoehe einen Integer _irgendwo_ im Speicher um 1&amp;quot; -&amp;gt; CRASH !!!}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
&lt;br /&gt;
==Cast-Operator==&lt;br /&gt;
&lt;br /&gt;
Der Cast Operator dient dazu, den Datentyp eines Wertes zu ändern. Dafür wird einfach der neue Datentyp in Klammern vor den Wert geschrieben.&lt;br /&gt;
&lt;br /&gt;
Um zum Beispiel aus einem Float ein Integer zu machen:&lt;br /&gt;
 var  = (int) 5.60;&lt;br /&gt;
Dabei wird der Wert aber auch gerundet, und es findet somit ein Informationsverlust statt.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Umwandeln einer ganzen Zahl in eine Adresse:&lt;br /&gt;
 int * addr;&lt;br /&gt;
 addr = (int*) 0x1234;&lt;br /&gt;
Damit ist &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; an Adresse 0x1234.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
Der Cast-Operator selbst führt ''keine Konvertierung'' von Darstellungen durch, etwa die Umwandlung der ganzen Zahl 123 ein den String &amp;lt;tt&amp;gt;&amp;quot;123&amp;quot;&amp;lt;/tt&amp;gt;, der diese Zahl darstellt! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
  int main(int argc, char ** argv)&lt;br /&gt;
  {&lt;br /&gt;
        char text[] = &amp;quot;5.6&amp;quot;;&lt;br /&gt;
        int zahl = (int) text;&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, zahl);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Anfangsadresse des Strings &amp;lt;tt&amp;gt;&amp;quot;5.6&amp;quot;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Komma-Operator==&lt;br /&gt;
Mit einem &amp;lt;tt&amp;gt;,&amp;lt;/tt&amp;gt; können mehrere Ausdrücke nacheinander ausgewertet werden.&lt;br /&gt;
Die Auswertung erfolgt von links nach rechts.&lt;br /&gt;
&lt;br /&gt;
Solche Konstrukte sieht man manchmal in Abfragen wie&lt;br /&gt;
 FILE  *file;&lt;br /&gt;
 if (file = fopen (&amp;quot;foo.exe&amp;quot;, &amp;quot;r&amp;quot;), file != NULL)&lt;br /&gt;
was erst an &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; einen Wert zuweist und den &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Block nur betritt,&lt;br /&gt;
wenn &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; nicht der Nullpointer ist.&lt;br /&gt;
&lt;br /&gt;
Bequem kann das auch in einer [[#for-Schleife|for-Schleife]] sein, wenn man zwei (oder mehr) Laufvariablen hat oder so:&lt;br /&gt;
 for (i=0, j=0; i &amp;lt; 10; i++, j += 2)&lt;br /&gt;
    &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Zuweisung===&lt;br /&gt;
=== ++ und -- ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; stellen einfachere Schreibweisen dar zum Addieren bzw. Subtrahieren von&amp;amp;nbsp;1.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; (Inkrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo++; &lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo + 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; 3}}&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; (Dekrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo--;&lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo - 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; -1}}&lt;br /&gt;
&lt;br /&gt;
Die beiden Operatoren können sowohl in der Präfix-Schreibweise (vor der Variablen) als auch als Postfix-Schreibweise (hinter der Variablen) notiert werden. &lt;br /&gt;
Der Unterschied liegt darin, dass beim Präfix der Wert zuerst neu berechnet wird und die Variable dann verwendet wird. Beim Postfix wird die Variable zuerst verwendet und erst nach Auswertung des Ausdrucks, in dem sie enthalten ist, neu berechnet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 int ausgabe1, ausgabe2, var1 = 10, var2 = 10;&lt;br /&gt;
 ausgabe1 = 3 * ++var1; {{comment|ausgabe1 &amp;amp;#61; 33; var1 &amp;amp;#61; 11;}}&lt;br /&gt;
 ausgabe2 = 3 * var2++; {{comment|ausgabe2 &amp;amp;#61; 30; var2 &amp;amp;#61; 11;}}&lt;br /&gt;
&lt;br /&gt;
Für Zeiger arbeiten diese Operatoren etwas anders, siehe dazu [[#Zeiger-Arithmetik|Zeiger-Arithmetik]].&lt;br /&gt;
&lt;br /&gt;
===Bedingter Ausdruck===&lt;br /&gt;
 ({{Bedingung}}) ? {{Ausdruck|1}} : {{Ausdruck|2}}&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; erfüllt ist, dann wertet dieser Ausdruck aus zu &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt;. Ist er nicht erfüllt, dann wertet er aus zu &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 x = (x &amp;gt;= 3) ? 0 : x+1;&lt;br /&gt;
Startet man &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; mit dem Wert 0, dann nimmt es bei mehrfacher Anwendung dieser Zeile (z.B. in einer Schleife) nacheinander die folgende Werte an:&lt;br /&gt;
:&amp;lt;tt&amp;gt;1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, ...&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&lt;br /&gt;
Wie auch in der Mathematik gibt es auch in C genaue Regeln über die Abarbeitungsreihenfolge (precedence)&lt;br /&gt;
der Operatoren. Dass sich alle C-Compiler genau an diesen ANSI-Vorschlag halten, ist leider nicht sicher.&lt;br /&gt;
Sicher jedoch ist, dass nicht jeder Programmierer diese Regel jederzeit im Kopf hat. &lt;br /&gt;
Daher ist es sinnvoll, Ausdrücke durch runde Klammern eindeutig zu kennzeichnen. &lt;br /&gt;
Nebenbei stören sich Compiler nicht an überflüssigen Klammerpaaren.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Priorität ||Operator||Assoziativität&lt;br /&gt;
|-&lt;br /&gt;
  &lt;br /&gt;
|&amp;lt;tt&amp;gt;15&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ( ) [ ] -&amp;gt; . &amp;lt;/tt&amp;gt;                      ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;14&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;! ~ ++ -- + - (TYP) * &amp;amp; sizeof &amp;lt;/tt&amp;gt;    ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;13&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; * / % (Rechenoperationen) &amp;lt;/tt&amp;gt;         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;12&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; + - (binär) &amp;lt;/tt&amp;gt;                       ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;11&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;&amp;lt; &amp;gt;&amp;gt; &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;10&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt; &amp;lt;= &amp;gt; &amp;gt;= &amp;lt;/tt&amp;gt;                         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 9&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; == != &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 8&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp; (bit-AND-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 7&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ^ (bit-XOR-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 6&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; (bit-OR-Operator)&amp;lt;/tt&amp;gt;   ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 5&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp;&amp;amp; &amp;lt;/tt&amp;gt;                                ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 4&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; &amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 3&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;? : &amp;lt;/tt&amp;gt;                               ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 2&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; = += -= /= *= %= &amp;gt;&amp;gt;= &amp;lt;&amp;lt;= &amp;amp;= &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;= ^= &amp;lt;/tt&amp;gt; ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 1&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; , (Sequenz-Operator) &amp;lt;/tt&amp;gt;              ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
&lt;br /&gt;
Peter Baeumle-Courth, ANSI-C im Überblick &amp;lt;p&amp;gt;&lt;br /&gt;
W. Alex, Einführung in C/C++&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
Eine Kontrollanweisung ist eine Anweisung, die Einfluss auf den Programmfluss hat. Normalerweise werden Anweisungen so ausgeführt, wie sie in der Quelldatei stehen: Von links nach rechts (falls mehrere Anweisungen in einer Zeile stehen sollten, wovon i.A. abzuraten ist) und von oben nach unten. Mit einer Kontrollanweisung kann dieser lineare Programmfluss durchbrochen werden: Die Codeausführung kann kann abhängig von einer Bedingung gemacht werden (&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;), kann wiederholt werden (Schleife) oder an einer anderen Stelle der Funktion fortgesetzt werden (&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==if-Anweisung==&lt;br /&gt;
Mit Hilfe des if-Befehls kann man Codeteile abhängig davon einer Bedingung ausführen lassen:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
oder mit else-Teil&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 if (x &amp;gt; 100)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;gt; 100 ist: Fehlerausgabe}}&lt;br /&gt;
    printf (&amp;quot;x = %d ist zu gross fuer die Berechnung!\n&amp;quot;, x);&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;lt;&amp;amp;#61; 100 ist: Berechne Summe der Zahlen 1...x}}&lt;br /&gt;
    {{comment|Die lokale Variable x2 lebt nur innerhalb dieses alse-Blocks}}&lt;br /&gt;
    int x2 = x;&lt;br /&gt;
 &lt;br /&gt;
    for (x = 0; x2 &amp;gt; 0; x2--)&lt;br /&gt;
       x += x2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Wenn die Bedingung wahr ist (&amp;lt;tt&amp;gt;x &amp;gt; 100&amp;lt;/tt&amp;gt;), dann wird eine Meldung ausgegeben; danach ist die if-Anweisung beendet. Der else-Block wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung nicht erfüllt (&amp;lt;tt&amp;gt;x &amp;amp;le; 100&amp;lt;/tt&amp;gt;), dann wird gleich zum else-Teil gesprungen, und nach dessen Ausführung der if-Befehl beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Ein häufiger Fehler ist es, statt &amp;lt;tt&amp;gt;if (a &amp;amp;#61;&amp;amp;#61; 23)&amp;lt;/tt&amp;gt; etwas wie &amp;lt;tt&amp;gt;if (a &amp;amp;#61; 23)&amp;lt;/tt&amp;gt; zu schreiben. &lt;br /&gt;
Dann wird allerdings nicht geprüft, ob die Variable&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gleich 23 ist, sondern der Variablen&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wird der Wert 23 zugewiesen. Der Ausdruck &amp;lt;tt&amp;gt;a &amp;amp;#61; 23&amp;lt;/tt&amp;gt; hat den Wert&amp;amp;nbsp;23 und ist damit immer &amp;quot;wahr&amp;quot;! Daher ist diese if-Bedingung immer erfüllt!&lt;br /&gt;
&lt;br /&gt;
Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken sondern bestenfalls eine Warnung. Damit ist dieser Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise &amp;lt;tt&amp;gt;if (23 &amp;amp;#61;&amp;amp;#61; a)&amp;lt;/tt&amp;gt;. Wenn man dort anstatt des Vergleichsoperators '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;amp;#61;&amp;lt;/tt&amp;gt;' den Zuweisungsoperator '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;lt;/tt&amp;gt;' verwendet, spuckt der Compiler sehr wohl einen Fehler aus! Ist die Zuweisung jedoch erwünscht und eine Compiler-Warnung lästig, dann wählt man eine Schreibweise wie &amp;lt;tt&amp;gt;if ((a &amp;amp;#61; b))&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;if (a &amp;amp;#61; b, a)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist zu schreiben &amp;lt;tt&amp;gt;if (Bedingung);&amp;lt;/tt&amp;gt; Richtig muss es heissen &amp;quot;&amp;lt;tt&amp;gt;if(Bedingung)&amp;lt;/tt&amp;gt;&amp;quot; Das Semikolon im ersten Fall ist eine leere Anweisung, die im if-Falle ausgeführt wird &amp;amp;ndash; sie bleibt also ohne Resultet. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt; ein auf das Semikolon folgende Anweisung die eigentlich zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören soll wird immer ausgeführt, die sie nicht mehr zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; dazu gehört.&lt;br /&gt;
}}&lt;br /&gt;
Bei verschachtelten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Konstrukten gehört ein &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zu letzten &amp;quot;freien&amp;quot; &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;. Soll in einer &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Folge das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zum ersten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören, dann ist das so zu hinzuschreiben:&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Ohne die geschweiften Klammern um das zweite &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehörte das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; dort hinzu.&lt;br /&gt;
&lt;br /&gt;
==switch-Anweisung==&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
&lt;br /&gt;
 switch ({{Ausdruck|}}) &lt;br /&gt;
 {&lt;br /&gt;
     case konstante1:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
    &lt;br /&gt;
     case konstante2:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 &lt;br /&gt;
     {{comment|weitere case-Marken}}&lt;br /&gt;
 &lt;br /&gt;
     default:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 } {{comment|Ende von switch}} &lt;br /&gt;
&lt;br /&gt;
Der Ausdruck muss ein skalarer Typ sein, er wird in die nächste ganze Zahl gewandelt und mit den Werten hinter den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Marken verglichen. Bei einer Übereinstimmung werden alle Befehle ab dem zutreffenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; ausgeführt. Stimmt der Ausdruck mit keinem der Werte überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt falls vorhanden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der nachfolgenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;- und des &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitts werden ausgeführt, wenn die Anweisungen des &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitts nicht mit dem Befehl &amp;lt;tt&amp;gt;break;&amp;lt;/tt&amp;gt; beendet werden!&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es dürfen beliebig viele &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitte angegeben werden, pro Vergleichswert jedoch nur einer.&lt;br /&gt;
Der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ist optional. Die Reihenfolge, in der &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt; angegeben werden, ist unerheblich.&lt;br /&gt;
&lt;br /&gt;
==Schleifen==&lt;br /&gt;
Um Anweisungen mehrmals hintereinander auszuführen, benötigt man Schleifen. Diese führen Anweisungen aus, bis oder solange Bedingungen erfüllt sind.&amp;lt;br&amp;gt; &lt;br /&gt;
Wichtig ist also, ob die Bedingung '''vor''' oder '''nach''' den Schleifen-Anweisungen geprüft wird. &lt;br /&gt;
&lt;br /&gt;
===while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 while ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Die while-Schleife wird solange durchlaufen, wie die Bedingung erfüllt ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Die Anweisung kann natürlich auch ein Block sein, der aus mehreren Deklarationen und Anweisungen besteht. &lt;br /&gt;
&lt;br /&gt;
 int zahl1 = 0;&lt;br /&gt;
 int zahl2 = 1;&lt;br /&gt;
 &lt;br /&gt;
 while (zahl1 &amp;lt; 3)&lt;br /&gt;
 {&lt;br /&gt;
    zahl1 = zahl1 + 1;&lt;br /&gt;
    zahl2 = zahl2 * 2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife drei mal durchlaufen. Zu Beginn des vierten Durchlaufs ist die Bedingung nicht mehr erfüllt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
&lt;br /&gt;
===do-while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
Die do-while-Schleife wird auf jeden Fall einmal durchlaufen und dann solange wiederholt, wie die Bedingung erfüllt ist.&lt;br /&gt;
 int i = 2;&lt;br /&gt;
 &lt;br /&gt;
 do &lt;br /&gt;
 {&lt;br /&gt;
     i = i*i;   {{comment|i quadrieren}}&lt;br /&gt;
     printf (&amp;quot;i = %d\n&amp;quot;, i);&lt;br /&gt;
 }&lt;br /&gt;
 while (i &amp;lt; 20);&lt;br /&gt;
&lt;br /&gt;
Die Schleife wird durchlaufen und wiederholt, solange &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; kleiner als 20 ist. Es werden also nacheinander die Werte 2, 4 und 16 ausgegeben. Nach der Schleife hat&amp;amp;nbsp;&amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; den Wert 256.&lt;br /&gt;
&lt;br /&gt;
===for-Schleife===&lt;br /&gt;
'''Syntax:''' &lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Bei den Ausdrücken wird es sich um einen Ausdrücke mit Nebeneffekt handeln wie etwa &amp;lt;tt&amp;gt;i=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;i=i+2&amp;lt;/tt&amp;gt;. Es werden folgende Aktionen ausgeführt:&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# falls die Bedingung wahr ist, dann führe &amp;lt;tt&amp;gt;Anweisung&amp;lt;/tt&amp;gt; aus.&lt;br /&gt;
# falls die Bedingung unwahr ist, dann sprinte zu 7 (Ende).&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# gehe zu 2&lt;br /&gt;
# nächste Anweisung nach der for-Schleife&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int lauf, summe;&lt;br /&gt;
 &lt;br /&gt;
 for (lauf=1, summe=0; lauf &amp;lt;= 10; lauf += 2) &lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel ist &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; ein [[#Komma-Operator|Komma-Ausdruck]], der zwei Anweisungen kombiniert und daher sogar zwei Nebeneffente hat: er setzt &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;1 und &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;0.&lt;br /&gt;
&lt;br /&gt;
Das Äquivalent als while-Schleife:&lt;br /&gt;
&lt;br /&gt;
 int lauf  = 1;                 {{comment|Anfangswerte}}&lt;br /&gt;
 int summe = 0;&lt;br /&gt;
 &lt;br /&gt;
 while (lauf &amp;lt;= 10)             {{comment|Bedingung}}&lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
    lauf  += 2;                 {{comment|Inkrement}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; in jedem Schleifendurchlauf um die Laufvariable &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; erhöht. Da &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nacheinander die ungeraden Werte von&amp;amp;nbsp;1 bis&amp;amp;nbsp;10 annimmt, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von&amp;amp;nbsp;1 bis kleinergleich 10 gespeichert, also der Wert&amp;amp;nbsp;25. &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; hat nach der Schleife den Wert&amp;amp;nbsp;11.&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf = 1&amp;lt;/tt&amp;gt; bedeutet, dass der Variablen &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; vor dem ersten Schleifendurchlauf der Wert&amp;amp;nbsp;1 zugewiesen wird. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf &amp;lt;= 10&amp;lt;/tt&amp;gt; ist die Schleifenbedingung; ist sie nicht erfüllt, wird die Schleife beendet. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf += 2&amp;lt;/tt&amp;gt; bedeutet, dass &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nach jedem Durchlauf um&amp;amp;nbsp;2 erhöht wird.&lt;br /&gt;
&lt;br /&gt;
===continue-Anweisung===&lt;br /&gt;
Innerhalb einer Schleife darf die &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die nachfolgenden Anweisungen übersprungen werden und mit dem nächsten Schleifendurchlauf fortgesetzt wird &amp;amp;ndash; vorausgesetzt die Schleifenbedingung ist noch erfüllt. Ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; etc. stehen, wenn dieses innerhalb einer Schleife steht.&lt;br /&gt;
&lt;br /&gt;
==break-Anweisung==&lt;br /&gt;
Innerhalb einer Schleife oder eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; darf die &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die Schleifen-/Switch-Anweisung sofort verlassen wird und das Programm dahinter weiter macht. Bei mehrfach geschachtelten Schleifen wird nur die innere verlassen. Ein &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; stehen, wenn dieses innerhalb einer Schleife/Switch-Anweisung steht.&lt;br /&gt;
&lt;br /&gt;
==goto-Anweisung==&lt;br /&gt;
&lt;br /&gt;
Innerhalb ein und derselben Funktion kann mit &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; an eine andere Stelle gesprungen werden. Dazu gibt man hinter dem &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einen Bezeichner an, der dadurch als Label fungiert:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 goto {{Bezeichner}};&lt;br /&gt;
Die Bezeichner selbst steht irgendwo in der Funktion und wird dadurch zur Sprungmarke (Label), daß er von einem Doppelpunkt (und mindestens einer C-Anweisung, die auch leer sein darf) gefolgt wird.&lt;br /&gt;
&lt;br /&gt;
Das Beispiel durchsucht das 2-dimensionale &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array &amp;lt;tt&amp;gt;feld&amp;lt;/tt&amp;gt; mit den &amp;lt;tt&amp;gt;SIZE_X &amp;amp;times; SIZE_Y&amp;lt;/tt&amp;gt; Werten nach dem Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;. Wird er gefunden, dann wird die 2-fach geschachtelte Suchschleife verlassen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int x, y;&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y; y++)&lt;br /&gt;
       if (feld[x][y] == 0)&lt;br /&gt;
          goto done;&lt;br /&gt;
 {{Label|done:}};&lt;br /&gt;
&lt;br /&gt;
Der folgende Code hat die gleiche Funktion, arbeitet jedoch ohne &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int x, y;&lt;br /&gt;
 int found = 0; {{comment|FALSE}}&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X &amp;amp;&amp;amp; !found; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y &amp;amp;&amp;amp; !found; y++)&lt;br /&gt;
       found = (0 == feld[x][y]);&lt;br /&gt;
Der Nachteil der &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-losen Variante ist, daß man eine Variable, die merkt, ob das Suchziel gefunden wurde, mitschleppen und in ''jedem'' Schleifendurchlauf abtesten muss. Dies bedeutet einen höheren Programmier- und Laufzeitaufwand und ist nicht so klar formuliert wie das &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-Beispiel.&lt;br /&gt;
&lt;br /&gt;
Gleichwohl sei angemerkt, daß die Verwendung von &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einem gewissen Dogmatismus unterliegt, der sich wie folgt subsummieren liesse:&lt;br /&gt;
:''goto ist böse und sollte keinesfalls verwendet werden! Wer es dennoch tut, offenbart dadurch seinen schlechten Geschmach sowie mangelhafte C-Kenntnis.'' &amp;lt;div align=&amp;quot;right&amp;quot;&amp;gt;http://www.roboternetz.de/phpBB2/images/smiles/icon_wink.gif&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Funktionen=&lt;br /&gt;
Stellen Dir vor, Du hast eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben &amp;amp;ndash; was Dich Zeit beim Erstellen des Programms und Speicherplatz im ausführbaren Programm kostet &amp;amp;ndash; kannst Du den Code-Abschnitt in eine Funktion schreiben und diese von jeder Stelle des Programms aus verwenden. Die Hauptgründe, um Funktionen zu verwenden, sind:&lt;br /&gt;
;Wiederverwendung von Code: Mehrfach verwendete Codestücke müssen nicht mehrfach implementiert werden. Oft unterscheiden sich die Codesequenzen nur in Kleinigkeiten, die man der Funktion über Parameter mitteilen kann.&lt;br /&gt;
;Übersichtlichkeit: Ein gut gegliedertes C-Programm implementiert klar umrissene Aufgaben in einer Funktion, auch wenn diese Funktion nur einmal im Code aufgerufen wird! Dadurch bleibt der Code um die Aufrufstelle besser verständlich, und man kann auf verschiedenen &amp;quot;Ebenen&amp;quot; denken. Eine Funktion wie &amp;quot;Datei öffnen&amp;quot; kann recht komplex sein. Auf höherer Ebene interessieren die Innereien nicht mehr, man möchte sich um andere Dinge kümmern und will den Code an der Stelle garnicht sehen...&lt;br /&gt;
;Rekursive Funktionen: Eine Funktion kann sich auch selbst aufrufen. In dem Falle nennt man die Funktion ''rekursiv''. Zwar lässt sich das, was eine rekursive Funktion tut, auch mit anderen Mitteln formulieren, die keine rekursiven Funktionen brauchen, aber oft ist der rekursive Weg knackiger und klarer formulierbar als eine nicht-rekursiven Ansatz, auch wenn es etwas mehr Resourcen verbraucht.&lt;br /&gt;
;Modulare Programmierung: Funktionen können anhand ihres Aufgabenbereichs auf verschiedene C-Quellen &amp;amp;ndash; sogenannte ''Module'' &amp;amp;ndash; verteilt werden. Funktionen, die etwas mit dem USB-Bus anstellen, werden in einem anderen Modul sein als mathematische Funktionen. Dies erhöht die Übersichtlichkeit und vereinfacht die Entwicklung im Team.&lt;br /&gt;
;Bibliotheken: Standard-Funktionen wie das hier oft auftauchende &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; sind in Bibliotheken gespeichert. Wenn das eigene Programm übersetzt wird, dann müssen nicht mehr alle Standard-Funktionen übersetzt werden, sondern werden nur noch aus der Bibliothek gelesen und ihr Code zum Programm dazugelinkt. Die Bibliotheks-Funktionen wurden schon zu einem früheren Zeitpunkt compiliert und liegen in dieser compilerten Form in der Bibliothek. Das spart mächtig Entwicklungszeit. Man kann auch selbst solche Bibliotheken erstellen und in diversen Projekten wiederverwenden.&lt;br /&gt;
;Generische Programmierung: In C ist es möglich, einer Funktion eine andere Funktion zu übergeben. (Damit ist nicht gemeint, ihr deren ''Rückgabewert'' zu übergeben (was auch ginge), sondern ''die Funktion selbst'' wird als Parameter übergeben und kann aufgerufen werden.) Ein typisches Beispiel dafür sind Sortieralgorithmen. Einem Sortieralgorithmus kann es egal sein, ''was'' er sortiert. Er muss lediglich wissen, ''wie'' er das Zeug zu sortieren hat: aufsteigend, absteigend, als Zahl, in lexikographischer Ordnung, nach der Quersumme, Körper nach Oberfläche, Durchmesser, Gewicht oder Volumen... Diese Vergleichsfunktion, die für zwei Objekte entscheidet, welches davon &amp;quot;kleiner&amp;quot; ist, kann man dem Sortierer übergeben. Will er zwei Werte vergleichen, dann muss er nur die Vergleichsfunktion aufrufen, ohne zu wissen, was diese tut. Damit kann der Sortieralgorithmus unanhängig von den Objekten gehalten werden, mit denen er hantieren soll.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Definition==&lt;br /&gt;
&lt;br /&gt;
In der ''Definition'' der Funktion wird gesagt, welche Werte sie liefern kann, wie sie heisst (Bezeichner) und wieviele und welche Parameter sie hat. Danach folgt ihre Implementierung:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}} ({{Parameterliste}})&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 &lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
Für Funktionen, die keinen Wert zurückliefern, gibt es den speziellen Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der besagt, daß die Funktion nichts zurückgibt. Die einfachste denkbare Funktion ist eine solch void-Funktion. Sie bekommt keine Parameter, gibt nicht zurück und ihr Body ist leer:&lt;br /&gt;
 void dummy()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==return-Anweisung==&lt;br /&gt;
An jeder Stelle des Programmflusses einer Funktion kann diese mit &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; beendet werden.&lt;br /&gt;
&lt;br /&gt;
'''bei void-Funktionen:'''&lt;br /&gt;
 return;&lt;br /&gt;
'''Funktionen mit Rückgabe-Wert:'''&lt;br /&gt;
 return {{Ausdruck|}};&lt;br /&gt;
Die zweite Variante gibt an, welcher Wert zurückgegeben wird.&lt;br /&gt;
 int main (int argc, char * argv[])&lt;br /&gt;
 {&lt;br /&gt;
    if (argc &amp;lt; 2)&lt;br /&gt;
       return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
Falls die letzte Anweisung einer void-Funktion ein &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; ist, kann es auch weggelassen werden wie oben bei der Funktion &amp;lt;tt&amp;gt;dummy&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Aufruf==&lt;br /&gt;
Um die Funktion aufzurufen gibt man ihren Namen an, gefolgt von den durch Komma getrennten Argumenten in runden Klammern wie im Beispiel unten das&lt;br /&gt;
 quadrat (5) &lt;br /&gt;
Da &amp;lt;tt&amp;gt;quadrat&amp;lt;/tt&amp;gt; einen Wert liefert, kann man damit weiter rechnen wie mit einem normalen Ausdruck:&lt;br /&gt;
 if (quadrat (a) + quadrat (b) == quadrat (c))&lt;br /&gt;
    c = quadrat (quadrat (a)); {{comment|c &amp;amp;#61; a hoch 4}}&lt;br /&gt;
&lt;br /&gt;
;Ein Hinweis am Rande: &lt;br /&gt;
Der Name einer Funktion ohne die beiden runden Klammern ist der Pointer/Zeiger auf ihren Anfang.&lt;br /&gt;
Damit kann ein Funktionsname überall dort verwendet werden, wo Pointer/Zeiger &lt;br /&gt;
zulässig sind. Insbesondere kann er als Argument einer weiteren Funktion dienen. &lt;br /&gt;
&lt;br /&gt;
'''Quelle:'''&lt;br /&gt;
W. Alex, Einführung in C/C++&lt;br /&gt;
&lt;br /&gt;
==Rekursive Funktionen==&lt;br /&gt;
Eine Funktion die sich selbst &amp;amp;ndash; möglicheweise auch über andere Zwischenfunktionen &amp;amp;ndash; wieder selbst aufruft, wird als ''rekursive Funktion'' bezeichnet. In der Definition ist nichts besonderes zu beachten. Ist die Verschachtelungstiefe im laufenden Programm zu tief, dann gibt das natürlich Probleme, aber das gilt bei tief verschachtelten 'normalen' Funktionen abenso...&lt;br /&gt;
&lt;br /&gt;
Das Beispiel berechnet den Größten Gemeinsamen Teiler zweier Zahlen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int ggT (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
     if (0 == a)&lt;br /&gt;
        return b;&lt;br /&gt;
 &lt;br /&gt;
    return ggT (b % a, a);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Ein komplettes kleines Programm:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int quadrat (int param1)&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  zahl = param1 * param1;&lt;br /&gt;
  return zahl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl, ergebnis;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Bitte Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = quadrat (zahl);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, zahl, ergebnis);&lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, 5, quadrat (5));&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur ausserhalb von Blöcken. Geschachtelte Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen beim Aufruf die Klammern angeben werden:&lt;br /&gt;
 dummy();&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Prototypen==&lt;br /&gt;
Wie oben erwähnt, kann ein Unterprogramm an jeder beliebigen Stelle im Programm stehen. Damit ist jedoch eine Bedingung verknüpft: Das Unterprogramm muß in der Datei oberhalb des ersten Aufrufes definiert worden sein. Wenn Sie ein Unterprogramm in Zeile 10 zum ersten mal aufrufen, müssen Sie die Deklaration davor erledigt haben. Verstanden?&lt;br /&gt;
Um dies zu erreichen, gibt es zwei Möglichkeiten: &lt;br /&gt;
&lt;br /&gt;
Entweder Sie schreiben alle Unterprogramme vor &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; in die Datei. Dies muß jedoch wiederum so geschehen, dass Funktionen zum Zeitpunkt ihres Aufrufes bereits bekannt sind! &lt;br /&gt;
Wo dies nicht möglich ist (z.B. sich gegenseitig aufrufende Unterprogramme), oder wenn Sie das stört, müssen Sie Prototypen verwenden. &lt;br /&gt;
Wie definiert man nun Prototypen? Sie kopieren einfach die erste Zeile des Unterprogrammes (z.B. &amp;quot;&amp;lt;tt&amp;gt;void ausgeben (int zahl)&amp;lt;/tt&amp;gt;&amp;quot;), fügen einen Strichpunkt&amp;amp;nbsp;&amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;an und fügen es an einer geeigneten Stelle ein (so, dass alle Aufrufe später in der Datei kommen). &lt;br /&gt;
Solche Definitionen stehen gewöhnlich am Anfang der Quelldatei oder in einer Header-Datei, die eingebunden wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl);  /* Der Prototyp */&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
   ausgeben (12);&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl)   /* Die eigentliche Prozedur */&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Ausgabe: %d\n&amp;quot;, zahl);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Parameterübergabe==&lt;br /&gt;
&lt;br /&gt;
Alle Werte, die an Prozeduren und Funktionen übergeben werden, werden grundsätzlich '''kopiert'''.&lt;br /&gt;
Das hat folgende Auswirkungen:&lt;br /&gt;
&lt;br /&gt;
# Änderungen an einem Parameter in einer Funktion erscheinen ''nicht'' beim Aufrufer!&lt;br /&gt;
# Möchte man, dass eine Funktion einen Wert trotzdem dauerhaft ändern soll, so muss die Adresse des Wertes via [[#Zeiger|Zeiger]] übergeben werden.&lt;br /&gt;
# Werden [[#Strukturen|Strukturen]] übergeben, so wird von ihnen eine Kopie erstellt, was bei großen Strukturen viel Zeit und Arbeitsspeicher kostet. Deshalb wird häufig nur die Adresse von Strukturen übergeben, da die Adresse viel schneller und platzsparender als die Struktur selbst kopiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele:'''&lt;br /&gt;
 void erhoehe (int x)&lt;br /&gt;
 {&lt;br /&gt;
    x = x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe(a);&lt;br /&gt;
    {{comment|a ist immer noch 0}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Beim Aufruf von &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; wird eine Kopie des Wertes von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; (im Beispiel also 0) erstellt und der Prozedur als Parameter &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; übergeben. Weil dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat dies keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|erhoehe den Wert an der Adresse x um eins}}&lt;br /&gt;
    *x = *x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe (&amp;amp;a);&lt;br /&gt;
    {{comment|a ist jetzt 1}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Jetzt wird im Hauptprogramm mittels [[#Adress-Operator und Dereferenzierung|Adress-Operator]] &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; die Speicheradresse von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; bestimmt. Dann wird eine ''Kopie der Adresse'' an das Unterprogramm &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; übergeben. Jetzt kennt das Unterprogramm die&lt;br /&gt;
Adresse des Originals &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und kann direkt mit dem Inhalts-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&lt;br /&gt;
'''Besonderheit bei Feldern'''&lt;br /&gt;
&lt;br /&gt;
Bei der Übergabe von [[#Felder|Feldern]] gibt es eine Besonderheit. Schreibt man nämlich den Namen eines Feldes, so ist das nichts anderes als die '''Speicheradresse des ersten Elements'''.&lt;br /&gt;
Bei der Übergabe eines Feldes wird also eine Kopie der Startadresse übergeben. Somit kann das Unterprogramm auf den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 void erhoehe (int x[])&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
   int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
   erhoehe (a);&lt;br /&gt;
   {{comment|a hat jetzt folgenden Inhalte: 11, 23, 35}}&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Dass die Übergabe einer Adresse erfolgt, sieht man an folgendem Beispiel, das von der Funktionsweise '''absolut identisch''' mit dem vorhergehenden ist:&lt;br /&gt;
&lt;br /&gt;
 {{comment|Bei Parametern gibt es keinen Unterschied zwischen Zeiger und Feld}}&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
    int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
    erhoehe (a);&lt;br /&gt;
 &lt;br /&gt;
    {{comment|a hat jetzt folgenden Inhalt: 11, 23, 35}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
Die Länge des Feldes wird nicht automatisch übergeben. Dafür ist ggf. ein zusätzlicher Parameter notwendig.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Variable Argumentanzahl==&lt;br /&gt;
== Funktionen indirekt aufrufen ==&lt;br /&gt;
Siehe [[#Zeiger auf Funktionen|Zeiger auf Funktionen]]&lt;br /&gt;
&lt;br /&gt;
=Zeiger II=&lt;br /&gt;
&lt;br /&gt;
Zeiger haben wir bereits weiter oben kennen gelernt. Zeiger sind ein zentrales Konzept in C und sollen hier etwas eingehender behandelt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger-Arithmetik==&lt;br /&gt;
In C kann man den Wert eines Zeigers verändern. Betrachten wir dazu die Funktion &amp;lt;tt&amp;gt;suche_0&amp;lt;/tt&amp;gt;, die einen Zeiger auf einen &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; erhält. Die Funktion soll ab der gegebenen Adresse nach dem ersten long-Wert suchen, der 0 ist, und dessen Adresse zurückgeben:&lt;br /&gt;
 long * suche_0 (long * addr)&lt;br /&gt;
 {&lt;br /&gt;
    while (*addr != 0)&lt;br /&gt;
       addr = addr + 1;&lt;br /&gt;
 &lt;br /&gt;
    return addr;&lt;br /&gt;
 }&lt;br /&gt;
In der Bedingung der while-Schleife wird der Inhalt an der Speicherstelle &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf 0 getestet. Ist der Wert 0, dann wird die Schleife beendet und die Adresse zurückgeliefert. Ist der Wert ungleich 0, dann wird &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf den nächste long gesetzt, &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; also um 4 Bytes weitergezählt. &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ist ja ein Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, und ein &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; ist 4 Bytes lang.&lt;br /&gt;
&lt;br /&gt;
Die Bedeutung von&lt;br /&gt;
 address + n&lt;br /&gt;
ist also, die Adresse um das &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;-fache der Größe des Typs, auf den &amp;lt;tt&amp;gt;address&amp;lt;/tt&amp;gt; zeigt, zu erhöhen. Dabei ist &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; eine ganze Zahl und darf auch negativ sein.&lt;br /&gt;
&lt;br /&gt;
Hier noch ein Beispiel einer Funktion, die nach einer Person mit einer bestimmten ID sucht (für die Definition von &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; siehe [[#Strukturen|Strukturen]]). Der Parameter &amp;lt;tt&amp;gt;person&amp;lt;/tt&amp;gt; ist dabei ein Array von Strukturen. Eine Person mit der gesuchten ID muss existieren, ansonsten hat die Suchfunktion kein definiertes Verhalten.&lt;br /&gt;
 {{comment|Sucht nach einer Person mit der ID person_id}}&lt;br /&gt;
 struct Person * &lt;br /&gt;
 suche_person_id (struct Person * person, int person_id)&lt;br /&gt;
 {&lt;br /&gt;
    while (person-&amp;gt;id != person_id)&lt;br /&gt;
       person++;&lt;br /&gt;
 &lt;br /&gt;
    return person;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:1em; padding:1em; border:solid 2px #FF0040;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- Vorlage:FarbigerRahmen funzt hier net --&amp;gt;&lt;br /&gt;
Beachte, daß es nicht sinnvoll ist, zwei Zeiger zu addieren oder zu multiplizieren. Ausserdem ist das &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt; der Zeiger-Arithmetik nicht kommutativ. Eine Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, der an Adresse 1 im Speicher zeigt, wird man schreiben als&lt;br /&gt;
 (long *) 1&lt;br /&gt;
Addiert man darauf eine ganze Zahl, dann haben die entstehenden Ausdrücke unterschiedliche Werte:&lt;br /&gt;
 (long *) 1 + 2    {{comment|zeigt zu Adresse 9}}&lt;br /&gt;
 (long *) 2 + 1    {{comment|zeigt zu Adresse 6}}&lt;br /&gt;
 (long *) (1 + 2)  {{comment|zeigt zu Adresse 3}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==void-Pointer==&lt;br /&gt;
Eine besondere Art von Zeiger ist der void-Pointer&lt;br /&gt;
 void * addr;&lt;br /&gt;
Ein void-Pointer ist ein &amp;quot;Zeiger auf irgendwas&amp;quot;, dementsprechend kann er nicht dereferenziert werden, Anwenden von &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf einen solchen Zeiger gibt also einen Fehler. Ausserdem ist es nicht möglich, mit einem void-Pointer Zeigerarithmetik zu machen, weil er nicht auf eine definierte Art von Objekt zeigt. Der Vorteil eines void-Pointers ist, daß er jede Art von Zeiger aufnehmen kann.&lt;br /&gt;
&lt;br /&gt;
Dazu betrachten wir die Funktion &amp;lt;tt&amp;gt;send_buf&amp;lt;/tt&amp;gt;, die eine Adresse erhält und ab dieser Adresse &amp;lt;tt&amp;gt;num&amp;lt;/tt&amp;gt; Bytes versenden soll. Wir könnten die Funktion so schreiben:&lt;br /&gt;
 void send_buf (unsigned char * buf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   ...&lt;br /&gt;
Das ist jedoch hässlich, wenn wir damit etwas anderes verschicken wollen als &amp;lt;tt&amp;gt; unsigned char&amp;lt;/tt&amp;gt;, etwa eine Struktur wie &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; (vom Typ &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;):&lt;br /&gt;
 send_buf ((unsigned char*) &amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
Ohne den Cast der Adresse von &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; zu einem Zeiger auf &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt; bekommt man eine Warnung oder gar einen Compilerfehler.&lt;br /&gt;
Dieses Zeiger gecaste ist mühsam und hässlich, es muss bei jedem Aufruf der Funktion explizit hingeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Besser ist es, den ersten Parameter der Funktion als void-Pointer zu definieren und den Cast in der Funktion zu machen:&lt;br /&gt;
 void send_buf (void * vbuf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   unsigned char *buf = (unsigned char*) vbuf;&lt;br /&gt;
   ...&lt;br /&gt;
Durch den Cast in der Funktion kann auf den Inhalt des Zeigers zugegriffen werden. Man muss nur festlegen, ''wie'' man zugreifen will, nämlich als &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Der Aufruf kann jetzt ohne Pointer-Cast erfolgen: &lt;br /&gt;
 send_buf (&amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
&lt;br /&gt;
==Null-Pointer==&lt;br /&gt;
==Zeiger als Parameter==&lt;br /&gt;
Wenn Sie ein Unterprogramm aufrufen, können Sie diesem Parameter übergeben, aber keine Werte zurückgekommen (außer den Funktionswert bei Funktionen). Dies hat einen guten Grund: beim Aufruf werden nicht die aufgerufenen Parameter benutzt, sondern es werden deren Werte in neue Variablen kopiert. Diese Variablen werden am Ende des Unterprogrammes &amp;quot;zerstört&amp;quot;, ohne ihre Werte an die aufrufenden Parameter zu übergeben. Jede Veränderung eines Parameters hat daher keine Auswirkung auf den Parameter.&lt;br /&gt;
&lt;br /&gt;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der C-Compiler legt dann immer noch Kopien an. In dieser Kopie steht aber kein Wert, sondern die Adresse einer Varaiblen. Und auf diese können Sie dann zugreifen. Denken Sie nur an &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; &amp;amp;ndash; da übergeben Sie ja auch die Adresse einer Variablen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void erhoehe (int *zeiger)&lt;br /&gt;
{&lt;br /&gt;
  *zeiger = 1 + *zeiger;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  erhoehe (&amp;amp;zahl);&lt;br /&gt;
  printf (&amp;quot;\nDie erhoehte Zahl lautet: %d\n&amp;quot;, zahl);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Zeiger auf Funktionen==&lt;br /&gt;
&lt;br /&gt;
Stell dir vor, du willst einen Sortieralgorithmus wie Bubble-Sort oder Quick-Sort oder wie sie alle heissen implementieren. Für den Sortieralgorithmus ist eigentlich egal, ''was'' er zu sortieren hat. Ihm ist es egal, ob er Zahlen aufwärts sortieren soll oder Strings in lexikographischer Reihenfolge, ob Objekte nach Größe oder Gewicht, Personen nach Alter oder Adressen nach Postleitzahl. Das einzige, was der Algorithmus wissen muss, ist ''wie'' er zwei Objekte zu vergleichen hat und wann eines davon &amp;quot;kleiner&amp;quot; (im Sinne der Ordnung, nach der sortiert werden soll) ist. &lt;br /&gt;
&lt;br /&gt;
Eine einfache Sortierfunktion, die nur zwei Zahlen sortiert, könnte man also so schreiben: &lt;br /&gt;
 {{comment|Sortiert ein Array von 2 int-Zeigern nach den Inhalten &lt;br /&gt;
  * an den Zeiger-Adressen}}&lt;br /&gt;
 void sort2_a (int * p[])&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Inhalte vergleichen...}}&lt;br /&gt;
    if (*p[0] &amp;gt; *p[1])&lt;br /&gt;
    {&lt;br /&gt;
       {{comment|... und ggf. Dreieckstausch der 2 Zeiger}}&lt;br /&gt;
       int * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Die Funktion bekommt ein Array der Länge&amp;amp;nbsp;2. In diesem Array stehen Zeiger auf die zu sortierenden Zahlen. Ein Array mit Zeigern zu verwenden und nicht ein Array von &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; scheint recht umständlich, und das ist es hier auch. Aber stell dir vor, du willst Strukturen wie &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; sortieren. Das Tauschen zweier Strukturen würde bedeuten, ihre kompletten Inhalte umzukopieren! Das wäre sehr aufwändig. Viel einfacher ist das Kopieren, wenn nur die Adressen zu kopieren sind.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; könnte dann so aussehen:&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void sortiere (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|p[] enthält 2 int-Zeiger: die Adressen von a und b}}&lt;br /&gt;
    int * p[2];&lt;br /&gt;
    p[0] = &amp;amp;a; &lt;br /&gt;
    p[1] = &amp;amp;b; &lt;br /&gt;
 &lt;br /&gt;
    {{comment|Sortiere die Zeiger}} &lt;br /&gt;
    sort2_a (p);&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Sortiert: %d, %d\n&amp;quot;, *p[0], *p[1]);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Für den nächsten Schritt überlegen wir uns, daß das Array in &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; ebensogut void-Pointer enthalten kann. Die einzige Stelle, an der wir auf die endgültigen int-Objekte zugreifen, ist der Vergleich. Diesen Vergleich lagern wir in die Funktion &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; aus:&lt;br /&gt;
 {{comment|Bekommt zwei void-Pointer und vergleicht die Inhalte.&lt;br /&gt;
  * Liefert 0 bei Gleichheit,&lt;br /&gt;
  * -1 wenn der erste Wert kleiner ist als der zweite und&lt;br /&gt;
  * 1  wenn der erste Wert größer ist als der zweite}}&lt;br /&gt;
 int compare_int (void * p0, void * p1)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Um über die Zeiger zugreifen zu können müssen wir diese&lt;br /&gt;
     * erst zu int-Zeigern casten}}&lt;br /&gt;
    int a0 = * (int*) p0;&lt;br /&gt;
    int a1 = * (int*) p1;&lt;br /&gt;
 &lt;br /&gt;
    if (a0 &amp;gt; a1)  return  1;&lt;br /&gt;
    if (a0 &amp;lt; a1)  return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void sort2_b (void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare_int (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Ein Aufruf von &amp;lt;tt&amp;gt;sort2_b&amp;lt;/tt&amp;gt; sieht dann genauso aus wie ein Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt definieren wir uns den neuen Datentyp &amp;lt;tt&amp;gt;comparator_t&amp;lt;/tt&amp;gt;. Dieser ist ein Zeiger auf eine Funktion, die zwei void-Pointer erhält und einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; zurückliefert, also analog arbeitet zu &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; von oben. &lt;br /&gt;
&lt;br /&gt;
Unsere Sortierfunktion bekommt nun neben dem zu sortierenden Zeiger-Array auch eine Vergleichsfunktion &amp;lt;tt&amp;gt;compare&amp;lt;/tt&amp;gt; mitgeliefert, die sie aufruft, wenn sie zwei Objekte vergleichen will&lt;br /&gt;
 {{comment|comparator_t sind Zeiger auf Funktionen, die 2 void-Pointer&lt;br /&gt;
  * erhalten und einen int zurückliefern}}&lt;br /&gt;
 typedef int (*comparator_t) (void*, void*);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Der Sortierer bekommt einen Funktionszeiger auf den Vergleicher.&lt;br /&gt;
  * Der Aufruf vom compare geht so als wäre es eine &amp;quot;normale&amp;quot; Funktion&lt;br /&gt;
  * (ist es im Endeffekt ja auch)}}&lt;br /&gt;
 void sort2_c (comparator_t compare, void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Bei einem Aufruf von &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; muss man dann einen Komparator mit angeben. In einem Beispiel analog zu &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; von oben ist das:&lt;br /&gt;
 sort2_c (compare_int, p);&lt;br /&gt;
Um zwei Strings lexikographisch zu sortieren nehmen wie die Standard-Funktion &amp;lt;tt&amp;gt;strcmp&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void foo()&lt;br /&gt;
 {&lt;br /&gt;
    char * worte[] = { &amp;quot;Wort1&amp;quot;, &amp;quot;Wort2&amp;quot; };&lt;br /&gt;
 &lt;br /&gt;
    sort2_c ((comparator_t) strcmp, (void**) worte);&lt;br /&gt;
 }&lt;br /&gt;
Die Casts sind hier erforderlich. Alternativ könnte man &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; mit reinen void-Pointern versorgen und diese dann dort umcasten.&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
&lt;br /&gt;
Die Syntax zur Definition/Deklaration von Funktionszeigern ist etwas verzwackt. Zur Verdeutlichung ein paar Beispiele. Dabei legt das linke &amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt; jeweils den Return-Typ fest.&lt;br /&gt;
 {{comment|definiert einen neuen Funktionszeiger-Typ}}&lt;br /&gt;
 typedef {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert einen Funktionszeiger}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert ein Array von Funktionszeigern (mit Initializer)}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}[]) ({{type}}, {{type}}, ...) = { wert1, wert2, ... };&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer}}&lt;br /&gt;
 ({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer und ruft die Funktion auf}}&lt;br /&gt;
 (({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}) (arg1, arg2, ...);&lt;br /&gt;
&lt;br /&gt;
=Standard-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==String-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===strcpy===&lt;br /&gt;
Bei vielen Compilern können sie einem String nicht direkt einen Wert (Text) zuweisen. Dazu müssen Sie dann die Prozedur strcpy() benutzen. Diese erwartet als ersten Parameter den Namen einer String-Variablen (ohne eckige Klammern) und als zweiten Parameter den eines (anderen) Strings. Letzterer kann auch ein in doppelten Hochkommas (&amp;quot;) eingeschlossener Text sein. Die Funktion fügt am Ende automatisch ein 0-Zeichen ein. Um diese Funktion nutzen zu können, müssen Sie die Datei string.h includieren! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri1[21], eingabe[21];&lt;br /&gt;
&lt;br /&gt;
  strcpy (stri1, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Der 1. String: %s\n&amp;quot;, stri1);&lt;br /&gt;
  printf (&amp;quot;Bitte geben Sie maximal 20 Zeichen ein: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%s&amp;quot;, eingabe);&lt;br /&gt;
  strcpy (stri1, eingabe);&lt;br /&gt;
  printf (&amp;quot;\n%s = %s&amp;quot;, stri1, eingabe);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis:''' &lt;br /&gt;
Da ein String, wie jedes Feld, eigentlich ein Zeiger ist, dürfen Sie kein &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; bei &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; angeben!&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
Es werden zwei gleich große Strings definiert: &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;eingabe&amp;lt;/tt&amp;gt;, mit je 20 &amp;quot;nutzbaren&amp;quot; Zeichen. &lt;br /&gt;
In &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; wird die Zeichenkette &amp;lt;tt&amp;gt;&amp;quot;hallo&amp;quot;&amp;lt;/tt&amp;gt; hineinkopiert. Das 0-Zeichen am Ende wird automatisch angefügt. &lt;br /&gt;
Der String wird ausgegeben. Als neues &amp;quot;Sonderzeichen&amp;quot; kommt &amp;lt;tt&amp;gt;%s&amp;lt;/tt&amp;gt; ins Spiel. Es hat die gleiche Aufgabe wie &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt;, nur für Strings. &lt;br /&gt;
Sie werden gebeten, eine String einzugeben. &lt;br /&gt;
Dieser String wird danach in die Variable &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; kopiert. &lt;br /&gt;
Beide Strings, die ja nun die gleiche Zeichenkette enthalten, werden ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===strlen===&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;strlen&amp;lt;/tt&amp;gt;, die als Parameter eine String-Variable erwartet, liefert die Länge diese Strings zurück. Sie werden jetzt vermutlich sagen: &amp;quot;Das ist doch klar, wie lang der String ist. Ich habe es ja bei der Deklaratin angegeben&amp;quot;. Das stimmt schon, aber denken Sie noch einmal an die null-terminierten Strings. Das 0-Zeichen steht am Ende des Strings (am Ende der gültigen Zeichenfolge), aber nicht unbedingt am Ende des reservierten Speicherplatzes. Haben Sie eine Variable &amp;quot;char Variable[21];&amp;quot;, und ihr den Wert &amp;quot;hallo&amp;quot; zugewiesen, dann steht das null-Zeichen in Variable[5]. Der &amp;quot;gültige&amp;quot; String ist also 5 Zeichen (0-4) lang. Und genau das (5) würde strlen zurück liefern. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri[21];&lt;br /&gt;
  &lt;br /&gt;
  strcpy (stri, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
  printf (&amp;quot;Der String ist %d Zeichen lang&amp;quot;, strlen (stri));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird vor allem gebraucht, wenn Sie direkt auf den String zugreifen, mittels &amp;lt;tt&amp;gt;stri[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;stri[1]&amp;lt;/tt&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
==Ein- und Ausgabe-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===Bildschirm-Ausgabe===&lt;br /&gt;
Bisher war das Tutorial trotz aller Beispiele reine Theorie. Sie konnten zwar Programme schreiben, aber die Funktion nicht testen. Hier lernen Sie nun, wie Sie etwas am Bildschirm ausgeben.&lt;br /&gt;
&lt;br /&gt;
Die dazu notwendige Funktione heisst &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (das '&amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt;' ist kein Fehler!). Diese Anweisung gibt die ihr übergebenen Parameter auf das Standard-Ausgabegerät aus, in der Regel also auf den Bildschirm. Sie kann beliebig viele Parameter übernehmen. Es müssen jedoch Standard-Datentypen (z.B. &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;...) sein! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
    int zahl1 = 12;&lt;br /&gt;
    char zeichen1 = 'A';&lt;br /&gt;
    &lt;br /&gt;
    printf (&amp;quot;Das ist Text, und er wird als solcher ausgegeben. \n&amp;quot;);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zahl1' ist: %d \n&amp;quot;, zahl1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %c \n&amp;quot;, zeichen1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %d \n&amp;quot;, zeichen1);&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt Text aus. Das Zeichen am Ende (&amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;) bedeutet &amp;quot;New Line&amp;quot;, es bewegt den Cursor an den Anfang der nächsten Zeile. &lt;br /&gt;
&lt;br /&gt;
Der zweite &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt auch Text aus, am Ende befindet sich wieder das &amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;, um einen Zeilenvorschub zu erreichen. Das &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; wird vom Compiler durch den ersten Parameter ersetzt, der nach dem Text angegeben wird. In diesem Fall wird &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; also durch den Wert der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ersetzt. Das &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; im &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; bedeutet &amp;quot;Dezimalzahl&amp;quot;, der Computer gibt also eine ganze Zahl aus. &lt;br /&gt;
&lt;br /&gt;
In der dritten Ausgabe wird ein Zeichen ausgegeben. Diesmal bedeutet &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; &amp;quot;char&amp;quot; (Zeichen). Es wird also &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; durch ein &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt; ersetzt, denn die Variable &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; wird als Character interpretiert. &lt;br /&gt;
&lt;br /&gt;
Die letzte Ausgabe interpretiert den Inhalt von &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; als Zahl, und gibt dager den ASCII-Wert von &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, also 65 aus. Das ist ein typisches Beispiel für das mögliche unterschiedliche Interpretieren einer  Variablen!&lt;br /&gt;
&lt;br /&gt;
===Tastatur-Eingabe===&lt;br /&gt;
&lt;br /&gt;
Um ein &amp;quot;gscheites&amp;quot; Programm schreiben zu können, muß man wissen, wie der Benutzer über die Tastatur Befehle eingeben kann. Die dafür notwendigen Funktionen stelle ich in diesem Kapitel vor.&lt;br /&gt;
Die wichtigste Funktion ist &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt;. Er liest Daten von der Tastatur. Die Syntax entspricht derer von &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int  zahl1;&lt;br /&gt;
char zeichen1;&lt;br /&gt;
&lt;br /&gt;
printf (&amp;quot;Bitte geben Sie eine Zahl ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl1);&lt;br /&gt;
printf (&amp;quot;Geben Sie einen Zeichen ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%c&amp;quot;, &amp;amp;zeichen1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Programm gibt eine Eingabeaufforderung aus. Dann erwartet es vom Benutzer, daß er eine Zahl eingibt, die mit [ENTER] bestätigt wird. Dieser Wert wird in &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; abgespeichert. Danach erfolgt wiederum eine Aufforderung zur Eingabe, diesmal eines einzelnen Zeichens. Dieses kann man nun eingeben und ebenfalls mit [ENTER] bestätigen.&lt;br /&gt;
&lt;br /&gt;
Macht man keine dem Datentyp der erwarteten Variable entsprechende Eingabe, dann bricht das Programm mit einer Fehlermeldung ab (wenn man z.B. &amp;quot;1_T2&amp;quot; eingibt, wenn eine Zahl erwartet wird)!&lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; vor den Parametern ist notwendig. Warum, das erfahren Sie im Kapitel &amp;quot;Unterprogramme&amp;quot;. Für die Profis eine Kurz-Erklärung: Das Unterprogramm &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; bekommt zwar einen Wert übergeben, kann aber keinen zurückliefern (&amp;quot;call by value&amp;quot;). Daher wird kein Wert, sondern ein Zeiger auf eine Variable übergeben. Mit dem &amp;amp; Zeichen bekommen Sie die Adresse einer Variablen (&amp;quot;call by reference&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=Parameter von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;=&lt;br /&gt;
Das Unterprogramm &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; kann, wie jede andere Funktion, Parameter besitzen. Doch keine selbst gewählten, sondern nur bestimmte. Doch warum braucht main Parameter? Denken Sie einmal an alle Betriebssystembefehle:&lt;br /&gt;
&amp;lt;tt&amp;gt;dir *.exe &amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;copy *.* a:&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;ls -la &amp;lt;/tt&amp;gt;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;&amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen!&lt;br /&gt;
&lt;br /&gt;
=Kurzreferenz=&lt;br /&gt;
==Syntax-Bausteine==&lt;br /&gt;
&lt;br /&gt;
Die Erklärung des Aufbaus von C-Befehlen erfolgt neben einfachen Beispielen auch durch ihren prinzipellen Aufbau. In diesen Syntax-Beschreibungen finden sich immer wieder die gleichen Bausteine, die hier näher erklärt werden sollen. Falls die solch ein Syntax-Baustein begegnet, kannst Du ihn anclicken und kommst dann zu seiner Erläuterung. &lt;br /&gt;
&lt;br /&gt;
In den Beispielen selbst gehören auch die spitzen Klammern zu dem Baustein (was daran zu erkennen ist, daß auch die Klammern eingefärbt sind). Die Klammern dürfen in einem konkreten C-Programm daher nicht eingetippt werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bezeichner&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Bezeichner in C dienen dazu, Variablen zu identifizieren und ihnen sprechende Namen zu geben, um die Quelle lesbarer zu machen. Man braucht Bezeichner auch, um selbstdefinierte Datentypen zu benennen und zum Benennen von Struct- und Union-Komponenten sowie als Namen für Funktionen und Sprungmarken (Labels).&lt;br /&gt;
&lt;br /&gt;
Bezeichner dürfen aus den Kleinbuchstaben &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;z&amp;lt;/tt&amp;gt;, den Großbuchstaben &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;Z&amp;lt;/tt&amp;gt;, dem Unterstrich&amp;amp;nbsp;&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt; und den Ziffern &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;9&amp;lt;/tt&amp;gt; aufgebaut werden, wobei an erster Stelle jedoch keine Ziffer stehen darf.&lt;br /&gt;
&lt;br /&gt;
Es wird zwischen Groß- und Kleinschreibung unterschieden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Ausdruck in C ist ein Konstrukt, das einen Wert hat. Ob dieser Wert eine ganze Zahl ist, eine Kommazahl oder ein Zeiger, etc. ist dabei egal. Die einfachsten Ausdrücke sind Konstanten wie&lt;br /&gt;
 2&lt;br /&gt;
oder Variablen wie&lt;br /&gt;
 ein_zahl&lt;br /&gt;
Mehrere Ausdrücke können durch [[#Liste der Operatoren|Operatoren]] zu komplexeren Ausdrücken kombiniert werden, etwa&lt;br /&gt;
 eine_zahl + andere_zahl == 2&lt;br /&gt;
oder &lt;br /&gt;
 eine_zahl = 2&lt;br /&gt;
Letzterer hat den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; und den Nebeneffekt, daß er diesen Wert an &amp;lt;tt&amp;gt;eine_zahl&amp;lt;/tt&amp;gt; zuweist.&lt;br /&gt;
&lt;br /&gt;
Auch der Aufruf einer Funktion, die einen Rückgabewert liefert, ist ein Ausdruck:&lt;br /&gt;
 sin (1.2)&lt;br /&gt;
und kann zum Aufbau komplexerer Ausdrüche verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bedingung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Bedingung ist ein Ausdruck, bei der nur interessiert, ob dieser zu&amp;amp;nbsp;0 (unwahr) auswertet oder zu ungleich&amp;amp;nbsp;0 (wahr). Solche Ausdrücke findet man in if-Anweisungen, in Schleifenbedingungen und bedingten Zuweisungen&lt;br /&gt;
 (ein_wert &amp;lt; 2) || (ein_wert &amp;gt; 40)&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Lvalue ist ein Ausdruck, dem etwas zugewiesen werden kann. Der Name ''Lvalue'' kommt aus dem Englischen. Das ''L'' steht abkürzend für left. Ein Lvalue ist damit ein Ausdruck, der auf der linken Seite eine Zuweisung in C stehen darf. Das &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; in den folgenden Beispiel-Ausdrücken muss ein Lvalue sein:&lt;br /&gt;
 x = y-1&lt;br /&gt;
&lt;br /&gt;
 x++&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Konstante&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Konstante ist ein Ausdruck, dessen Wert dem Compiler bekannt ist. Beispiele für Konstanten sind etwa&lt;br /&gt;
 7&lt;br /&gt;
 'B'&lt;br /&gt;
 -13.98e12&lt;br /&gt;
 1+(2*3)&lt;br /&gt;
und die Werte von [[#Enum|Enum]]s. &lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; aus dem folgenden Codestück definiert jedoch keine Konstante in diesem Sinne&lt;br /&gt;
 const double Pi = 3.14159256;&lt;br /&gt;
denn in einem anderen Quellmodul könnte durch die Deklaration&lt;br /&gt;
 extern const double Pi;&lt;br /&gt;
das Symbol &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; bekannt sein, ohne daß sein Wert bekannt ist!&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Adresse&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Adresse ist ein Ausdruck, der einen Speicherort (physikalisch oder virtuell) halten kann. Adressen erhält man dadurch, daß man einem Bezeichner den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt;voranstellt, Adressen durch Arithmetik berechnet oder Zahlen zu Adressen castet. Folgende Ausdrücke sind Adressen (eine sinnvolle Deklaration der auftretenden Variablen vorausgesetzt)&lt;br /&gt;
 &amp;amp; eine_zahl&lt;br /&gt;
 &amp;amp; ein_array[10]&lt;br /&gt;
 &amp;amp; ein_struct&lt;br /&gt;
 &amp;amp; ein_struct.komponente&lt;br /&gt;
 (int *) 0x1234&lt;br /&gt;
 (int *) eine_zahl&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Deklaration&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Anweisungen sind gewissermassen die Atome (oder Moleküle?), aus denen ein C-Programm besteht. Jedes C-Programm ist eine Abfolge von Deklarationen und Anweisungen. Einfache Anweisungen erhält man, in dem man einen Ausdruck nimmt und einen Strichpunkt dahinter schreibt:&lt;br /&gt;
 {{Ausdruck|}};&lt;br /&gt;
wie in&lt;br /&gt;
 x = x+1;&lt;br /&gt;
&lt;br /&gt;
Andere Anweisungen sind die unten aufgeführten Schleifen und die if- sowie die switch-Anweisung.&lt;br /&gt;
&lt;br /&gt;
Mehrere Deklarationen und Anweisungen können zu einem Block zusammengefasst werden. Dieser Block stellt dann wieder eine einzelne Anweisung dar und kann genau so gehandhabt werden!&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
In diesem Sinne ist auch z.B. die Syntax der if-Anweisung zu verstehen&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
besagt, daß der abhängig ausgeführte Code eine einzelne Anweisung sein darf oder eben ein kompletter Block oder die Verschachtelung mehrerer Blöcke etc.&lt;br /&gt;
&lt;br /&gt;
Eine Anweisung kann auch &amp;quot;leer&amp;quot; sein, also nichts tun. Diese Anweisungen sind der leere Block&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
und der Strichpunkt&lt;br /&gt;
 ;&lt;br /&gt;
die man gelegentlich in Schleifen findet:&lt;br /&gt;
 while (!timeout())&lt;br /&gt;
    {}&lt;br /&gt;
oder hinter Sprungmarken, die sonst direkt vor einer schliessenden Blockklammer stünden:&lt;br /&gt;
 {&lt;br /&gt;
    ...&lt;br /&gt;
    goto ein_label;&lt;br /&gt;
    ...&lt;br /&gt;
    {{Label|ein_label}}:;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Nicht jede Anweisung ist an jeder Stelle eines C-Programms erlaubt, so darf ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; nut innerhalb einer Schleife stehen. Gleiches gilt für &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;, das aber auch innerhalb eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; vorkommen darf.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Dies steht für einen Datentyp. Es kann ein elementarer Typ sein wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;, ein Zeiger darauf wie &amp;lt;tt&amp;gt;char*&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;void*&amp;lt;/tt&amp;gt;, und auch Qualifier enthalten wie das &amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt; im Typ &amp;lt;tt&amp;gt;unsigned long long&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Zu den Typen gehören auch zusammengesetzte Datentypen wie Strukturen und Unions, mit &amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt; selbst definierte Typen und natürlich Zeiger darauf, wie aus dem Abschnitt [[#Datentypen|Datentypen]]:&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person *&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;data32_t&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;&lt;br /&gt;
und Zeiger auf Funktionen.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Parameterliste&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
Die Parameterliste bei einer Funktionsdefinition gibt an, wieviel Übergabeparameter sie bekommt, wie diese heissen und welchen Typs diese sind. Der prinzipielle Aufbau ist&lt;br /&gt;
 {{Type}} {{Bezeichner}}, {{Type}} {{Bezeichner}}, ...&lt;br /&gt;
Falls die Funktion keine Parameter hat, dann ist die Parameterliste leer.&lt;br /&gt;
&lt;br /&gt;
Hier als Beispiel die zweiparametrige Funktion &amp;lt;tt&amp;gt;produkt&amp;lt;/tt&amp;gt;. Der erste Parameter heisst&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und ist ein &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;. Der zweite namens&amp;amp;nbsp;&amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; ist vom Typ &amp;quot;Zeiger auf double&amp;quot;, der Inhalt &amp;lt;tt&amp;gt;*b&amp;lt;/tt&amp;gt; ist also auch ein double.&lt;br /&gt;
&lt;br /&gt;
'''Definition der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b)&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
In älteren C-Quellen findet man noch eine andere Syntax für die Deklaration der Parameter, die aber heute praktisch nicht mehr verwendet wird:&lt;br /&gt;
'''alte Definition der Funktion:'''&lt;br /&gt;
 double produkt (a, b)&lt;br /&gt;
 double a, *b;&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Um die Funktion bekannt zu machen, werdendet man eine Deklaration bzw. den Prototypen, der dem Compiler nur mitteilt, welche Parameter die Funktion bekommt und was sie zurückliefert. Für den Aufruf der Funktion muss der Compiler nur diesen Prototyp kennen, ''was'' die Funktion im Endeffekt macht und wie sie implementiert wurde ist egal, sie wird als BlackBox angesehen.&lt;br /&gt;
&lt;br /&gt;
'''Prototyp der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b);&lt;br /&gt;
Hier dürfen die Bezeichner auch fehlen:&lt;br /&gt;
 double produkt (double, double*);&lt;br /&gt;
&lt;br /&gt;
==if==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==if-else==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==for==&lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Eine for-Schleife entspricht folgendem Konstrukt. Dabei sind die drei Ausdrücke optional. Fehlt die Bedingung, dann wird diese als &amp;quot;wahr&amp;quot; angenommen. Die beiden anderen Ausdrücke wird man als Ausdrücke mit Nebeneffekt wählen wie z.B. &amp;lt;tt&amp;gt;x=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;x=x-2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
 {&lt;br /&gt;
    {{Ausdruck|1}};&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_loop}}:&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
    else&lt;br /&gt;
       goto _break;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_continue}}:&lt;br /&gt;
    {{Ausdruck|2}};&lt;br /&gt;
    goto _loop;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_break}}:;&lt;br /&gt;
 }&lt;br /&gt;
Die Labels &amp;lt;tt&amp;gt;_break&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_continue&amp;lt;/tt&amp;gt; entsprechen den Sprungzielen einer &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Anweisung innerhalb von &amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==do-while==&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while  ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
==while==&lt;br /&gt;
 while  ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==switch==&lt;br /&gt;
 switch  ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    ...&lt;br /&gt;
  &lt;br /&gt;
    default:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#break-Anweisung|&amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Konstanten|&amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#continue-Anweisung|&amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#do-while-Schleife|&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Enum|&amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#for-Schleife|&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#goto-Anweisung|&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#return-Anweisung|&amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Liste der Operatoren|sizeof]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Strukturen|&amp;lt;tt&amp;gt;struct&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Eigene Datentypen|&amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Unions|&amp;lt;tt&amp;gt;union&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#while-Schleife|&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund2}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Arithmetische Operatoren&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Dies sind die &amp;quot;normalen&amp;quot; arithmetischen Operationen, wie man sie aus der Schule kennt. Man kann damit und allen anderen Operatoren auch komplexere Ausdrücke aufbauen. Die Prioritäten sind so, wie man sie kennt, also &amp;quot;Punktrechnung vor Strichrechnung&amp;quot;. Will man dies ändern, dann mit den runden Klammern:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;1+2*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 7&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(1+2)*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 9&amp;lt;br/&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}}&amp;amp;nbsp;+&amp;amp;nbsp;{{Ausdruck|}}&amp;lt;/tt&amp;gt; || Addition&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} - {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Subtraktion&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} * {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Multiplikation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} / {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Division&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} % {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Rest der Division (modulo)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;- {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Vorzeichenumkehr, Zweier-Komplement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Logische Operatoren und Vergleiche&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die logischen und die vergleichenden Operatoren liefern als Ergebnis den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (wahr) oder einen Wert ungleich&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (falsch, um genau zu sein den Wert &amp;lt;tt&amp;gt;!0&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Man kann das Ergebnis zwar einer Variablen zuweisen, in aller Regel wird man solche Ausdrücke jedoch in Bedingungen zu &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder in Abbruch-Bedingungen von Schleifen finden.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;&amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches AND: beides wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124;&amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches OR: mind. eines ist wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;! {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches NOT (0 &amp;amp;harr; ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} == {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} != {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist nicht gleich&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bitweise Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~ {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise NOT (Einser-Komplement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise AND&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise ODER&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} ^ {{Ausdruck|}}&amp;lt;/tt&amp;gt; ||bitweise XOR&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Shift-Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;lt;&amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Bits nach links schieben&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;gt;&amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Schieben nach rechts schieben&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Typen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Ein Cast in C kann dazu verwendet werden, den Typ eines Ausdruckes zu ändern oder den Ausdruck mit einer bestimmten Genauigkeit zu berechnen. Wird z.B. eine Berechnung standardmässig in 16 Bit ausgeführt, dann kann man mit einem Cast &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(long) &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
ausdrücken, daß die Berechnung in 32 Bit erfolgen soll. Des weiteren kann man Zeiger und ganze Zahlen und Gleitkommazahlen ineinander umwandeln.&lt;br /&gt;
&lt;br /&gt;
Casts können ''nicht'' dazu verwendet werden, um z.B. eine Zahl in einen String zu konvertieren, der diese Zahl darstellt! Dafür gibt es spezielle Funktionen wie &amp;lt;tt&amp;gt;itoa&amp;lt;/tt&amp;gt;!&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Type}}) {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Cast, Typwandlung&lt;br /&gt;
|-&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;| &amp;lt;tt&amp;gt;sizeof ({{Type}})&amp;lt;/tt&amp;gt; || Eine Konstante, deren Wert die Größe (in Bytes) des Typs ist. &amp;lt;tt&amp;gt;sizeof&amp;lt;/tt&amp;gt; ist auch auf Objekte anwendbar wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, Arrays bekannter Größe, Strukturen und Unions,  Array-, Struktur- und Union-Komponenten, Pointer, etc. Beispiel:&amp;lt;br/&amp;gt;&lt;br /&gt;
 int i, sum=0, array[] = { 1, -13, 4, 0, sizeof (int*) };&lt;br /&gt;
 &lt;br /&gt;
 for (i=0; i&amp;lt; sizeof (array) / sizeof (array[0]); i++)&lt;br /&gt;
    sum += array[i];&lt;br /&gt;
Alle Elemente des Arrays werden aufaddiert, ohne daß deren Anzahl explizit in der Schleife genannt ist.&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zeiger und Adressen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;* {{Adresse}}&amp;lt;/tt&amp;gt; || der Inhalt an Adresse&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp; {{Lvalue}}&amp;lt;/tt&amp;gt; || Adresse von&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Strukturen, Unions, Arrays&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Struct&amp;gt;}}.{{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Zeiger-auf-Struct&amp;gt;}} -&amp;gt; {{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union, deren Adresse man hat&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Adresse}}&amp;amp;#91;{{Ausdruck|}}&amp;amp;#93;&amp;lt;/tt&amp;gt; || Array-Element&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bedingte Auswertung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Bedingung}}) ? {{Ausdruck|}} : {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Auswahl des Wertes abhängig von der Bedingung&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zuweisung und Operatoren mit Nebeneffekt&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die Unterschiede der post- und pre-Varianten der Increment/Decrement kommen in Konstrukten wie &amp;lt;tt&amp;gt;x = *p++&amp;lt;/tt&amp;gt; zum tragen:&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *p++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; p = p+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *++p;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; p = p+1; x = *p;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = (*p)++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; *p = (*p)+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = ++(*p);&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; *p = (*p)+1; x = *p;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} = {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Zuweisung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++ {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-- {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Decrement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ++&amp;lt;/tt&amp;gt; || Post-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} --&amp;lt;/tt&amp;gt; || Post-Decrement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Kurzschreibweisen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Für ganz Faule gibt es anstatt&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a = a @ b&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
für viele Operatoren (hier dargestellt durch ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;@&amp;lt;/tt&amp;gt;) die abkürzende Schreibweise&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a @= b&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} += {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} -= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} *= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} /= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} %= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ^= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;lt;&amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;gt;&amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Autoren'''&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
* Kernighan und Ritchie - Buch&lt;br /&gt;
* Christian Wirth , C Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://wwwuser.gwdg.de/~kboehm/ebook/inhalt.html C-Programmieren unter Linux]&lt;br /&gt;
* [http://www.gdv.uni-hannover.de/documentation.php Skripte zum Selbststudium: C, C++, Java, etc]&lt;br /&gt;
* [http://info.baeumle.com/ansic.html Einführung in ANSI-C]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Quellcode C|!]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Inrfb2</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10399</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10399"/>
				<updated>2007-03-13T11:49:25Z</updated>
		
		<summary type="html">&lt;p&gt;Inrfb2: /* Aufruf */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Programmiersprache C wurde 1971 als Gundlage für das Betriebssystem UNIX in den USA entwickelt (UNIX ist zu über 90% in C geschrieben). 1978 wurde von Brian Kernighan und Dennis Ritchie eine eindeutige Sprachdefinition entwickelt. Mittlerweile ist C von ANSI und ISO standardisiert.&lt;br /&gt;
&lt;br /&gt;
Heute sind C und ihr Nachfolger C++ die dominierenden Programmiersprachen. Sehr viele Anwendungen sind in C geschrieben, was inzwischen auch auf eingebettete Systeme zutrifft, die lange in Assembler programmiert werden mussten, da keine ausreichend leistungsfähigen Compiler zur Verfügung standen. &lt;br /&gt;
&lt;br /&gt;
Leider ist C nicht einfach zu lernen &amp;amp;ndash; es wurde weder von noch für Hobby-Programmierer entwickelt &amp;amp;ndash; und eignet sich daher nur bedingt für den Einsteiger. Mit etwas Übung und einem optimierenden Compiler kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
Vom Design her ist C eine Hardware-unabhängig Sprache. Das bedeutet, daß C-Programme mit vertretbarem Aufwand auf ein anderes System portiert werden können. Dazu benötigt man lediglich einen anderen Compiler, und Inline-Assembler-Anweisungen (Assembleranweisungen innerhalb eines C-Programmes) müssen der neuen Hardware (Prozessor) angepasst werden. &lt;br /&gt;
&lt;br /&gt;
==Geschichte==&lt;br /&gt;
;1971: C wird entwickelt&lt;br /&gt;
;1978: Kernighan und Ritchie definieren die Sprache.&lt;br /&gt;
;1983: ANSI und ISO standardisieren C.&lt;br /&gt;
;1992: Bjarne Stroustrup enwickelt die Nachfolgesprache C++.&lt;br /&gt;
&lt;br /&gt;
=Aufbau eines C-Programmes=&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
   C-Programme haben keinen fixen Aufbau wie z.B. Pascal. Es gibt zwar gewisse Regeln, aber sonst sind dem Programmierer alle Freiheiten überlassen. Der folgende &amp;quot;Beispiel-Aufbau&amp;quot; ist daher nicht zwingend und kann durchaus verändert werden.&lt;br /&gt;
&lt;br /&gt;
   Natürlich haben C-Programme einen fixen Aufbau! Ebenso wie Pascal-Programme auch unterliegen sie einer strikten Grammatik! &lt;br /&gt;
Auskommentiert --[[Benutzer:SprinterSB|SprinterSB]] 10:23, 17. Feb 2006 (CET)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Ein einfaches C-Programm könnte folgendermassen aussehen. Das Programm tut eigentlich nichts, aber das Beispiel zeigt den prinzipiellen Aufbau. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 int Zahl1;&lt;br /&gt;
 char Zeichen1;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int zahl2;&lt;br /&gt;
 &lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Beschreibung:'''&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndash; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
 {{comment|void-Definition von main ist nur beim Controller ueblich}}&lt;br /&gt;
 {{comment|spezielle Compilereinstellungen sind noetig, damit bei dieser Definition von main}}&lt;br /&gt;
 {{comment|kein Fehler/Warnung erzeugt wird.}}&lt;br /&gt;
 void main ()&lt;br /&gt;
 {&lt;br /&gt;
     ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
 int main (void)&lt;br /&gt;
 {  {{comment|der Block &amp;quot;main&amp;quot; beginnt}}&lt;br /&gt;
    int zahl;&lt;br /&gt;
    &lt;br /&gt;
    {   {{comment|ein Block beginnt}}&lt;br /&gt;
        {{comment|hier koennen Deklarationen und Anweisungen stehen}}&lt;br /&gt;
    }   {{comment|der Block endet}}&lt;br /&gt;
   &lt;br /&gt;
    return 0;&lt;br /&gt;
 }  {{comment|&amp;quot;main&amp;quot; endet}}&lt;br /&gt;
&lt;br /&gt;
=Datentypen=&lt;br /&gt;
==Elementare Datentypen==&lt;br /&gt;
Der Datentyp einer Variable gibt an, welche Werte eine Variable enthalten kann, welcher Art diese Daten sind und wie sie verarbeitet werden, etwa in arithmetischen Operationen wie einer Addition. So ist es zum Beispiel möglich, in eine Variable vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ganze Zahlen zwischen ca. -32000 und +32000 einzutragen. In einer char-Variable können ASCII-Zeichen gespeichert werden (alles, was Sie mit der Tastatur erzeugen können) oder ganze Zahlen von -128 bis 127.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da C plattformabhängig ist, hängt die Größe eines Datentypes zum Teil von der genutzten Hardware (z.B. 8, 16 oder 32 Bit-Controller) und dem Compiler und dessen Einstellungen ab!&lt;br /&gt;
&lt;br /&gt;
===int, char, short, long (ganze Zahlen)===&lt;br /&gt;
In Variable dieser Typen können Sie ganze Zahlen abspeichern, also z.B. 1, &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;2, 100, 12345. Jeden dieser Typen gibt es in zwei Ausprägungen: als &amp;quot;&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;quot;, also als vorzeichenbehafteten Typ, und als &amp;quot;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&amp;quot;, also ohne Vorzeichen, d.h. das Vorzeichen wird als 0 oder +1 genommen. &lt;br /&gt;
&lt;br /&gt;
Vorzeichenbehaftete Ganzzahl-Typen werden intern im &amp;lt;tt&amp;gt;n-1&amp;lt;/tt&amp;gt;-Komplement dargestellt, das Vorzeichen selbst findet sich also im höchstwertigen Bit. Werden zur Speicherung ''b'' Bits verwendet, dann reicht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;z.B. *zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==Enum==&lt;br /&gt;
&lt;br /&gt;
Über &amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt; können Aufzählungen definiert werden. Die Werte sind &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Werte und beginnen mit&amp;amp;nbsp;0. Der folgende enum hat einen um&amp;amp;nbsp;1 grösseren Wert. Mit einer Zuweisung können auch andere Werte zugeordnet werden. Klarer wird's im Beispiel:&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 enum Farben&lt;br /&gt;
 {&lt;br /&gt;
    ROT,&lt;br /&gt;
    GRUEN,&lt;br /&gt;
    BLAU,&lt;br /&gt;
    BRAUN = 5,&lt;br /&gt;
    SCHWARZ&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
Dies definiert die Konstanten &amp;lt;tt&amp;gt;ROT=0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;GRUEN=1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BLAU=2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BRAUN=5&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;SCHWARZ=6&amp;lt;/tt&amp;gt; und den Typ &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void foo (enum Farben farbe)&lt;br /&gt;
{&lt;br /&gt;
   switch (farbe)&lt;br /&gt;
   {&lt;br /&gt;
      case ROT:&lt;br /&gt;
         ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit kann man anstatt &amp;quot;magischer&amp;quot; Zahlen sprechende Namen im Code verwenden, etwa in Berechnungen und Zuweisungen, Vergleichen oder als Konstante hinter einem &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zusammengesetzte Datentypen==&lt;br /&gt;
===Arrays===&lt;br /&gt;
Oft muß man sehr viele Werte gleichzeitig abspeichern und betrachten, die alle der selben Aufgabe dienen. Man schreibt z.B. ein Programm, das 10 Zahlen einlesen und anschließend wieder ausgeben soll. Man könnte das natürlich mit 10 einzelnen Variablen bewerkstelligen, aber es ist sinnvoller, dabei Arrays &amp;amp;ndash; teilweise auch als ''Felder'' bezeichnet &amp;amp;ndash; zu verwenden.&lt;br /&gt;
&lt;br /&gt;
In einem Array werden mehrere Variablen gleichen Typs zusammengefasst und hintereinander im Speicher abgelegt. So kann man viele tausend Variablen anlegen mit nur einer Zeile Code. Doch es gibt noch größere Vorteile: Sie können das Array mit einer Schleife ganz einfach nach Werten durchsuchen. Stellen Sie sich vor, Sie müssten mit 100 verschiedenen Variablen &amp;lt;tt&amp;gt;Zahl_00&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;Zahl_99&amp;lt;/tt&amp;gt; arbeiten!&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}}&amp;amp;#91;{{Konstante}}&amp;amp;#93;;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 unsigned int werte[100];&lt;br /&gt;
&lt;br /&gt;
Der Name muß natürlich ein gültiger Bezeichner sein, als Datentyp kann jeder Typ genommen werden &amp;amp;ndash; sowohl elementare Datentypen als auch Zeiger, Strukturen, Unions oder selbst definierte Datentypen. In der eckigen Klammer wird die Anzahl der Elemente bekanntgegeben. Ein mit [3] definiertes Array hat Platz für drei Variablen. Da der Index immer bei 0 beginnt, greift man also mit &amp;lt;tt&amp;gt;[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;[1]&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;[2]&amp;lt;/tt&amp;gt; auf den jeweilige Inhalt zu. Um auf eine der im Array enthaltenen Variablen zugreifen zu können, müssen Sie den Variablennamen und in eckigen Klammern den Index (die &amp;quot;Nummer&amp;quot;) der Variablen angeben. Diese Variable verhält sich dann wie eine ganz normale Variable des jeweiligen Datentypes. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #define NZAHLEN 10&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int i;&lt;br /&gt;
    int zahlen[NZAHLEN];  {{comment|zahlen[0] ... zahlen[9]}}&lt;br /&gt;
  &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++)&lt;br /&gt;
    {&lt;br /&gt;
       printf (&amp;quot;Bitte Zahl %d eingeben: &amp;quot;, i);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; zahlen[i]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++) &lt;br /&gt;
       printf (&amp;quot;Zahl %d ist: %d\n&amp;quot;, i, zahlen[i]);&lt;br /&gt;
      &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 10 int-Variablen großes Array angelegt. &lt;br /&gt;
In dieses wird nun der Reihe nach 10 Zahlen eingelesen. &lt;br /&gt;
Anschließend werden alle 10 Zahlen ausgegeben. &lt;br /&gt;
&lt;br /&gt;
Dabei wird die Größe der Arrays und das Schleifenende über das Define &amp;quot;&amp;lt;tt&amp;gt;NZAHLEN&amp;lt;/tt&amp;gt;&amp;quot; angegeben. Dadurch muss nur ''eine Stelle'' im Code geändert werden, wenn die Größe des Arrays einmal einen anderer Wert als 10 haben soll &amp;amp;ndash; dies vermeidet Fehler die dadurch entstehen, wenn man beim Anpassen der Array-Größe eine Codestelle vergisst, zudem wird der Code lesbarer als wenn irgendwo die Zahl &amp;quot;10&amp;quot; auftaucht.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
:Wird ein ungültiger Index angeben (einer, der in der Deklaration nicht enthalten ist) können  undefinierte Dinge passieren, wenn dadurch andere Variableninhalte oder Programmcode überschrieben wird, der hinter oder vor dem Array im Speicher liegt. Schlimmstenfalls kann sogar der Computer/Controller abstürzen. Also darauf achten, daß keine ungültigen Werte als Index auftreten!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Strings (Zeichenketten)===&lt;br /&gt;
Ein String ist nichts anderes als ein Array, das aus einzelnen Zeichen (&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;) gebildet wird. Die Ausgabe auf dem Bildschirm funktioniert am einfachsten mittels Strings.&lt;br /&gt;
&lt;br /&gt;
Die Definition eines Strings erfolgt also genauso wie bei Arrays:&lt;br /&gt;
 char string[21];&lt;br /&gt;
&lt;br /&gt;
Nun haben Sie eine String, in dem Sie 21 Zeichen speichern können. Ganz richtig ist das jedoch nicht. C arbeitet mit &amp;quot;null-terminierten Strings&amp;quot;. Das beudeutet, dass die Länge des Strings nicht abgespeichert wird, sondern das Zeichen mit dem ASCII-Wert 0 das Stringende kennzeichnet. Daher auch die Bezeichnung  &amp;quot;null terminiert&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Das letzte Zeichen eines Strings muß daher immer das ASCII-Zeichen Nr. 0 sein. Ist es das nicht, hat der String kein definiertes Ende, und wenn Sie versuchen, ihn durch eine Standard-Funktion auszugeben zu lassen, könnte es eine Weile dauern, bis sich im Speicher zufällig irgendwo eine 0 befindet. Es stehen ihnen daher bei dem Beispiel nur 20 Zeichen zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
===Mehrdimensionale Arrays===&lt;br /&gt;
Manchmal benötigt man mehr als nur ein eindimensionales Array, wie Sie es bisher kennengelernt haben. Auch dies ist kein Problem. In der Deklaration geben Sie einfach mehrere eckige Klammern hintereinander an. Aber Vorsicht: der Speicherplatz ist begrenzt, ein &amp;quot;&amp;lt;tt&amp;gt;char feld[1024][1024]&amp;lt;/tt&amp;gt;&amp;quot; hat die Speicherplatzgrenzen vermutlich bereits weit überschritten, und der Compiler wird einen (bei gewissen Einstellung auch keinen) Fehler liefern.&lt;br /&gt;
Beim Zugriff auf mehrdimensionale Felder müssen auch mehrere Indizes angeben werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  int x,y;&lt;br /&gt;
  int feld[3][5];&lt;br /&gt;
 &lt;br /&gt;
  for (x=0; x&amp;lt;3; x++) &lt;br /&gt;
  {&lt;br /&gt;
     for (y=0; y&amp;lt;5; y++)&lt;br /&gt;
     {&lt;br /&gt;
       printf (&amp;quot;Feldwert x: %d,  y: %d &amp;quot;, x, y);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; feld[x][y]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  for(x=0; x&amp;lt;3; x++) &lt;br /&gt;
     for (y=0; y&amp;lt;5; y++) &lt;br /&gt;
        printf (&amp;quot;Wert: feld[%d][%d] = %d\n&amp;quot;, x, y, feld[x][y]);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 3 mal 5 &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array angelegt. &lt;br /&gt;
Dann werden die Werte eingegeben: zuerst &amp;lt;tt&amp;gt;feld[0][0]&amp;lt;/tt&amp;gt;, dann &amp;lt;tt&amp;gt;feld[0][1]&amp;lt;/tt&amp;gt;, usw. bis &amp;lt;tt&amp;gt;feld[2][4]&amp;lt;/tt&amp;gt;. &lt;br /&gt;
Zum Schluß werden alle Werte noch einmal ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===Strukturen===&lt;br /&gt;
In C können Sie sogenannte &amp;quot;Strukturen&amp;quot; definieren. Dabei handelt es sich um eine Zusammenfassung mehrerer Datentypen zu einem größeren. Im Unterschied zu Feldern können in Strukturen unterschiedliche Datentypen zusammengestellt und gespeichert werden: &lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 struct {{Bezeichner}}&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur 'Person'}}&lt;br /&gt;
 struct Person &lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;lt;tt&amp;gt;struct Person {&amp;lt;/tt&amp;gt;&amp;quot; leitet die Definition der Struktur mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;Person&amp;lt;/tt&amp;gt;&amp;quot; ein. &lt;br /&gt;
Dann werden in dieser Struktur fünf Komponenten definiert: drei Strings und zwei &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. &lt;br /&gt;
mit &amp;lt;tt&amp;gt;}&amp;lt;/tt&amp;gt; wird die Definition abgeschlossen. Sie haben damit einen Datentyp erstellt. Um eine Variable des Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach an&lt;br /&gt;
 struct Person {{Bezeichner}};&lt;br /&gt;
&lt;br /&gt;
Zum Zugriff auf eine Komponente der Struktur gibt man den Namen der Struktur-Variablen an (im folgenden Beispiel also &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;klaus&amp;lt;/tt&amp;gt;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
 {{comment|Definition zweier Struktur-Variablen}}&lt;br /&gt;
 struct Person hubert, klaus;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Zugriff auf Struktur-Komponenten}}&lt;br /&gt;
 hubert.alter = 32;&lt;br /&gt;
 klaus.alter = hubert.alter + 1;&lt;br /&gt;
&lt;br /&gt;
===Unions===&lt;br /&gt;
Eine Union wird ganz analog zu einer Struktur deklariert und verwendet. Sie unterscheidet sich von einer Struktur jedoch dadurch, daß ihre Elemente nicht nacheinander im Speicher abgelegt werden, sondern sich überlagern. Auf die in einer Union enthaltenen Daten gibt es also verschiedene Sichten: je nachdem, welche Sicht bzw. Interpretation der Daten man gerne hätte, wählt man den gewünschten Zugriff.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
union Daten &lt;br /&gt;
{&lt;br /&gt;
   int id;&lt;br /&gt;
&lt;br /&gt;
   struct Person u_person;&lt;br /&gt;
&lt;br /&gt;
   struct u_double&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      double wert;&lt;br /&gt;
   };&lt;br /&gt;
&lt;br /&gt;
   struct u_pointer&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      union Daten * p1;&lt;br /&gt;
      union Daten * p2;&lt;br /&gt;
   };&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
union Daten data;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies definiert eine Union mit den vier Zugriffsmöglichkeiten &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_double&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Größe der Union richtet sich dabei nach der grössten Komponente. In diesem Beispiel sind alle Komponenten so angelegt worden, daß sie an erster Stelle ein &amp;lt;tt&amp;gt;int id&amp;lt;/tt&amp;gt; enthalten. In &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; könnte man sich also merken, wie die Daten in der Union zu interpretieren sind. Würde &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; nicht dieses &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; enthalten, so würde sich &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; mit &amp;lt;tt&amp;gt;data.u_person.vname&amp;lt;/tt&amp;gt; überlagern. Ein Ändern der ersten Buchstaben von &amp;lt;tt&amp;gt;vname&amp;lt;/tt&amp;gt; hätte also ein Ändern von &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; zur Folge, und man könnte es nicht mehr als Merker verwenden. Mit diesem Feld überlagert das &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; die &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;-Felder der anderen Sichten, z.B. ist &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; der selbe Zugriff wie auf &amp;lt;tt&amp;gt;data.u_person.id&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein anderes Beispiel ist eine Union, die es ermöglicht, auf die einzelnen Bytes eines &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; zuzugreifen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef union&lt;br /&gt;
{&lt;br /&gt;
   unsigned long  as_long;&lt;br /&gt;
   unsignen short as_short[2];&lt;br /&gt;
   unsignen char  as_byte[4];&lt;br /&gt;
} data32_t;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies überlagert einen &amp;lt;tt&amp;gt;unsigned long&amp;lt;/tt&amp;gt; &amp;amp;ndash; also eine 32-Bit-Zahl &amp;amp;ndash; mit vier Bytes bzw. zwei Shorts.&lt;br /&gt;
 data32_t wert;&lt;br /&gt;
 &lt;br /&gt;
 wert.as_long = 0x12345678;&lt;br /&gt;
 wert.as_byte[0] = 0xab;&lt;br /&gt;
 {{comment|nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform)}}&lt;br /&gt;
&lt;br /&gt;
==Eigene Datentypen==&lt;br /&gt;
&lt;br /&gt;
=Variablen=&lt;br /&gt;
Eine Variable ist ein Synonym (=anderer Name) für eine Speicherstelle in einem Computer. Einfacher gesagt, eine Variable bietet Raum, um Daten wie Zahlen oder Zeichen zu speichern und wieder zu lesen.&lt;br /&gt;
&lt;br /&gt;
==Variablennamen==&lt;br /&gt;
Ein Variablenname kann zusammengesetzt werden aus den Buchstaben &amp;lt;tt&amp;gt;'''A'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''Z'''&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;'''a'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''z'''&amp;lt;/tt&amp;gt;, den Ziffern &amp;lt;tt&amp;gt;'''0'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''9'''&amp;lt;/tt&amp;gt;, sowie dem Sonderzeichen &amp;quot;Unterstrich&amp;quot; (underscore) &amp;lt;tt&amp;gt;'''_'''&amp;lt;/tt&amp;gt;. Dabei darf an erster Stelle keine Ziffer stehen. Die Bezeichner &amp;lt;tt&amp;gt;hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALLO&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALL0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;_123&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_HALLO&amp;lt;/tt&amp;gt; sind also alle gültige und unterschiedliche Variablennamen.&lt;br /&gt;
&lt;br /&gt;
==Anlegen von Variablen==&lt;br /&gt;
Um eine Variable verwenden zu können, muss sie zuerst vereinbart (&amp;quot;erzeugt&amp;quot;) werden. Dies wird auch als &amp;quot;''Definition der Variablen''&amp;quot; bezeichnet und geht so: Schreiben Sie zuerst den Datentyp, dann den Namen der Variablen. Zum Schluß kommt noch der Strichpunkt, wie nach jeder C-Anweisung oder Deklaration. Und nicht vergessen: C unterscheidet zwischen  Groß- und Kleinschreibung! &lt;br /&gt;
 int Zahl1, Zahl2;&lt;br /&gt;
 char Zeichen;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    float gleitZahl;&lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:'''&lt;br /&gt;
In einer Zeile können auch mehrere Variablen gleichen Types vereinbart werden, wenn man ein Komma dazwischen setzt. Variablen können in jedem Block vereinbart werden. Siehe [[#Gültigkeitsbereich|Gültigkeitsbereich]].&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen==&lt;br /&gt;
Man kann einer vereinbarten Variable Werte [[#Zuweisungen|zuweisen]]. Dazu schreibt man zuerst den Variablennamen, ein Gleichheitszeichen &amp;quot;&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;&amp;quot; und anschliessend den zuzuweisenden [[#Ausdrücke|Ausdruck]]. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, zahl2 = 12;&lt;br /&gt;
  char zeichen1 = 'A';&lt;br /&gt;
&lt;br /&gt;
  zahl1 = 52;&lt;br /&gt;
  zeichen1 = zeichen1 + 1; &lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Zuerst werden drei Variablen angelegt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;: wird gleich bei der Vereinbarung der Wert 12 zugewiesen. &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl1 = 52&amp;lt;/tt&amp;gt;: Hier wird der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; der Wert 52 zugewiesen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;: wird um 1 erhöht. Da in der Variablen &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; gespeichert ist, gibt sich ihr neuer Wert aus &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt;. Weil &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; dem Wert 65 entspricht, ist &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt; gleich 66, was dem Wert für &amp;lt;tt&amp;gt;'B'&amp;lt;/tt&amp;gt; entspricht.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei float==&lt;br /&gt;
Das funktioniert genau wie bei normale Zuweisungen. Nachkommastellen werden durch einen Punkt abgegrenzt: &lt;br /&gt;
 floatVariable = 3.14;&lt;br /&gt;
Zusätzlich kann eine Zehnerpotenz angegeben werden:&lt;br /&gt;
 floatVariable2 = -1.234E-6;&lt;br /&gt;
Dadurch wird der erst Wert mit 10&amp;lt;sup&amp;gt;&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;6&amp;lt;/sup&amp;gt; multipliziert, der Wert der Variablen ist also &lt;br /&gt;
:&amp;lt;math&amp;gt;-1{,}234\cdot10^{-6} = -0.000001234&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei logischen Variablen==&lt;br /&gt;
Wie bereits erwähnt, besitzt C keinen logischen Datentyp. Es müssen also &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; dafür genutzt werden. Die Zuweisung entpricht der Standard-Zuweisung. Wird der Wert 0 zugewiesen, dann ist die Variable &amp;quot;unwahr&amp;quot;, ansonsten ist sie &amp;quot;wahr&amp;quot;. &lt;br /&gt;
 intVariable = !0;   /* entspricht &amp;quot;wahr&amp;quot;   */&lt;br /&gt;
 intVariable = 0;    /* entspricht &amp;quot;unwahr&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
==Konstanten==&lt;br /&gt;
Konstanten können als Variable angesehen werden, die nicht beschrieben, sondern nur gelesen werden können. Ein typisches Beispiel dafür ist die Zahl &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; (rund 3,141592654). Niemand würde in der realen Welt versuchen, ihr einen anderen Wert zuzuweisen. Würde man &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; jedoch wie eine normale Variable anlegen, wäre dies ohne weiteres möglich. Um dies zu verhindern, gibt es das Schlüsselwort &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in C:&lt;br /&gt;
 const {{Type}} {{Bezeichner}} = {{Konstante}};  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Wichtig dabei ist, dass man Konstanten nur bei der Vereinbarung einen Wert zuweisen kann. &lt;br /&gt;
Da Konstanten gewöhnlich im gesamten Programm, zumindest einer Quelldatei genutzt werden, definiert man diese allerdings gewöhnlich außerhalb des main-Blockes entweder am Anfang eines Programmes, oder in einer sogenannten Header-Datei, die per &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; eingebunden wird.&lt;br /&gt;
 const float PI = 3.141592;  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Es sei jedoch erwähnt, daß auch einer Konstanten nachträglich ein anderer Wert zugewieden werden kann. Im obigen Beispiel könnte mit&lt;br /&gt;
 * ((float*) &amp;amp;PI) = 2;&lt;br /&gt;
der Wert von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; im Nachhinein verändert werden. Es wird die Adresse von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; genommen und diese Adresse durch den Cast in eine ganz normale &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;-Adresse umgewandelt, über welche der Wert geändert wird. Die sei der Vollständigkeit halber erwähnt.&lt;br /&gt;
&lt;br /&gt;
Je nachdem, an welcher Stelle sich das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; bei einer Pointer-Deklaration befindet, markiert es den Pointer als konstant oder das Objekt, auf das dieser Pointer zeigt. Eine häufige Parameterdeklaration in Ausgabe-Funktionen, die einen String erhalten, ist&lt;br /&gt;
 void foo (const char * str, ...);&lt;br /&gt;
Dadurch ist &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; der Zeiger auf eine Zeichenkette, die innerhalt der Funktion nicht verändert wird bzw. verändert werden darf. Eine Zuweisung wie &amp;lt;tt&amp;gt;*str = 'a'&amp;lt;/tt&amp;gt; ergibt also einen Fehler. &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; selbst kann aber sehr wohl verändert werden, etwa mit &amp;lt;tt&amp;gt;str++&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Soll ausgedrückt werden, daß &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; unveränderlich ist, dann so:&lt;br /&gt;
 void foo (char * const str, ...);&lt;br /&gt;
Jetzt wäre eine Änderung des Strings in Ordnung, etwa durch &amp;lt;tt&amp;gt;str[10] = 'a'&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Um sich zu merken, worauf das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; wirkt, trennt man die Deklaration in Gedanken beim&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf: Steht das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; links vom&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, dann gehört es zum &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, steht es rechts davon, dann gehört es zum Pointer. Natürlich ist es auch denkbar, beides &amp;amp;ndash; also den Zeiger und sein Ziel &amp;amp;ndash; als konstant zu markieren.&lt;br /&gt;
&lt;br /&gt;
==Gültigkeitsbereich==&lt;br /&gt;
In C können mehrere Variablen den gleichen Namen haben, solange eindeutig ist, welche in welchen Block gültig ist. Dabei gelten folgende Regeln: &lt;br /&gt;
&lt;br /&gt;
;Lokale Variablen: sind Variablen, die innerhalb eines Blockes definiert werden. Jede Variable ist nur in dem Block gültig, in dem sie vereinbart wurde, sowie in allen darin enthaltenen Blöcken; es sei denn, in einem Unter-Block wird eine Variable gleichen Namens definiert. Dann bezieht sich in diesem Unter-Block der Bezeichner auf die im Unter-Block angelegte Variable.&lt;br /&gt;
;Globale Variablen: werden ausserhalb jedes Blockes definiert und gelten ab der Stelle, an der sie deklariert werden, siehe auch [[#Deklaration und Definition|Deklaration und Definition]]. Wird jedoch in einem Block eine Variable gleichen Namens angelegt, gilt ab hier bis zum Ende des Blocks nicht mehr die globale Variable, sondern die im Block deklarierte. Das Spiel kann man weiterspielen: wird in einem Unter-Block wieder eine namensgleiche Variable angelegt, gilt diese in dem Unterblock.&lt;br /&gt;
&lt;br /&gt;
==Speicherklassen==&lt;br /&gt;
Jede Variable in C gehört zu einer bestimmten Speicherklasse&lt;br /&gt;
;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;: Lokale Variablen sind in aller Regal sogenannte ''automatische Variablen''. Das bedeutet, sie werden automatisch angelegt, wenn ein Block bzw. eine Funktion betreten wird und danach wieder entfernt. Das Schlüsselwort &amp;quot;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;&amp;quot; wird praktisch nie hingeschrieben, denn lokale Variablen ohne die ausdrückliche Angabe einer Speicherklasse, sind automatisch automatische Variablen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;: Eine externes Symbol ist im ganzen Programm bekannt bzw. in dem Block, in der die Deklaration steht. In unterschiedlichen Blöcken stehende Deklarationen beziehen sich auf das gleiche Symbol! Obgleich das Datum global zugreifbar ist, ist der Gültigkeitsbereich auf den deklarierenden Block begrenzt bzw. auf das deklarierende Quell-Modul, sofern das Symbol ausserhalb jedes Blocks des Moduls deklariert wird. Siehe auch [[#Deklaration und Definition|Deklaration und Definition]].&lt;br /&gt;
;&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;: Die Variable ist im Block gültig bzw. im Quell-Modul (also in der C-Datei, in der die angelegt wurde), wenn sie nicht innerhalb eines Blockes angelegt wurde. Statische Variablen werden nicht in Registern oder im Frame der Funktion angelegt, sondern im selben Speicherbereich, in dem auch die globalen Variablen liegen; Konstanten evtl. auch im Flash. Eine lokale Variable, die als &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; angelegt wird, &amp;quot;überlebt&amp;quot; also das Verlassen des Blocks und hat beim neuerlichen Betreten des Blockes ihren bisherigen Wert. In unterschiedlichen Blöcken angelegte lokale statische Variablen beziehen sich auf unterschiedliche Speicherstellen, genau wie bei lokalen Variablen auch.&lt;br /&gt;
;&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;: Durch diese Speicherklasse wird eine Variable &amp;amp;ndash; falls möglich &amp;amp;ndash; als Registervariable angelegt, also in einem Maschinenregister des Computer/Controllers gehalten. Dadurch kann auf solche Variablen besonders schnell zugegriffen werden. Dieses Schlüsselwort ist bei modernen Compilern weitgehend überflüssig, da die entsprechenden Optimierungen selbständig vorgenommen werden, wenn ausreichend Register vorhanden sind. Auch globale Variablen können als Register angelegt werden, davon ist dem Anfänger aber dringend abzuraten, weil leicht schwerauffindbare Fehler und Abstürze auftreten, wenn man nicht genau weiss, welche Implikationen in einer solchen Definition stecken!&lt;br /&gt;
;&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;: (FIXME: volatile ist ein Qualifier und keine Speicherklasse) Dies ist das genaue Gegenteil von &amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt; und bewirkt, dass die Variable auf keinen Fall in einem Register zwischengespeichert werden darf, sondern immer aus dem RAM gelesen und ins RAM geschrieben werden soll. &amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt; müssen alle ''globalen'' Variablen markiert werden, die in [[ISR | Interrupt-Handlern]] verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Ausdrücke=&lt;br /&gt;
Eine Variable oder eine Konstante in C stellen einfache Ausdrücke dar.&lt;br /&gt;
Diese elementaren Ausdrücke können durch Operatoren miteinander verknüpft werden und so zu neuen, komplexeren Ausdrücken zusammen gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Einfache Beispiele für Ausdrücke sind also z.B.:&lt;br /&gt;
 1&lt;br /&gt;
 a&lt;br /&gt;
 'a'&lt;br /&gt;
 1 + a&lt;br /&gt;
 a == 1&lt;br /&gt;
&lt;br /&gt;
Auch Funktionen können einen Wert zurückliefern und in Ausdrücken weiter benutzt werden.&lt;br /&gt;
In den folgenden Abschnitten wird gezeigt, welche Operatoren in C vorhanden sind,&lt;br /&gt;
und wei man damit neue Ausdrücke aufbauen kann.&lt;br /&gt;
&lt;br /&gt;
==Lvalues==&lt;br /&gt;
&lt;br /&gt;
Ein Lvalue in C ist ein Ausdruck, dem ein anderer Ausdruck zugewiesen werden kann, dessen Wert also durch eine Zuweisung verändert werden kann.&lt;br /&gt;
das 'L' leitet sich ab von 'left' bwz. 'links' und das 'value' bedeutet Wert: Ein Lvalue ist ein Ausdruck, der auf der linken Seite einer Zuweisung stehen darf. Ein Lvalue ist also immer auch ein gültiger Ausdruck, aber die Umkehrung gilt in alles Regel nicht.&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für einen Lvalue ist eine &amp;quot;normale&amp;quot; Variable, die nicht mit &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; als Konstante markiert ist:&lt;br /&gt;
 a = 1;&lt;br /&gt;
Hingegen ist der Ausdruck &amp;lt;tt&amp;gt;a+1&amp;lt;/tt&amp;gt; kein Lvalue, denn eine Zuweisung wie&lt;br /&gt;
 a+1 = 2;&lt;br /&gt;
die mathematisch durchaus sinnvoll ist, erzeugt einen Compilerfehler, der etwa lauten könnte &amp;quot;illegal lvalue in assignment&amp;quot;:&lt;br /&gt;
&amp;quot;ungültiger Wert in Zuweisung&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Andere Beipiele für Lvalues sind die Komponenten von (nicht-konstanten) [[#Strukturen|Strukturen]] und [[#Unions|Unions]], [[#Arrays|Array]]-Elemente und die Dereferenzierungen von Pointern: Die Konstante&amp;amp;nbsp;4 wird durch den Cast in eine Adresse umgewandelt. Über die Dereferenzierung&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; wird an die Adresse&amp;amp;nbsp;4 im Speicher eine&amp;amp;nbsp;3 geschrieben. Ob das erlaubt bzw. sinnvoll ist, ist abhängig von der jeweiligen Architektur.&lt;br /&gt;
 * ((unsigned int *) 4) = 3;&lt;br /&gt;
Hier ist der gesamte &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;-Ausdruck ein Lvalue&lt;br /&gt;
&lt;br /&gt;
==Logische (boolsche) Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp;amp;&amp;amp;amp; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr oder &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; || gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; || ungleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;= b&amp;lt;/tt&amp;gt; || kleiner oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt; b&amp;lt;/tt&amp;gt; || kleiner als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt;= b&amp;lt;/tt&amp;gt; || glösser oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt; b&amp;lt;/tt&amp;gt; || grösser als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; nicht wahr und vice versa&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine interessante Eigenschaft der Operatoren &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;amp;amp;&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; ist, dass&lt;br /&gt;
sie die Auswertung abbrechen, sobald das Ergebnis feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet. Ein oft anzutreffendes Codestück sieht so aus, dabei sei &amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
  if (p &amp;amp;&amp;amp; *p == 5)&lt;br /&gt;
  {&lt;br /&gt;
     {{comment|mach was}}&lt;br /&gt;
  }&lt;br /&gt;
Zuerst wird in der Bedinung geprüft, ob Zeiger&amp;amp;nbsp;&amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; einen Wert ungleich Null hat, also ob er überhaupt einen gültigen Wert enthält. Es ist weit verbreitete Konvention in C, daß Zeiger, die keinen gültigen Wert haben, die Adresse&amp;amp;nbsp;0 enthalten. '''Nur dann, wenn ein Zeiger nicht ein Null-Pointer ist, darf überhaupt ein Zugriff über ihn erfolgen!'''&lt;br /&gt;
&lt;br /&gt;
==Vergleich von Variablen==&lt;br /&gt;
Skalare Variablen (also ganze Zahlen, Gleitkommazahlen, Zeiger) können miteinander verglichen werden. Dazu gibt es die folgenden Operatoren in C: &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; || ist nicht gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;=&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;=&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das Ergebnis der Auswertung ist eine ganze Zahl. Ist die Bedingung erfüllt, dann ist der Wert ungleich&amp;amp;nbsp;0. Ist die Bedingung nicht erfüllt, dann ist ihr Wert gleich&amp;amp;nbsp;0.&lt;br /&gt;
Meistens wird man diese Operatoren in &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Konstrukten finden wie zum Beispiel&lt;br /&gt;
 if (x &amp;gt;= 10)&lt;br /&gt;
    x = 10;&lt;br /&gt;
oder in Abbruchbedingungen von Schleifen, wie sie weiter unten erklärt werden.&lt;br /&gt;
&lt;br /&gt;
Es ist auch möglich, das Ergebnis der Auswertung in einer &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Variablen zu speichern:&lt;br /&gt;
 int i;&lt;br /&gt;
 int z1, z2;&lt;br /&gt;
 &lt;br /&gt;
 z1 = 5;&lt;br /&gt;
 z2 = 100;&lt;br /&gt;
 i = z1 &amp;lt;= z2;  {{comment|Ein Vergleich. i wird &amp;quot;wahr&amp;quot;, da z1 kleinergleich z2 ist}}&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich&amp;amp;nbsp;0 (&amp;quot;wahr&amp;quot;), wenn &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; kleiner oder gleich &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt; ist. Ist &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; jedoch größer als &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt;, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich&amp;amp;nbsp;0 (&amp;quot;unwahr&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
==Arithmetische Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a + b&amp;lt;/tt&amp;gt; || Summe (Addition)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a - b&amp;lt;/tt&amp;gt; || Differenz (Subtraktion)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a * b&amp;lt;/tt&amp;gt; || Produkt (Multiplikation)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a / b&amp;lt;/tt&amp;gt; || Quotient (Division, evtl. mit Rest)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a % b&amp;lt;/tt&amp;gt; || Rest bei Division (Modulo)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;-a&amp;lt;/tt&amp;gt; || Vorzeichenumkehr (Zweierkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Bit-Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp; b&amp;lt;/tt&amp;gt; || bitweise und (and)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || bitweise oder (or)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a ^ b&amp;lt;/tt&amp;gt; || bitweise exclusiv-oder (xor, exor)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;~a&amp;lt;/tt&amp;gt; || jedes Bit in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; invertieren (not, Einerkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Index-Operator bei Arrays==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a[b]&amp;lt;/tt&amp;gt; || das (b+1)ste Element des Feldes a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Folgendes gilt es bei der Verwendung des Indexoperators zu beachten:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; muss ein [[C-Tutorial#Felder | Feld]] oder [[C-Tutorial#Zeiger | Zeiger]] sein&lt;br /&gt;
# &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; muss ein Integer sein oder ein Datentyp, der sich in einen int umwandeln läßt (z.B. char)&lt;br /&gt;
# Es wird nicht geprüft, ob der Index &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; im Feld &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gültig ist!&lt;br /&gt;
# Der erste Index eines Feldes ist immer 0. Daher ''(b+1)stes Element'' in der Beschreibung&lt;br /&gt;
&lt;br /&gt;
==Komponenten-Auswahl bei Structs und Unions==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a.b&amp;lt;/tt&amp;gt; || Element b der [[C-Tutorial#Strukturen | Struktur]] oder des Unions a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adress-Operator und Dereferenzierung==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&amp;amp;amp;a&amp;lt;/tt&amp;gt; || Speicheradresse der Variablen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;*a&amp;lt;/tt&amp;gt; || Wert, der an der Adresse &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a-&amp;amp;gt;b&amp;lt;/tt&amp;gt; || Wert des Elements &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; der Struktur, deren Adresse in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Adressoperator &amp;amp; kann auf Variablen angewendet werden und&lt;br /&gt;
gibt die Startadresse der Variablen im Speicher zurück.&lt;br /&gt;
&lt;br /&gt;
Handelt es sich bei einer Variable um einen [[C-Tutorial#Zeiger | Zeiger]], so enthält&lt;br /&gt;
sie eine Speicheradresse. Um an den '''Wert''' zu gelangen, der&lt;br /&gt;
an dieser Adresse steht, wird der Operator * vorangestellt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
&lt;br /&gt;
 {{comment|x ist eine Integervariable und hat den Wert 5}}&lt;br /&gt;
 int x = 5;&lt;br /&gt;
     &lt;br /&gt;
 {{comment|z ist ein Zeiger auf eine Integer-Variable und enthaelt somit}}&lt;br /&gt;
 {{comment|die Speicheradresse einer Integer-Variablen}}&lt;br /&gt;
 int *z;       &lt;br /&gt;
  &lt;br /&gt;
 {{comment|Verwendung des Adress-Operators: weist an z die Adresse von x zu}}&lt;br /&gt;
 z = &amp;amp;x;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Verwendung der Dereferenzierung}}&lt;br /&gt;
 {{comment|erhoehe den Wert, der bei Adresse z steht, um eins}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|da z auf x zeigt, hat x jetzt den Wert 6}}&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff auf Struktir- und Union-Elemente eine abkürzende Schreibweise möglich:&lt;br /&gt;
&lt;br /&gt;
Statt &lt;br /&gt;
  (*strukturZeiger).element&lt;br /&gt;
kann geschrieben werden&lt;br /&gt;
  strukturZeiger-&amp;gt;element&lt;br /&gt;
Beide Schreibweisen sind absolut gleichbedeutend, die Klammern bei der ersteren sind notwendig.&lt;br /&gt;
&lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
:Bei der Dereferenzierung durch &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; findet keine Prüfung statt, ob der Zeiger auch auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu einer Änderung '''irgendeiner''' Speicherstelle!&lt;br /&gt;
&lt;br /&gt;
 int *z; {{comment|z ist ein Zeiger auf einen int}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.}}&lt;br /&gt;
 {{comment|z enthaelt irgendeine ungueltige Adresse!!}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|&amp;quot;Erhoehe einen Integer _irgendwo_ im Speicher um 1&amp;quot; -&amp;gt; CRASH !!!}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
&lt;br /&gt;
==Cast-Operator==&lt;br /&gt;
&lt;br /&gt;
Der Cast Operator dient dazu, den Datentyp eines Wertes zu ändern. Dafür wird einfach der neue Datentyp in Klammern vor den Wert geschrieben.&lt;br /&gt;
&lt;br /&gt;
Um zum Beispiel aus einem Float ein Integer zu machen:&lt;br /&gt;
 var  = (int) 5.60;&lt;br /&gt;
Dabei wird der Wert aber auch gerundet, und es findet somit ein Informationsverlust statt.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Umwandeln einer ganzen Zahl in eine Adresse:&lt;br /&gt;
 int * addr;&lt;br /&gt;
 addr = (int*) 0x1234;&lt;br /&gt;
Damit ist &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; an Adresse 0x1234.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
Der Cast-Operator selbst führt ''keine Konvertierung'' von Darstellungen durch, etwa die Umwandlung der ganzen Zahl 123 ein den String &amp;lt;tt&amp;gt;&amp;quot;123&amp;quot;&amp;lt;/tt&amp;gt;, der diese Zahl darstellt! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
  int main(int argc, char ** argv)&lt;br /&gt;
  {&lt;br /&gt;
        char text[] = &amp;quot;5.6&amp;quot;;&lt;br /&gt;
        int zahl = (int) text;&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, zahl);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Anfangsadresse des Strings &amp;lt;tt&amp;gt;&amp;quot;5.6&amp;quot;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Komma-Operator==&lt;br /&gt;
Mit einem &amp;lt;tt&amp;gt;,&amp;lt;/tt&amp;gt; können mehrere Ausdrücke nacheinander ausgewertet werden.&lt;br /&gt;
Die Auswertung erfolgt von links nach rechts.&lt;br /&gt;
&lt;br /&gt;
Solche Konstrukte sieht man manchmal in Abfragen wie&lt;br /&gt;
 FILE  *file;&lt;br /&gt;
 if (file = fopen (&amp;quot;foo.exe&amp;quot;, &amp;quot;r&amp;quot;), file != NULL)&lt;br /&gt;
was erst an &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; einen Wert zuweist und den &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Block nur betritt,&lt;br /&gt;
wenn &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; nicht der Nullpointer ist.&lt;br /&gt;
&lt;br /&gt;
Bequem kann das auch in einer [[#for-Schleife|for-Schleife]] sein, wenn man zwei (oder mehr) Laufvariablen hat oder so:&lt;br /&gt;
 for (i=0, j=0; i &amp;lt; 10; i++, j += 2)&lt;br /&gt;
    &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Zuweisung===&lt;br /&gt;
=== ++ und -- ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; stellen einfachere Schreibweisen dar zum Addieren bzw. Subtrahieren von&amp;amp;nbsp;1.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; (Inkrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo++; &lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo + 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; 3}}&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; (Dekrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo--;&lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo - 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; -1}}&lt;br /&gt;
&lt;br /&gt;
Die beiden Operatoren können sowohl in der Präfix-Schreibweise (vor der Variablen) als auch als Postfix-Schreibweise (hinter der Variablen) notiert werden. &lt;br /&gt;
Der Unterschied liegt darin, dass beim Präfix der Wert zuerst neu berechnet wird und die Variable dann verwendet wird. Beim Postfix wird die Variable zuerst verwendet und erst nach Auswertung des Ausdrucks, in dem sie enthalten ist, neu berechnet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 int ausgabe1, ausgabe2, var1 = 10, var2 = 10;&lt;br /&gt;
 ausgabe1 = 3 * ++var1; {{comment|ausgabe1 &amp;amp;#61; 33; var1 &amp;amp;#61; 11;}}&lt;br /&gt;
 ausgabe2 = 3 * var2++; {{comment|ausgabe2 &amp;amp;#61; 30; var2 &amp;amp;#61; 11;}}&lt;br /&gt;
&lt;br /&gt;
Für Zeiger arbeiten diese Operatoren etwas anders, siehe dazu [[#Zeiger-Arithmetik|Zeiger-Arithmetik]].&lt;br /&gt;
&lt;br /&gt;
===Bedingter Ausdruck===&lt;br /&gt;
 ({{Bedingung}}) ? {{Ausdruck|1}} : {{Ausdruck|2}}&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; erfüllt ist, dann wertet dieser Ausdruck aus zu &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt;. Ist er nicht erfüllt, dann wertet er aus zu &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 x = (x &amp;gt;= 3) ? 0 : x+1;&lt;br /&gt;
Startet man &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; mit dem Wert 0, dann nimmt es bei mehrfacher Anwendung dieser Zeile (z.B. in einer Schleife) nacheinander die folgende Werte an:&lt;br /&gt;
:&amp;lt;tt&amp;gt;1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, ...&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&lt;br /&gt;
Wie auch in der Mathematik gibt es auch in C genaue Regeln über die Abarbeitungsreihenfolge (precedence)&lt;br /&gt;
der Operatoren. Dass sich alle C-Compiler genau an diesen ANSI-Vorschlag halten, ist leider nicht sicher.&lt;br /&gt;
Neben hat auch nicht jeder Programmierer diese Regel jederzeit im Kopf. &lt;br /&gt;
Daher ist es sinnvoll, Ausdrücke durch runde Klammern eindeutig zu kennzeichnen. &lt;br /&gt;
Nebenbei stören sich Compiler nicht an überflüssigen Klammerpaaren.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Priorität ||Operator||Assoziativität&lt;br /&gt;
|-&lt;br /&gt;
  &lt;br /&gt;
|&amp;lt;tt&amp;gt;15&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ( ) [ ] -&amp;gt; . &amp;lt;/tt&amp;gt;                      ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;14&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;! ~ ++ -- + - (TYP) * &amp;amp; sizeof &amp;lt;/tt&amp;gt;    ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;13&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; * / % (Rechenoperationen) &amp;lt;/tt&amp;gt;         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;12&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; + - (binär) &amp;lt;/tt&amp;gt;                       ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;11&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;&amp;lt; &amp;gt;&amp;gt; &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;10&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt; &amp;lt;= &amp;gt; &amp;gt;= &amp;lt;/tt&amp;gt;                         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 9&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; == != &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 8&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp; (bit-AND-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 7&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ^ (bit-XOR-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 6&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; (bit-OR-Operator)&amp;lt;/tt&amp;gt;   ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 5&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp;&amp;amp; &amp;lt;/tt&amp;gt;                                ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 4&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; &amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 3&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;? : &amp;lt;/tt&amp;gt;                               ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 2&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; = += -= /= *= %= &amp;gt;&amp;gt;= &amp;lt;&amp;lt;= &amp;amp;= &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;= ^= &amp;lt;/tt&amp;gt; ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 1&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; , (Sequenz-Operator) &amp;lt;/tt&amp;gt;              ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
&lt;br /&gt;
Peter Baeumle-Courth, ANSI-C im Überblick &amp;lt;p&amp;gt;&lt;br /&gt;
W. Alex, Einführung in C/C++&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
Eine Kontrollanweisung ist eine Anweisung, die Einfluss auf den Programmfluss hat. Normalerweise werden Anweisungen so ausgeführt, wie sie in der Quelldatei stehen: Von links nach rechts (falls mehrere Anweisungen in einer Zeile stehen sollten, wovon i.A. abzuraten ist) und von oben nach unten. Mit einer Kontrollanweisung kann dieser lineare Programmfluss durchbrochen werden: Die Codeausführung kann kann abhängig von einer Bedingung gemacht werden (&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;), kann wiederholt werden (Schleife) oder an einer anderen Stelle der Funktion fortgesetzt werden (&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==if-Anweisung==&lt;br /&gt;
Mit Hilfe des if-Befehls kann man Codeteile abhängig davon einer Bedingung ausführen lassen:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
oder mit else-Teil&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 if (x &amp;gt; 100)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;gt; 100 ist: Fehlerausgabe}}&lt;br /&gt;
    printf (&amp;quot;x = %d ist zu gross fuer die Berechnung!\n&amp;quot;, x);&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;lt;&amp;amp;#61; 100 ist: Berechne Summe der Zahlen 1...x}}&lt;br /&gt;
    {{comment|Die lokale Variable x2 lebt nur innerhalb dieses alse-Blocks}}&lt;br /&gt;
    int x2 = x;&lt;br /&gt;
 &lt;br /&gt;
    for (x = 0; x2 &amp;gt; 0; x2--)&lt;br /&gt;
       x += x2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Wenn die Bedingung wahr ist (&amp;lt;tt&amp;gt;x &amp;gt; 100&amp;lt;/tt&amp;gt;), dann wird eine Meldung ausgegeben; danach ist die if-Anweisung beendet. Der else-Block wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung nicht erfüllt (&amp;lt;tt&amp;gt;x &amp;amp;le; 100&amp;lt;/tt&amp;gt;), dann wird gleich zum else-Teil gesprungen, und nach dessen Ausführung der if-Befehl beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Ein häufiger Fehler ist es, statt &amp;lt;tt&amp;gt;if (a &amp;amp;#61;&amp;amp;#61; 23)&amp;lt;/tt&amp;gt; etwas wie &amp;lt;tt&amp;gt;if (a &amp;amp;#61; 23)&amp;lt;/tt&amp;gt; zu schreiben. &lt;br /&gt;
Dann wird allerdings nicht geprüft, ob die Variable&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gleich 23 ist, sondern der Variablen&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wird der Wert 23 zugewiesen. Der Ausdruck &amp;lt;tt&amp;gt;a &amp;amp;#61; 23&amp;lt;/tt&amp;gt; hat den Wert&amp;amp;nbsp;23 und ist damit immer &amp;quot;wahr&amp;quot;! Daher ist diese if-Bedingung immer erfüllt!&lt;br /&gt;
&lt;br /&gt;
Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken sondern bestenfalls eine Warnung. Damit ist dieser Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise &amp;lt;tt&amp;gt;if (23 &amp;amp;#61;&amp;amp;#61; a)&amp;lt;/tt&amp;gt;. Wenn man dort anstatt des Vergleichsoperators '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;amp;#61;&amp;lt;/tt&amp;gt;' den Zuweisungsoperator '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;lt;/tt&amp;gt;' verwendet, spuckt der Compiler sehr wohl einen Fehler aus! Ist die Zuweisung jedoch erwünscht und eine Compiler-Warnung lästig, dann wählt man eine Schreibweise wie &amp;lt;tt&amp;gt;if ((a &amp;amp;#61; b))&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;if (a &amp;amp;#61; b, a)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist zu schreiben &amp;lt;tt&amp;gt;if (Bedingung);&amp;lt;/tt&amp;gt; Richtig muss es heissen &amp;quot;&amp;lt;tt&amp;gt;if(Bedingung)&amp;lt;/tt&amp;gt;&amp;quot; Das Semikolon im ersten Fall ist eine leere Anweisung, die im if-Falle ausgeführt wird &amp;amp;ndash; sie bleibt also ohne Resultet. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt; ein auf das Semikolon folgende Anweisung die eigentlich zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören soll wird immer ausgeführt, die sie nicht mehr zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; dazu gehört.&lt;br /&gt;
}}&lt;br /&gt;
Bei verschachtelten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Konstrukten gehört ein &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zu letzten &amp;quot;freien&amp;quot; &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;. Soll in einer &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Folge das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zum ersten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören, dann ist das so zu hinzuschreiben:&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Ohne die geschweiften Klammern um das zweite &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehörte das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; dort hinzu.&lt;br /&gt;
&lt;br /&gt;
==switch-Anweisung==&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
&lt;br /&gt;
 switch ({{Ausdruck|}}) &lt;br /&gt;
 {&lt;br /&gt;
     case konstante1:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
    &lt;br /&gt;
     case konstante2:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 &lt;br /&gt;
     {{comment|weitere case-Marken}}&lt;br /&gt;
 &lt;br /&gt;
     default:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 } {{comment|Ende von switch}} &lt;br /&gt;
&lt;br /&gt;
Der Ausdruck muss ein skalarer Typ sein, er wird in die nächste ganze Zahl gewandelt und mit den Werten hinter den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Marken verglichen. Bei einer Übereinstimmung werden alle Befehle ab dem zutreffenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; ausgeführt. Stimmt der Ausdruck mit keinem der Werte überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt falls vorhanden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der nachfolgenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;- und des &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitts werden ausgeführt, wenn die Anweisungen des &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitts nicht mit dem Befehl &amp;lt;tt&amp;gt;break;&amp;lt;/tt&amp;gt; beendet werden!&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es dürfen beliebig viele &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitte angegeben werden, pro Vergleichswert jedoch nur einer.&lt;br /&gt;
Der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ist optional. Die Reihenfolge, in der &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt; angegeben werden, ist unerheblich.&lt;br /&gt;
&lt;br /&gt;
==Schleifen==&lt;br /&gt;
Um Anweisungen mehrmals hintereinander auszuführen, benötigt man Schleifen. Diese führen Anweisungen aus, bis oder solange Bedingungen erfüllt sind.&amp;lt;br&amp;gt; &lt;br /&gt;
Wichtig ist also, ob die Bedingung '''vor''' oder '''nach''' den Schleifen-Anweisungen geprüft wird. &lt;br /&gt;
&lt;br /&gt;
===while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 while ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Die while-Schleife wird solange durchlaufen, wie die Bedingung erfüllt ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Die Anweisung kann natürlich auch ein Block sein, der aus mehreren Deklarationen und Anweisungen besteht. &lt;br /&gt;
&lt;br /&gt;
 int zahl1 = 0;&lt;br /&gt;
 int zahl2 = 1;&lt;br /&gt;
 &lt;br /&gt;
 while (zahl1 &amp;lt; 3)&lt;br /&gt;
 {&lt;br /&gt;
    zahl1 = zahl1 + 1;&lt;br /&gt;
    zahl2 = zahl2 * 2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife drei mal durchlaufen. Zu Beginn des vierten Durchlaufs ist die Bedingung nicht mehr erfüllt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
&lt;br /&gt;
===do-while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
Die do-while-Schleife wird auf jeden Fall einmal durchlaufen und dann solange wiederholt, wie die Bedingung erfüllt ist.&lt;br /&gt;
 int i = 2;&lt;br /&gt;
 &lt;br /&gt;
 do &lt;br /&gt;
 {&lt;br /&gt;
     i = i*i;   {{comment|i quadrieren}}&lt;br /&gt;
     printf (&amp;quot;i = %d\n&amp;quot;, i);&lt;br /&gt;
 }&lt;br /&gt;
 while (i &amp;lt; 20);&lt;br /&gt;
&lt;br /&gt;
Die Schleife wird durchlaufen und wiederholt, solange &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; kleiner als 20 ist. Es werden also nacheinander die Werte 2, 4 und 16 ausgegeben. Nach der Schleife hat&amp;amp;nbsp;&amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; den Wert 256.&lt;br /&gt;
&lt;br /&gt;
===for-Schleife===&lt;br /&gt;
'''Syntax:''' &lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Bei den Ausdrücken wird es sich um einen Ausdrücke mit Nebeneffekt handeln wie etwa &amp;lt;tt&amp;gt;i=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;i=i+2&amp;lt;/tt&amp;gt;. Es werden folgende Aktionen ausgeführt:&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# falls die Bedingung wahr ist, dann führe &amp;lt;tt&amp;gt;Anweisung&amp;lt;/tt&amp;gt; aus.&lt;br /&gt;
# falls die Bedingung unwahr ist, dann sprinte zu 7 (Ende).&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# gehe zu 2&lt;br /&gt;
# nächste Anweisung nach der for-Schleife&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int lauf, summe;&lt;br /&gt;
 &lt;br /&gt;
 for (lauf=1, summe=0; lauf &amp;lt;= 10; lauf += 2) &lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel ist &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; ein [[#Komma-Operator|Komma-Ausdruck]], der zwei Anweisungen kombiniert und daher sogar zwei Nebeneffente hat: er setzt &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;1 und &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;0.&lt;br /&gt;
&lt;br /&gt;
Das Äquivalent als while-Schleife:&lt;br /&gt;
&lt;br /&gt;
 int lauf  = 1;                 {{comment|Anfangswerte}}&lt;br /&gt;
 int summe = 0;&lt;br /&gt;
 &lt;br /&gt;
 while (lauf &amp;lt;= 10)             {{comment|Bedingung}}&lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
    lauf  += 2;                 {{comment|Inkrement}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; in jedem Schleifendurchlauf um die Laufvariable &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; erhöht. Da &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nacheinander die ungeraden Werte von&amp;amp;nbsp;1 bis&amp;amp;nbsp;10 annimmt, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von&amp;amp;nbsp;1 bis kleinergleich 10 gespeichert, also der Wert&amp;amp;nbsp;25. &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; hat nach der Schleife den Wert&amp;amp;nbsp;11.&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf = 1&amp;lt;/tt&amp;gt; bedeutet, dass der Variablen &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; vor dem ersten Schleifendurchlauf der Wert&amp;amp;nbsp;1 zugewiesen wird. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf &amp;lt;= 10&amp;lt;/tt&amp;gt; ist die Schleifenbedingung; ist sie nicht erfüllt, wird die Schleife beendet. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf += 2&amp;lt;/tt&amp;gt; bedeutet, dass &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nach jedem Durchlauf um&amp;amp;nbsp;2 erhöht wird.&lt;br /&gt;
&lt;br /&gt;
===continue-Anweisung===&lt;br /&gt;
Innerhalb einer Schleife darf die &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die nachfolgenden Anweisungen übersprungen werden und mit dem nächsten Schleifendurchlauf fortgesetzt wird &amp;amp;ndash; vorausgesetzt die Schleifenbedingung ist noch erfüllt. Ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; etc. stehen, wenn dieses innerhalb einer Schleife steht.&lt;br /&gt;
&lt;br /&gt;
==break-Anweisung==&lt;br /&gt;
Innerhalb einer Schleife oder eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; darf die &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die Schleifen-/Switch-Anweisung sofort verlassen wird und das Programm dahinter weiter macht. Bei mehrfach geschachtelten Schleifen wird nur die innere verlassen. Ein &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; stehen, wenn dieses innerhalb einer Schleife/Switch-Anweisung steht.&lt;br /&gt;
&lt;br /&gt;
==goto-Anweisung==&lt;br /&gt;
&lt;br /&gt;
Innerhalb ein und derselben Funktion kann mit &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; an eine andere Stelle gesprungen werden. Dazu gibt man hinter dem &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einen Bezeichner an, der dadurch als Label fungiert:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 goto {{Bezeichner}};&lt;br /&gt;
Die Bezeichner selbst steht irgendwo in der Funktion und wird dadurch zur Sprungmarke (Label), daß er von einem Doppelpunkt (und mindestens einer C-Anweisung, die auch leer sein darf) gefolgt wird.&lt;br /&gt;
&lt;br /&gt;
Das Beispiel durchsucht das 2-dimensionale &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array &amp;lt;tt&amp;gt;feld&amp;lt;/tt&amp;gt; mit den &amp;lt;tt&amp;gt;SIZE_X &amp;amp;times; SIZE_Y&amp;lt;/tt&amp;gt; Werten nach dem Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;. Wird er gefunden, dann wird die 2-fach geschachtelte Suchschleife verlassen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int x, y;&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y; y++)&lt;br /&gt;
       if (feld[x][y] == 0)&lt;br /&gt;
          goto done;&lt;br /&gt;
 {{Label|done:}};&lt;br /&gt;
&lt;br /&gt;
Der folgende Code hat die gleiche Funktion, arbeitet jedoch ohne &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int x, y;&lt;br /&gt;
 int found = 0; {{comment|FALSE}}&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X &amp;amp;&amp;amp; !found; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y &amp;amp;&amp;amp; !found; y++)&lt;br /&gt;
       found = (0 == feld[x][y]);&lt;br /&gt;
Der Nachteil der &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-losen Variante ist, daß man eine Variable, die merkt, ob das Suchziel gefunden wurde, mitschleppen und in ''jedem'' Schleifendurchlauf abtesten muss. Dies bedeutet einen höheren Programmier- und Laufzeitaufwand und ist nicht so klar formuliert wie das &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-Beispiel.&lt;br /&gt;
&lt;br /&gt;
Gleichwohl sei angemerkt, daß die Verwendung von &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einem gewissen Dogmatismus unterliegt, der sich wie folgt subsummieren liesse:&lt;br /&gt;
:''goto ist böse und sollte keinesfalls verwendet werden! Wer es dennoch tut, offenbart dadurch seinen schlechten Geschmach sowie mangelhafte C-Kenntnis.'' &amp;lt;div align=&amp;quot;right&amp;quot;&amp;gt;http://www.roboternetz.de/phpBB2/images/smiles/icon_wink.gif&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Funktionen=&lt;br /&gt;
Stellen Dir vor, Du hast eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben &amp;amp;ndash; was Dich Zeit beim Erstellen des Programms und Speicherplatz im ausführbaren Programm kostet &amp;amp;ndash; kannst Du den Code-Abschnitt in eine Funktion schreiben und diese von jeder Stelle des Programms aus verwenden. Die Hauptgründe, um Funktionen zu verwenden, sind:&lt;br /&gt;
;Wiederverwendung von Code: Mehrfach verwendete Codestücke müssen nicht mehrfach implementiert werden. Oft unterscheiden sich die Codesequenzen nur in Kleinigkeiten, die man der Funktion über Parameter mitteilen kann.&lt;br /&gt;
;Übersichtlichkeit: Ein gut gegliedertes C-Programm implementiert klar umrissene Aufgaben in einer Funktion, auch wenn diese Funktion nur einmal im Code aufgerufen wird! Dadurch bleibt der Code um die Aufrufstelle besser verständlich, und man kann auf verschiedenen &amp;quot;Ebenen&amp;quot; denken. Eine Funktion wie &amp;quot;Datei öffnen&amp;quot; kann recht komplex sein. Auf höherer Ebene interessieren die Innereien nicht mehr, man möchte sich um andere Dinge kümmern und will den Code an der Stelle garnicht sehen...&lt;br /&gt;
;Rekursive Funktionen: Eine Funktion kann sich auch selbst aufrufen. In dem Falle nennt man die Funktion ''rekursiv''. Zwar lässt sich das, was eine rekursive Funktion tut, auch mit anderen Mitteln formulieren, die keine rekursiven Funktionen brauchen, aber oft ist der rekursive Weg knackiger und klarer formulierbar als eine nicht-rekursiven Ansatz, auch wenn es etwas mehr Resourcen verbraucht.&lt;br /&gt;
;Modulare Programmierung: Funktionen können anhand ihres Aufgabenbereichs auf verschiedene C-Quellen &amp;amp;ndash; sogenannte ''Module'' &amp;amp;ndash; verteilt werden. Funktionen, die etwas mit dem USB-Bus anstellen, werden in einem anderen Modul sein als mathematische Funktionen. Dies erhöht die Übersichtlichkeit und vereinfacht die Entwicklung im Team.&lt;br /&gt;
;Bibliotheken: Standard-Funktionen wie das hier oft auftauchende &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; sind in Bibliotheken gespeichert. Wenn das eigene Programm übersetzt wird, dann müssen nicht mehr alle Standard-Funktionen übersetzt werden, sondern werden nur noch aus der Bibliothek gelesen und ihr Code zum Programm dazugelinkt. Die Bibliotheks-Funktionen wurden schon zu einem früheren Zeitpunkt compiliert und liegen in dieser compilerten Form in der Bibliothek. Das spart mächtig Entwicklungszeit. Man kann auch selbst solche Bibliotheken erstellen und in diversen Projekten wiederverwenden.&lt;br /&gt;
;Generische Programmierung: In C ist es möglich, einer Funktion eine andere Funktion zu übergeben. (Damit ist nicht gemeint, ihr deren ''Rückgabewert'' zu übergeben (was auch ginge), sondern ''die Funktion selbst'' wird als Parameter übergeben und kann aufgerufen werden.) Ein typisches Beispiel dafür sind Sortieralgorithmen. Einem Sortieralgorithmus kann es egal sein, ''was'' er sortiert. Er muss lediglich wissen, ''wie'' er das Zeug zu sortieren hat: aufsteigend, absteigend, als Zahl, in lexikographischer Ordnung, nach der Quersumme, Körper nach Oberfläche, Durchmesser, Gewicht oder Volumen... Diese Vergleichsfunktion, die für zwei Objekte entscheidet, welches davon &amp;quot;kleiner&amp;quot; ist, kann man dem Sortierer übergeben. Will er zwei Werte vergleichen, dann muss er nur die Vergleichsfunktion aufrufen, ohne zu wissen, was diese tut. Damit kann der Sortieralgorithmus unanhängig von den Objekten gehalten werden, mit denen er hantieren soll.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Definition==&lt;br /&gt;
&lt;br /&gt;
In der ''Definition'' der Funktion wird gesagt, welche Werte sie liefern kann, wie sie heisst (Bezeichner) und wieviele und welche Parameter sie hat. Danach folgt ihre Implementierung:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}} ({{Parameterliste}})&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 &lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
Für Funktionen, die keinen Wert zurückliefern, gibt es den speziellen Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der besagt, daß die Funktion nichts zurückgibt. Die einfachste denkbare Funktion ist eine solch void-Funktion. Sie bekommt keine Parameter, gibt nicht zurück und ihr Body ist leer:&lt;br /&gt;
 void dummy()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==return-Anweisung==&lt;br /&gt;
An jeder Stelle des Programmflusses einer Funktion kann diese mit &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; beendet werden.&lt;br /&gt;
&lt;br /&gt;
'''bei void-Funktionen:'''&lt;br /&gt;
 return;&lt;br /&gt;
'''Funktionen mit Rückgabe-Wert:'''&lt;br /&gt;
 return {{Ausdruck|}};&lt;br /&gt;
Die zweite Variante gibt an, welcher Wert zurückgegeben wird.&lt;br /&gt;
 int main (int argc, char * argv[])&lt;br /&gt;
 {&lt;br /&gt;
    if (argc &amp;lt; 2)&lt;br /&gt;
       return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
Falls die letzte Anweisung einer void-Funktion ein &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; ist, kann es auch weggelassen werden wie oben bei der Funktion &amp;lt;tt&amp;gt;dummy&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Aufruf==&lt;br /&gt;
Um die Funktion aufzurufen gibt man ihren Namen an, gefolgt von den durch Komma getrennten Argumenten in runden Klammern wie im Beispiel unten das&lt;br /&gt;
 quadrat (5) &lt;br /&gt;
Da &amp;lt;tt&amp;gt;quadrat&amp;lt;/tt&amp;gt; einen Wert liefert, kann man damit weiter rechnen wie mit einem normalen Ausdruck:&lt;br /&gt;
 if (quadrat (a) + quadrat (b) == quadrat (c))&lt;br /&gt;
    c = quadrat (quadrat (a)); {{comment|c &amp;amp;#61; a hoch 4}}&lt;br /&gt;
&lt;br /&gt;
;Ein Hinweis am Rande: &lt;br /&gt;
Der Name einer Funktion ohne die beiden runden Klammern ist der Pointer/Zeiger auf ihren Anfang.&lt;br /&gt;
Damit kann ein Funktionsname überall dort verwendet werden, wo Pointer/Zeiger &lt;br /&gt;
zulässig sind. Insbesondere kann er als Argument einer weiteren Funktion dienen. &lt;br /&gt;
&lt;br /&gt;
'''Quelle:'''&lt;br /&gt;
W. Alex, Einführung in C/C++&lt;br /&gt;
&lt;br /&gt;
==Rekursive Funktionen==&lt;br /&gt;
Eine Funktion die sich selbst &amp;amp;ndash; möglicheweise auch über andere Zwischenfunktionen &amp;amp;ndash; wieder selbst aufruft, wird als ''rekursive Funktion'' bezeichnet. In der Definition ist nichts besonderes zu beachten. Ist die Verschachtelungstiefe im laufenden Programm zu tief, dann gibt das natürlich Probleme, aber das gilt bei tief verschachtelten 'normalen' Funktionen abenso...&lt;br /&gt;
&lt;br /&gt;
Das Beispiel berechnet den Größten Gemeinsamen Teiler zweier Zahlen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int ggT (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
     if (0 == a)&lt;br /&gt;
        return b;&lt;br /&gt;
 &lt;br /&gt;
    return ggT (b % a, a);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Ein komplettes kleines Programm:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int quadrat (int param1)&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  zahl = param1 * param1;&lt;br /&gt;
  return zahl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl, ergebnis;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Bitte Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = quadrat (zahl);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, zahl, ergebnis);&lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, 5, quadrat (5));&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur ausserhalb von Blöcken. Geschachtelte Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen beim Aufruf die Klammern angeben werden:&lt;br /&gt;
 dummy();&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Prototypen==&lt;br /&gt;
Wie oben erwähnt, kann ein Unterprogramm an jeder beliebigen Stelle im Programm stehen. Damit ist jedoch eine Bedingung verknüpft: Das Unterprogramm muß in der Datei oberhalb des ersten Aufrufes definiert worden sein. Wenn Sie ein Unterprogramm in Zeile 10 zum ersten mal aufrufen, müssen Sie die Deklaration davor erledigt haben. Verstanden?&lt;br /&gt;
Um dies zu erreichen, gibt es zwei Möglichkeiten: &lt;br /&gt;
&lt;br /&gt;
Entweder Sie schreiben alle Unterprogramme vor &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; in die Datei. Dies muß jedoch wiederum so geschehen, dass Funktionen zum Zeitpunkt ihres Aufrufes bereits bekannt sind! &lt;br /&gt;
Wo dies nicht möglich ist (z.B. sich gegenseitig aufrufende Unterprogramme), oder wenn Sie das stört, müssen Sie Prototypen verwenden. &lt;br /&gt;
Wie definiert man nun Prototypen? Sie kopieren einfach die erste Zeile des Unterprogrammes (z.B. &amp;quot;&amp;lt;tt&amp;gt;void ausgeben (int zahl)&amp;lt;/tt&amp;gt;&amp;quot;), fügen einen Strichpunkt&amp;amp;nbsp;&amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;an und fügen es an einer geeigneten Stelle ein (so, dass alle Aufrufe später in der Datei kommen). &lt;br /&gt;
Solche Definitionen stehen gewöhnlich am Anfang der Quelldatei oder in einer Header-Datei, die eingebunden wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl);  /* Der Prototyp */&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
   ausgeben (12);&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl)   /* Die eigentliche Prozedur */&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Ausgabe: %d\n&amp;quot;, zahl);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Parameterübergabe==&lt;br /&gt;
&lt;br /&gt;
Alle Werte, die an Prozeduren und Funktionen übergeben werden, werden grundsätzlich '''kopiert'''.&lt;br /&gt;
Das hat folgende Auswirkungen:&lt;br /&gt;
&lt;br /&gt;
# Änderungen an einem Parameter in einer Funktion erscheinen ''nicht'' beim Aufrufer!&lt;br /&gt;
# Möchte man, dass eine Funktion einen Wert trotzdem dauerhaft ändern soll, so muss die Adresse des Wertes via [[#Zeiger|Zeiger]] übergeben werden.&lt;br /&gt;
# Werden [[#Strukturen|Strukturen]] übergeben, so wird von ihnen eine Kopie erstellt, was bei großen Strukturen viel Zeit und Arbeitsspeicher kostet. Deshalb wird häufig nur die Adresse von Strukturen übergeben, da die Adresse viel schneller und platzsparender als die Struktur selbst kopiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele:'''&lt;br /&gt;
 void erhoehe (int x)&lt;br /&gt;
 {&lt;br /&gt;
    x = x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe(a);&lt;br /&gt;
    {{comment|a ist immer noch 0}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Beim Aufruf von &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; wird eine Kopie des Wertes von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; (im Beispiel also 0) erstellt und der Prozedur als Parameter &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; übergeben. Weil dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat dies keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|erhoehe den Wert an der Adresse x um eins}}&lt;br /&gt;
    *x = *x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe (&amp;amp;a);&lt;br /&gt;
    {{comment|a ist jetzt 1}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Jetzt wird im Hauptprogramm mittels [[#Adress-Operator und Dereferenzierung|Adress-Operator]] &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; die Speicheradresse von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; bestimmt. Dann wird eine ''Kopie der Adresse'' an das Unterprogramm &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; übergeben. Jetzt kennt das Unterprogramm die&lt;br /&gt;
Adresse des Originals &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und kann direkt mit dem Inhalts-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&lt;br /&gt;
'''Besonderheit bei Feldern'''&lt;br /&gt;
&lt;br /&gt;
Bei der Übergabe von [[#Felder|Feldern]] gibt es eine Besonderheit. Schreibt man nämlich den Namen eines Feldes, so ist das nichts anderes als die '''Speicheradresse des ersten Elements'''.&lt;br /&gt;
Bei der Übergabe eines Feldes wird also eine Kopie der Startadresse übergeben. Somit kann das Unterprogramm auf den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 void erhoehe (int x[])&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
   int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
   erhoehe (a);&lt;br /&gt;
   {{comment|a hat jetzt folgenden Inhalte: 11, 23, 35}}&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Dass die Übergabe einer Adresse erfolgt, sieht man an folgendem Beispiel, das von der Funktionsweise '''absolut identisch''' mit dem vorhergehenden ist:&lt;br /&gt;
&lt;br /&gt;
 {{comment|Bei Parametern gibt es keinen Unterschied zwischen Zeiger und Feld}}&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
    int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
    erhoehe (a);&lt;br /&gt;
 &lt;br /&gt;
    {{comment|a hat jetzt folgenden Inhalt: 11, 23, 35}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
Die Länge des Feldes wird nicht automatisch übergeben. Dafür ist ggf. ein zusätzlicher Parameter notwendig.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Variable Argumentanzahl==&lt;br /&gt;
== Funktionen indirekt aufrufen ==&lt;br /&gt;
Siehe [[#Zeiger auf Funktionen|Zeiger auf Funktionen]]&lt;br /&gt;
&lt;br /&gt;
=Zeiger II=&lt;br /&gt;
&lt;br /&gt;
Zeiger haben wir bereits weiter oben kennen gelernt. Zeiger sind ein zentrales Konzept in C und sollen hier etwas eingehender behandelt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger-Arithmetik==&lt;br /&gt;
In C kann man den Wert eines Zeigers verändern. Betrachten wir dazu die Funktion &amp;lt;tt&amp;gt;suche_0&amp;lt;/tt&amp;gt;, die einen Zeiger auf einen &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; erhält. Die Funktion soll ab der gegebenen Adresse nach dem ersten long-Wert suchen, der 0 ist, und dessen Adresse zurückgeben:&lt;br /&gt;
 long * suche_0 (long * addr)&lt;br /&gt;
 {&lt;br /&gt;
    while (*addr != 0)&lt;br /&gt;
       addr = addr + 1;&lt;br /&gt;
 &lt;br /&gt;
    return addr;&lt;br /&gt;
 }&lt;br /&gt;
In der Bedingung der while-Schleife wird der Inhalt an der Speicherstelle &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf 0 getestet. Ist der Wert 0, dann wird die Schleife beendet und die Adresse zurückgeliefert. Ist der Wert ungleich 0, dann wird &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf den nächste long gesetzt, &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; also um 4 Bytes weitergezählt. &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ist ja ein Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, und ein &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; ist 4 Bytes lang.&lt;br /&gt;
&lt;br /&gt;
Die Bedeutung von&lt;br /&gt;
 address + n&lt;br /&gt;
ist also, die Adresse um das &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;-fache der Größe des Typs, auf den &amp;lt;tt&amp;gt;address&amp;lt;/tt&amp;gt; zeigt, zu erhöhen. Dabei ist &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; eine ganze Zahl und darf auch negativ sein.&lt;br /&gt;
&lt;br /&gt;
Hier noch ein Beispiel einer Funktion, die nach einer Person mit einer bestimmten ID sucht (für die Definition von &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; siehe [[#Strukturen|Strukturen]]). Der Parameter &amp;lt;tt&amp;gt;person&amp;lt;/tt&amp;gt; ist dabei ein Array von Strukturen. Eine Person mit der gesuchten ID muss existieren, ansonsten hat die Suchfunktion kein definiertes Verhalten.&lt;br /&gt;
 {{comment|Sucht nach einer Person mit der ID person_id}}&lt;br /&gt;
 struct Person * &lt;br /&gt;
 suche_person_id (struct Person * person, int person_id)&lt;br /&gt;
 {&lt;br /&gt;
    while (person-&amp;gt;id != person_id)&lt;br /&gt;
       person++;&lt;br /&gt;
 &lt;br /&gt;
    return person;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:1em; padding:1em; border:solid 2px #FF0040;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- Vorlage:FarbigerRahmen funzt hier net --&amp;gt;&lt;br /&gt;
Beachte, daß es nicht sinnvoll ist, zwei Zeiger zu addieren oder zu multiplizieren. Ausserdem ist das &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt; der Zeiger-Arithmetik nicht kommutativ. Eine Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, der an Adresse 1 im Speicher zeigt, wird man schreiben als&lt;br /&gt;
 (long *) 1&lt;br /&gt;
Addiert man darauf eine ganze Zahl, dann haben die entstehenden Ausdrücke unterschiedliche Werte:&lt;br /&gt;
 (long *) 1 + 2    {{comment|zeigt zu Adresse 9}}&lt;br /&gt;
 (long *) 2 + 1    {{comment|zeigt zu Adresse 6}}&lt;br /&gt;
 (long *) (1 + 2)  {{comment|zeigt zu Adresse 3}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==void-Pointer==&lt;br /&gt;
Eine besondere Art von Zeiger ist der void-Pointer&lt;br /&gt;
 void * addr;&lt;br /&gt;
Ein void-Pointer ist ein &amp;quot;Zeiger auf irgendwas&amp;quot;, dementsprechend kann er nicht dereferenziert werden, Anwenden von &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf einen solchen Zeiger gibt also einen Fehler. Ausserdem ist es nicht möglich, mit einem void-Pointer Zeigerarithmetik zu machen, weil er nicht auf eine definierte Art von Objekt zeigt. Der Vorteil eines void-Pointers ist, daß er jede Art von Zeiger aufnehmen kann.&lt;br /&gt;
&lt;br /&gt;
Dazu betrachten wir die Funktion &amp;lt;tt&amp;gt;send_buf&amp;lt;/tt&amp;gt;, die eine Adresse erhält und ab dieser Adresse &amp;lt;tt&amp;gt;num&amp;lt;/tt&amp;gt; Bytes versenden soll. Wir könnten die Funktion so schreiben:&lt;br /&gt;
 void send_buf (unsigned char * buf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   ...&lt;br /&gt;
Das ist jedoch hässlich, wenn wir damit etwas anderes verschicken wollen als &amp;lt;tt&amp;gt; unsigned char&amp;lt;/tt&amp;gt;, etwa eine Struktur wie &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; (vom Typ &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;):&lt;br /&gt;
 send_buf ((unsigned char*) &amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
Ohne den Cast der Adresse von &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; zu einem Zeiger auf &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt; bekommt man eine Warnung oder gar einen Compilerfehler.&lt;br /&gt;
Dieses Zeiger gecaste ist mühsam und hässlich, es muss bei jedem Aufruf der Funktion explizit hingeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Besser ist es, den ersten Parameter der Funktion als void-Pointer zu definieren und den Cast in der Funktion zu machen:&lt;br /&gt;
 void send_buf (void * vbuf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   unsigned char *buf = (unsigned char*) vbuf;&lt;br /&gt;
   ...&lt;br /&gt;
Durch den Cast in der Funktion kann auf den Inhalt des Zeigers zugegriffen werden. Man muss nur festlegen, ''wie'' man zugreifen will, nämlich als &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Der Aufruf kann jetzt ohne Pointer-Cast erfolgen: &lt;br /&gt;
 send_buf (&amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
&lt;br /&gt;
==Null-Pointer==&lt;br /&gt;
==Zeiger als Parameter==&lt;br /&gt;
Wenn Sie ein Unterprogramm aufrufen, können Sie diesem Parameter übergeben, aber keine Werte zurückgekommen (außer den Funktionswert bei Funktionen). Dies hat einen guten Grund: beim Aufruf werden nicht die aufgerufenen Parameter benutzt, sondern es werden deren Werte in neue Variablen kopiert. Diese Variablen werden am Ende des Unterprogrammes &amp;quot;zerstört&amp;quot;, ohne ihre Werte an die aufrufenden Parameter zu übergeben. Jede Veränderung eines Parameters hat daher keine Auswirkung auf den Parameter.&lt;br /&gt;
&lt;br /&gt;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der C-Compiler legt dann immer noch Kopien an. In dieser Kopie steht aber kein Wert, sondern die Adresse einer Varaiblen. Und auf diese können Sie dann zugreifen. Denken Sie nur an &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; &amp;amp;ndash; da übergeben Sie ja auch die Adresse einer Variablen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void erhoehe (int *zeiger)&lt;br /&gt;
{&lt;br /&gt;
  *zeiger = 1 + *zeiger;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  erhoehe (&amp;amp;zahl);&lt;br /&gt;
  printf (&amp;quot;\nDie erhoehte Zahl lautet: %d\n&amp;quot;, zahl);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Zeiger auf Funktionen==&lt;br /&gt;
&lt;br /&gt;
Stell dir vor, du willst einen Sortieralgorithmus wie Bubble-Sort oder Quick-Sort oder wie sie alle heissen implementieren. Für den Sortieralgorithmus ist eigentlich egal, ''was'' er zu sortieren hat. Ihm ist es egal, ob er Zahlen aufwärts sortieren soll oder Strings in lexikographischer Reihenfolge, ob Objekte nach Größe oder Gewicht, Personen nach Alter oder Adressen nach Postleitzahl. Das einzige, was der Algorithmus wissen muss, ist ''wie'' er zwei Objekte zu vergleichen hat und wann eines davon &amp;quot;kleiner&amp;quot; (im Sinne der Ordnung, nach der sortiert werden soll) ist. &lt;br /&gt;
&lt;br /&gt;
Eine einfache Sortierfunktion, die nur zwei Zahlen sortiert, könnte man also so schreiben: &lt;br /&gt;
 {{comment|Sortiert ein Array von 2 int-Zeigern nach den Inhalten &lt;br /&gt;
  * an den Zeiger-Adressen}}&lt;br /&gt;
 void sort2_a (int * p[])&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Inhalte vergleichen...}}&lt;br /&gt;
    if (*p[0] &amp;gt; *p[1])&lt;br /&gt;
    {&lt;br /&gt;
       {{comment|... und ggf. Dreieckstausch der 2 Zeiger}}&lt;br /&gt;
       int * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Die Funktion bekommt ein Array der Länge&amp;amp;nbsp;2. In diesem Array stehen Zeiger auf die zu sortierenden Zahlen. Ein Array mit Zeigern zu verwenden und nicht ein Array von &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; scheint recht umständlich, und das ist es hier auch. Aber stell dir vor, du willst Strukturen wie &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; sortieren. Das Tauschen zweier Strukturen würde bedeuten, ihre kompletten Inhalte umzukopieren! Das wäre sehr aufwändig. Viel einfacher ist das Kopieren, wenn nur die Adressen zu kopieren sind.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; könnte dann so aussehen:&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void sortiere (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|p[] enthält 2 int-Zeiger: die Adressen von a und b}}&lt;br /&gt;
    int * p[2];&lt;br /&gt;
    p[0] = &amp;amp;a; &lt;br /&gt;
    p[1] = &amp;amp;b; &lt;br /&gt;
 &lt;br /&gt;
    {{comment|Sortiere die Zeiger}} &lt;br /&gt;
    sort2_a (p);&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Sortiert: %d, %d\n&amp;quot;, *p[0], *p[1]);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Für den nächsten Schritt überlegen wir uns, daß das Array in &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; ebensogut void-Pointer enthalten kann. Die einzige Stelle, an der wir auf die endgültigen int-Objekte zugreifen, ist der Vergleich. Diesen Vergleich lagern wir in die Funktion &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; aus:&lt;br /&gt;
 {{comment|Bekommt zwei void-Pointer und vergleicht die Inhalte.&lt;br /&gt;
  * Liefert 0 bei Gleichheit,&lt;br /&gt;
  * -1 wenn der erste Wert kleiner ist als der zweite und&lt;br /&gt;
  * 1  wenn der erste Wert größer ist als der zweite}}&lt;br /&gt;
 int compare_int (void * p0, void * p1)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Um über die Zeiger zugreifen zu können müssen wir diese&lt;br /&gt;
     * erst zu int-Zeigern casten}}&lt;br /&gt;
    int a0 = * (int*) p0;&lt;br /&gt;
    int a1 = * (int*) p1;&lt;br /&gt;
 &lt;br /&gt;
    if (a0 &amp;gt; a1)  return  1;&lt;br /&gt;
    if (a0 &amp;lt; a1)  return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void sort2_b (void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare_int (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Ein Aufruf von &amp;lt;tt&amp;gt;sort2_b&amp;lt;/tt&amp;gt; sieht dann genauso aus wie ein Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt definieren wir uns den neuen Datentyp &amp;lt;tt&amp;gt;comparator_t&amp;lt;/tt&amp;gt;. Dieser ist ein Zeiger auf eine Funktion, die zwei void-Pointer erhält und einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; zurückliefert, also analog arbeitet zu &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; von oben. &lt;br /&gt;
&lt;br /&gt;
Unsere Sortierfunktion bekommt nun neben dem zu sortierenden Zeiger-Array auch eine Vergleichsfunktion &amp;lt;tt&amp;gt;compare&amp;lt;/tt&amp;gt; mitgeliefert, die sie aufruft, wenn sie zwei Objekte vergleichen will&lt;br /&gt;
 {{comment|comparator_t sind Zeiger auf Funktionen, die 2 void-Pointer&lt;br /&gt;
  * erhalten und einen int zurückliefern}}&lt;br /&gt;
 typedef int (*comparator_t) (void*, void*);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Der Sortierer bekommt einen Funktionszeiger auf den Vergleicher.&lt;br /&gt;
  * Der Aufruf vom compare geht so als wäre es eine &amp;quot;normale&amp;quot; Funktion&lt;br /&gt;
  * (ist es im Endeffekt ja auch)}}&lt;br /&gt;
 void sort2_c (comparator_t compare, void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Bei einem Aufruf von &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; muss man dann einen Komparator mit angeben. In einem Beispiel analog zu &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; von oben ist das:&lt;br /&gt;
 sort2_c (compare_int, p);&lt;br /&gt;
Um zwei Strings lexikographisch zu sortieren nehmen wie die Standard-Funktion &amp;lt;tt&amp;gt;strcmp&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void foo()&lt;br /&gt;
 {&lt;br /&gt;
    char * worte[] = { &amp;quot;Wort1&amp;quot;, &amp;quot;Wort2&amp;quot; };&lt;br /&gt;
 &lt;br /&gt;
    sort2_c ((comparator_t) strcmp, (void**) worte);&lt;br /&gt;
 }&lt;br /&gt;
Die Casts sind hier erforderlich. Alternativ könnte man &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; mit reinen void-Pointern versorgen und diese dann dort umcasten.&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
&lt;br /&gt;
Die Syntax zur Definition/Deklaration von Funktionszeigern ist etwas verzwackt. Zur Verdeutlichung ein paar Beispiele. Dabei legt das linke &amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt; jeweils den Return-Typ fest.&lt;br /&gt;
 {{comment|definiert einen neuen Funktionszeiger-Typ}}&lt;br /&gt;
 typedef {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert einen Funktionszeiger}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert ein Array von Funktionszeigern (mit Initializer)}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}[]) ({{type}}, {{type}}, ...) = { wert1, wert2, ... };&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer}}&lt;br /&gt;
 ({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer und ruft die Funktion auf}}&lt;br /&gt;
 (({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}) (arg1, arg2, ...);&lt;br /&gt;
&lt;br /&gt;
=Standard-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==String-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===strcpy===&lt;br /&gt;
Bei vielen Compilern können sie einem String nicht direkt einen Wert (Text) zuweisen. Dazu müssen Sie dann die Prozedur strcpy() benutzen. Diese erwartet als ersten Parameter den Namen einer String-Variablen (ohne eckige Klammern) und als zweiten Parameter den eines (anderen) Strings. Letzterer kann auch ein in doppelten Hochkommas (&amp;quot;) eingeschlossener Text sein. Die Funktion fügt am Ende automatisch ein 0-Zeichen ein. Um diese Funktion nutzen zu können, müssen Sie die Datei string.h includieren! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri1[21], eingabe[21];&lt;br /&gt;
&lt;br /&gt;
  strcpy (stri1, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Der 1. String: %s\n&amp;quot;, stri1);&lt;br /&gt;
  printf (&amp;quot;Bitte geben Sie maximal 20 Zeichen ein: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%s&amp;quot;, eingabe);&lt;br /&gt;
  strcpy (stri1, eingabe);&lt;br /&gt;
  printf (&amp;quot;\n%s = %s&amp;quot;, stri1, eingabe);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis:''' &lt;br /&gt;
Da ein String, wie jedes Feld, eigentlich ein Zeiger ist, dürfen Sie kein &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; bei &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; angeben!&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
Es werden zwei gleich große Strings definiert: &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;eingabe&amp;lt;/tt&amp;gt;, mit je 20 &amp;quot;nutzbaren&amp;quot; Zeichen. &lt;br /&gt;
In &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; wird die Zeichenkette &amp;lt;tt&amp;gt;&amp;quot;hallo&amp;quot;&amp;lt;/tt&amp;gt; hineinkopiert. Das 0-Zeichen am Ende wird automatisch angefügt. &lt;br /&gt;
Der String wird ausgegeben. Als neues &amp;quot;Sonderzeichen&amp;quot; kommt &amp;lt;tt&amp;gt;%s&amp;lt;/tt&amp;gt; ins Spiel. Es hat die gleiche Aufgabe wie &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt;, nur für Strings. &lt;br /&gt;
Sie werden gebeten, eine String einzugeben. &lt;br /&gt;
Dieser String wird danach in die Variable &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; kopiert. &lt;br /&gt;
Beide Strings, die ja nun die gleiche Zeichenkette enthalten, werden ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===strlen===&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;strlen&amp;lt;/tt&amp;gt;, die als Parameter eine String-Variable erwartet, liefert die Länge diese Strings zurück. Sie werden jetzt vermutlich sagen: &amp;quot;Das ist doch klar, wie lang der String ist. Ich habe es ja bei der Deklaratin angegeben&amp;quot;. Das stimmt schon, aber denken Sie noch einmal an die null-terminierten Strings. Das 0-Zeichen steht am Ende des Strings (am Ende der gültigen Zeichenfolge), aber nicht unbedingt am Ende des reservierten Speicherplatzes. Haben Sie eine Variable &amp;quot;char Variable[21];&amp;quot;, und ihr den Wert &amp;quot;hallo&amp;quot; zugewiesen, dann steht das null-Zeichen in Variable[5]. Der &amp;quot;gültige&amp;quot; String ist also 5 Zeichen (0-4) lang. Und genau das (5) würde strlen zurück liefern. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri[21];&lt;br /&gt;
  &lt;br /&gt;
  strcpy (stri, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
  printf (&amp;quot;Der String ist %d Zeichen lang&amp;quot;, strlen (stri));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird vor allem gebraucht, wenn Sie direkt auf den String zugreifen, mittels &amp;lt;tt&amp;gt;stri[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;stri[1]&amp;lt;/tt&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
==Ein- und Ausgabe-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===Bildschirm-Ausgabe===&lt;br /&gt;
Bisher war das Tutorial trotz aller Beispiele reine Theorie. Sie konnten zwar Programme schreiben, aber die Funktion nicht testen. Hier lernen Sie nun, wie Sie etwas am Bildschirm ausgeben.&lt;br /&gt;
&lt;br /&gt;
Die dazu notwendige Funktione heisst &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (das '&amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt;' ist kein Fehler!). Diese Anweisung gibt die ihr übergebenen Parameter auf das Standard-Ausgabegerät aus, in der Regel also auf den Bildschirm. Sie kann beliebig viele Parameter übernehmen. Es müssen jedoch Standard-Datentypen (z.B. &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;...) sein! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
    int zahl1 = 12;&lt;br /&gt;
    char zeichen1 = 'A';&lt;br /&gt;
    &lt;br /&gt;
    printf (&amp;quot;Das ist Text, und er wird als solcher ausgegeben. \n&amp;quot;);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zahl1' ist: %d \n&amp;quot;, zahl1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %c \n&amp;quot;, zeichen1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %d \n&amp;quot;, zeichen1);&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt Text aus. Das Zeichen am Ende (&amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;) bedeutet &amp;quot;New Line&amp;quot;, es bewegt den Cursor an den Anfang der nächsten Zeile. &lt;br /&gt;
&lt;br /&gt;
Der zweite &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt auch Text aus, am Ende befindet sich wieder das &amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;, um einen Zeilenvorschub zu erreichen. Das &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; wird vom Compiler durch den ersten Parameter ersetzt, der nach dem Text angegeben wird. In diesem Fall wird &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; also durch den Wert der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ersetzt. Das &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; im &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; bedeutet &amp;quot;Dezimalzahl&amp;quot;, der Computer gibt also eine ganze Zahl aus. &lt;br /&gt;
&lt;br /&gt;
In der dritten Ausgabe wird ein Zeichen ausgegeben. Diesmal bedeutet &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; &amp;quot;char&amp;quot; (Zeichen). Es wird also &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; durch ein &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt; ersetzt, denn die Variable &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; wird als Character interpretiert. &lt;br /&gt;
&lt;br /&gt;
Die letzte Ausgabe interpretiert den Inhalt von &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; als Zahl, und gibt dager den ASCII-Wert von &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, also 65 aus. Das ist ein typisches Beispiel für das mögliche unterschiedliche Interpretieren einer  Variablen!&lt;br /&gt;
&lt;br /&gt;
===Tastatur-Eingabe===&lt;br /&gt;
&lt;br /&gt;
Um ein &amp;quot;gscheites&amp;quot; Programm schreiben zu können, muß man wissen, wie der Benutzer über die Tastatur Befehle eingeben kann. Die dafür notwendigen Funktionen stelle ich in diesem Kapitel vor.&lt;br /&gt;
Die wichtigste Funktion ist &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt;. Er liest Daten von der Tastatur. Die Syntax entspricht derer von &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int  zahl1;&lt;br /&gt;
char zeichen1;&lt;br /&gt;
&lt;br /&gt;
printf (&amp;quot;Bitte geben Sie eine Zahl ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl1);&lt;br /&gt;
printf (&amp;quot;Geben Sie einen Zeichen ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%c&amp;quot;, &amp;amp;zeichen1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Programm gibt eine Eingabeaufforderung aus. Dann erwartet es vom Benutzer, daß er eine Zahl eingibt, die mit [ENTER] bestätigt wird. Dieser Wert wird in &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; abgespeichert. Danach erfolgt wiederum eine Aufforderung zur Eingabe, diesmal eines einzelnen Zeichens. Dieses kann man nun eingeben und ebenfalls mit [ENTER] bestätigen.&lt;br /&gt;
&lt;br /&gt;
Macht man keine dem Datentyp der erwarteten Variable entsprechende Eingabe, dann bricht das Programm mit einer Fehlermeldung ab (wenn man z.B. &amp;quot;1_T2&amp;quot; eingibt, wenn eine Zahl erwartet wird)!&lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; vor den Parametern ist notwendig. Warum, das erfahren Sie im Kapitel &amp;quot;Unterprogramme&amp;quot;. Für die Profis eine Kurz-Erklärung: Das Unterprogramm &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; bekommt zwar einen Wert übergeben, kann aber keinen zurückliefern (&amp;quot;call by value&amp;quot;). Daher wird kein Wert, sondern ein Zeiger auf eine Variable übergeben. Mit dem &amp;amp; Zeichen bekommen Sie die Adresse einer Variablen (&amp;quot;call by reference&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=Parameter von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;=&lt;br /&gt;
Das Unterprogramm &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; kann, wie jede andere Funktion, Parameter besitzen. Doch keine selbst gewählten, sondern nur bestimmte. Doch warum braucht main Parameter? Denken Sie einmal an alle Betriebssystembefehle:&lt;br /&gt;
&amp;lt;tt&amp;gt;dir *.exe &amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;copy *.* a:&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;ls -la &amp;lt;/tt&amp;gt;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;&amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen!&lt;br /&gt;
&lt;br /&gt;
=Kurzreferenz=&lt;br /&gt;
==Syntax-Bausteine==&lt;br /&gt;
&lt;br /&gt;
Die Erklärung des Aufbaus von C-Befehlen erfolgt neben einfachen Beispielen auch durch ihren prinzipellen Aufbau. In diesen Syntax-Beschreibungen finden sich immer wieder die gleichen Bausteine, die hier näher erklärt werden sollen. Falls die solch ein Syntax-Baustein begegnet, kannst Du ihn anclicken und kommst dann zu seiner Erläuterung. &lt;br /&gt;
&lt;br /&gt;
In den Beispielen selbst gehören auch die spitzen Klammern zu dem Baustein (was daran zu erkennen ist, daß auch die Klammern eingefärbt sind). Die Klammern dürfen in einem konkreten C-Programm daher nicht eingetippt werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bezeichner&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Bezeichner in C dienen dazu, Variablen zu identifizieren und ihnen sprechende Namen zu geben, um die Quelle lesbarer zu machen. Man braucht Bezeichner auch, um selbstdefinierte Datentypen zu benennen und zum Benennen von Struct- und Union-Komponenten sowie als Namen für Funktionen und Sprungmarken (Labels).&lt;br /&gt;
&lt;br /&gt;
Bezeichner dürfen aus den Kleinbuchstaben &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;z&amp;lt;/tt&amp;gt;, den Großbuchstaben &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;Z&amp;lt;/tt&amp;gt;, dem Unterstrich&amp;amp;nbsp;&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt; und den Ziffern &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;9&amp;lt;/tt&amp;gt; aufgebaut werden, wobei an erster Stelle jedoch keine Ziffer stehen darf.&lt;br /&gt;
&lt;br /&gt;
Es wird zwischen Groß- und Kleinschreibung unterschieden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Ausdruck in C ist ein Konstrukt, das einen Wert hat. Ob dieser Wert eine ganze Zahl ist, eine Kommazahl oder ein Zeiger, etc. ist dabei egal. Die einfachsten Ausdrücke sind Konstanten wie&lt;br /&gt;
 2&lt;br /&gt;
oder Variablen wie&lt;br /&gt;
 ein_zahl&lt;br /&gt;
Mehrere Ausdrücke können durch [[#Liste der Operatoren|Operatoren]] zu komplexeren Ausdrücken kombiniert werden, etwa&lt;br /&gt;
 eine_zahl + andere_zahl == 2&lt;br /&gt;
oder &lt;br /&gt;
 eine_zahl = 2&lt;br /&gt;
Letzterer hat den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; und den Nebeneffekt, daß er diesen Wert an &amp;lt;tt&amp;gt;eine_zahl&amp;lt;/tt&amp;gt; zuweist.&lt;br /&gt;
&lt;br /&gt;
Auch der Aufruf einer Funktion, die einen Rückgabewert liefert, ist ein Ausdruck:&lt;br /&gt;
 sin (1.2)&lt;br /&gt;
und kann zum Aufbau komplexerer Ausdrüche verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bedingung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Bedingung ist ein Ausdruck, bei der nur interessiert, ob dieser zu&amp;amp;nbsp;0 (unwahr) auswertet oder zu ungleich&amp;amp;nbsp;0 (wahr). Solche Ausdrücke findet man in if-Anweisungen, in Schleifenbedingungen und bedingten Zuweisungen&lt;br /&gt;
 (ein_wert &amp;lt; 2) || (ein_wert &amp;gt; 40)&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Lvalue ist ein Ausdruck, dem etwas zugewiesen werden kann. Der Name ''Lvalue'' kommt aus dem Englischen. Das ''L'' steht abkürzend für left. Ein Lvalue ist damit ein Ausdruck, der auf der linken Seite eine Zuweisung in C stehen darf. Das &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; in den folgenden Beispiel-Ausdrücken muss ein Lvalue sein:&lt;br /&gt;
 x = y-1&lt;br /&gt;
&lt;br /&gt;
 x++&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Konstante&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Konstante ist ein Ausdruck, dessen Wert dem Compiler bekannt ist. Beispiele für Konstanten sind etwa&lt;br /&gt;
 7&lt;br /&gt;
 'B'&lt;br /&gt;
 -13.98e12&lt;br /&gt;
 1+(2*3)&lt;br /&gt;
und die Werte von [[#Enum|Enum]]s. &lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; aus dem folgenden Codestück definiert jedoch keine Konstante in diesem Sinne&lt;br /&gt;
 const double Pi = 3.14159256;&lt;br /&gt;
denn in einem anderen Quellmodul könnte durch die Deklaration&lt;br /&gt;
 extern const double Pi;&lt;br /&gt;
das Symbol &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; bekannt sein, ohne daß sein Wert bekannt ist!&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Adresse&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Adresse ist ein Ausdruck, der einen Speicherort (physikalisch oder virtuell) halten kann. Adressen erhält man dadurch, daß man einem Bezeichner den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt;voranstellt, Adressen durch Arithmetik berechnet oder Zahlen zu Adressen castet. Folgende Ausdrücke sind Adressen (eine sinnvolle Deklaration der auftretenden Variablen vorausgesetzt)&lt;br /&gt;
 &amp;amp; eine_zahl&lt;br /&gt;
 &amp;amp; ein_array[10]&lt;br /&gt;
 &amp;amp; ein_struct&lt;br /&gt;
 &amp;amp; ein_struct.komponente&lt;br /&gt;
 (int *) 0x1234&lt;br /&gt;
 (int *) eine_zahl&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Deklaration&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Anweisungen sind gewissermassen die Atome (oder Moleküle?), aus denen ein C-Programm besteht. Jedes C-Programm ist eine Abfolge von Deklarationen und Anweisungen. Einfache Anweisungen erhält man, in dem man einen Ausdruck nimmt und einen Strichpunkt dahinter schreibt:&lt;br /&gt;
 {{Ausdruck|}};&lt;br /&gt;
wie in&lt;br /&gt;
 x = x+1;&lt;br /&gt;
&lt;br /&gt;
Andere Anweisungen sind die unten aufgeführten Schleifen und die if- sowie die switch-Anweisung.&lt;br /&gt;
&lt;br /&gt;
Mehrere Deklarationen und Anweisungen können zu einem Block zusammengefasst werden. Dieser Block stellt dann wieder eine einzelne Anweisung dar und kann genau so gehandhabt werden!&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
In diesem Sinne ist auch z.B. die Syntax der if-Anweisung zu verstehen&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
besagt, daß der abhängig ausgeführte Code eine einzelne Anweisung sein darf oder eben ein kompletter Block oder die Verschachtelung mehrerer Blöcke etc.&lt;br /&gt;
&lt;br /&gt;
Eine Anweisung kann auch &amp;quot;leer&amp;quot; sein, also nichts tun. Diese Anweisungen sind der leere Block&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
und der Strichpunkt&lt;br /&gt;
 ;&lt;br /&gt;
die man gelegentlich in Schleifen findet:&lt;br /&gt;
 while (!timeout())&lt;br /&gt;
    {}&lt;br /&gt;
oder hinter Sprungmarken, die sonst direkt vor einer schliessenden Blockklammer stünden:&lt;br /&gt;
 {&lt;br /&gt;
    ...&lt;br /&gt;
    goto ein_label;&lt;br /&gt;
    ...&lt;br /&gt;
    {{Label|ein_label}}:;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Nicht jede Anweisung ist an jeder Stelle eines C-Programms erlaubt, so darf ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; nut innerhalb einer Schleife stehen. Gleiches gilt für &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;, das aber auch innerhalb eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; vorkommen darf.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Dies steht für einen Datentyp. Es kann ein elementarer Typ sein wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;, ein Zeiger darauf wie &amp;lt;tt&amp;gt;char*&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;void*&amp;lt;/tt&amp;gt;, und auch Qualifier enthalten wie das &amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt; im Typ &amp;lt;tt&amp;gt;unsigned long long&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Zu den Typen gehören auch zusammengesetzte Datentypen wie Strukturen und Unions, mit &amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt; selbst definierte Typen und natürlich Zeiger darauf, wie aus dem Abschnitt [[#Datentypen|Datentypen]]:&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person *&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;data32_t&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;&lt;br /&gt;
und Zeiger auf Funktionen.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Parameterliste&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
Die Parameterliste bei einer Funktionsdefinition gibt an, wieviel Übergabeparameter sie bekommt, wie diese heissen und welchen Typs diese sind. Der prinzipielle Aufbau ist&lt;br /&gt;
 {{Type}} {{Bezeichner}}, {{Type}} {{Bezeichner}}, ...&lt;br /&gt;
Falls die Funktion keine Parameter hat, dann ist die Parameterliste leer.&lt;br /&gt;
&lt;br /&gt;
Hier als Beispiel die zweiparametrige Funktion &amp;lt;tt&amp;gt;produkt&amp;lt;/tt&amp;gt;. Der erste Parameter heisst&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und ist ein &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;. Der zweite namens&amp;amp;nbsp;&amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; ist vom Typ &amp;quot;Zeiger auf double&amp;quot;, der Inhalt &amp;lt;tt&amp;gt;*b&amp;lt;/tt&amp;gt; ist also auch ein double.&lt;br /&gt;
&lt;br /&gt;
'''Definition der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b)&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
In älteren C-Quellen findet man noch eine andere Syntax für die Deklaration der Parameter, die aber heute praktisch nicht mehr verwendet wird:&lt;br /&gt;
'''alte Definition der Funktion:'''&lt;br /&gt;
 double produkt (a, b)&lt;br /&gt;
 double a, *b;&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Um die Funktion bekannt zu machen, werdendet man eine Deklaration bzw. den Prototypen, der dem Compiler nur mitteilt, welche Parameter die Funktion bekommt und was sie zurückliefert. Für den Aufruf der Funktion muss der Compiler nur diesen Prototyp kennen, ''was'' die Funktion im Endeffekt macht und wie sie implementiert wurde ist egal, sie wird als BlackBox angesehen.&lt;br /&gt;
&lt;br /&gt;
'''Prototyp der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b);&lt;br /&gt;
Hier dürfen die Bezeichner auch fehlen:&lt;br /&gt;
 double produkt (double, double*);&lt;br /&gt;
&lt;br /&gt;
==if==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==if-else==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==for==&lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Eine for-Schleife entspricht folgendem Konstrukt. Dabei sind die drei Ausdrücke optional. Fehlt die Bedingung, dann wird diese als &amp;quot;wahr&amp;quot; angenommen. Die beiden anderen Ausdrücke wird man als Ausdrücke mit Nebeneffekt wählen wie z.B. &amp;lt;tt&amp;gt;x=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;x=x-2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
 {&lt;br /&gt;
    {{Ausdruck|1}};&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_loop}}:&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
    else&lt;br /&gt;
       goto _break;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_continue}}:&lt;br /&gt;
    {{Ausdruck|2}};&lt;br /&gt;
    goto _loop;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_break}}:;&lt;br /&gt;
 }&lt;br /&gt;
Die Labels &amp;lt;tt&amp;gt;_break&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_continue&amp;lt;/tt&amp;gt; entsprechen den Sprungzielen einer &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Anweisung innerhalb von &amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==do-while==&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while  ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
==while==&lt;br /&gt;
 while  ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==switch==&lt;br /&gt;
 switch  ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    ...&lt;br /&gt;
  &lt;br /&gt;
    default:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#break-Anweisung|&amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Konstanten|&amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#continue-Anweisung|&amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#do-while-Schleife|&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Enum|&amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#for-Schleife|&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#goto-Anweisung|&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#return-Anweisung|&amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Liste der Operatoren|sizeof]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Strukturen|&amp;lt;tt&amp;gt;struct&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Eigene Datentypen|&amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Unions|&amp;lt;tt&amp;gt;union&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#while-Schleife|&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund2}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Arithmetische Operatoren&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Dies sind die &amp;quot;normalen&amp;quot; arithmetischen Operationen, wie man sie aus der Schule kennt. Man kann damit und allen anderen Operatoren auch komplexere Ausdrücke aufbauen. Die Prioritäten sind so, wie man sie kennt, also &amp;quot;Punktrechnung vor Strichrechnung&amp;quot;. Will man dies ändern, dann mit den runden Klammern:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;1+2*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 7&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(1+2)*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 9&amp;lt;br/&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}}&amp;amp;nbsp;+&amp;amp;nbsp;{{Ausdruck|}}&amp;lt;/tt&amp;gt; || Addition&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} - {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Subtraktion&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} * {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Multiplikation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} / {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Division&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} % {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Rest der Division (modulo)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;- {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Vorzeichenumkehr, Zweier-Komplement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Logische Operatoren und Vergleiche&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die logischen und die vergleichenden Operatoren liefern als Ergebnis den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (wahr) oder einen Wert ungleich&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (falsch, um genau zu sein den Wert &amp;lt;tt&amp;gt;!0&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Man kann das Ergebnis zwar einer Variablen zuweisen, in aller Regel wird man solche Ausdrücke jedoch in Bedingungen zu &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder in Abbruch-Bedingungen von Schleifen finden.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;&amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches AND: beides wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124;&amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches OR: mind. eines ist wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;! {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches NOT (0 &amp;amp;harr; ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} == {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} != {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist nicht gleich&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bitweise Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~ {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise NOT (Einser-Komplement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise AND&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise ODER&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} ^ {{Ausdruck|}}&amp;lt;/tt&amp;gt; ||bitweise XOR&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Shift-Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;lt;&amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Bits nach links schieben&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;gt;&amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Schieben nach rechts schieben&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Typen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Ein Cast in C kann dazu verwendet werden, den Typ eines Ausdruckes zu ändern oder den Ausdruck mit einer bestimmten Genauigkeit zu berechnen. Wird z.B. eine Berechnung standardmässig in 16 Bit ausgeführt, dann kann man mit einem Cast &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(long) &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
ausdrücken, daß die Berechnung in 32 Bit erfolgen soll. Des weiteren kann man Zeiger und ganze Zahlen und Gleitkommazahlen ineinander umwandeln.&lt;br /&gt;
&lt;br /&gt;
Casts können ''nicht'' dazu verwendet werden, um z.B. eine Zahl in einen String zu konvertieren, der diese Zahl darstellt! Dafür gibt es spezielle Funktionen wie &amp;lt;tt&amp;gt;itoa&amp;lt;/tt&amp;gt;!&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Type}}) {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Cast, Typwandlung&lt;br /&gt;
|-&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;| &amp;lt;tt&amp;gt;sizeof ({{Type}})&amp;lt;/tt&amp;gt; || Eine Konstante, deren Wert die Größe (in Bytes) des Typs ist. &amp;lt;tt&amp;gt;sizeof&amp;lt;/tt&amp;gt; ist auch auf Objekte anwendbar wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, Arrays bekannter Größe, Strukturen und Unions,  Array-, Struktur- und Union-Komponenten, Pointer, etc. Beispiel:&amp;lt;br/&amp;gt;&lt;br /&gt;
 int i, sum=0, array[] = { 1, -13, 4, 0, sizeof (int*) };&lt;br /&gt;
 &lt;br /&gt;
 for (i=0; i&amp;lt; sizeof (array) / sizeof (array[0]); i++)&lt;br /&gt;
    sum += array[i];&lt;br /&gt;
Alle Elemente des Arrays werden aufaddiert, ohne daß deren Anzahl explizit in der Schleife genannt ist.&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zeiger und Adressen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;* {{Adresse}}&amp;lt;/tt&amp;gt; || der Inhalt an Adresse&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp; {{Lvalue}}&amp;lt;/tt&amp;gt; || Adresse von&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Strukturen, Unions, Arrays&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Struct&amp;gt;}}.{{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Zeiger-auf-Struct&amp;gt;}} -&amp;gt; {{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union, deren Adresse man hat&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Adresse}}&amp;amp;#91;{{Ausdruck|}}&amp;amp;#93;&amp;lt;/tt&amp;gt; || Array-Element&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bedingte Auswertung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Bedingung}}) ? {{Ausdruck|}} : {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Auswahl des Wertes abhängig von der Bedingung&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zuweisung und Operatoren mit Nebeneffekt&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die Unterschiede der post- und pre-Varianten der Increment/Decrement kommen in Konstrukten wie &amp;lt;tt&amp;gt;x = *p++&amp;lt;/tt&amp;gt; zum tragen:&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *p++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; p = p+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *++p;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; p = p+1; x = *p;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = (*p)++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; *p = (*p)+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = ++(*p);&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; *p = (*p)+1; x = *p;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} = {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Zuweisung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++ {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-- {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Decrement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ++&amp;lt;/tt&amp;gt; || Post-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} --&amp;lt;/tt&amp;gt; || Post-Decrement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Kurzschreibweisen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Für ganz Faule gibt es anstatt&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a = a @ b&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
für viele Operatoren (hier dargestellt durch ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;@&amp;lt;/tt&amp;gt;) die abkürzende Schreibweise&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a @= b&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} += {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} -= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} *= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} /= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} %= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ^= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;lt;&amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;gt;&amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Autoren'''&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
* Kernighan und Ritchie - Buch&lt;br /&gt;
* Christian Wirth , C Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://wwwuser.gwdg.de/~kboehm/ebook/inhalt.html C-Programmieren unter Linux]&lt;br /&gt;
* [http://www.gdv.uni-hannover.de/documentation.php Skripte zum Selbststudium: C, C++, Java, etc]&lt;br /&gt;
* [http://info.baeumle.com/ansic.html Einführung in ANSI-C]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Quellcode C|!]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Inrfb2</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10398</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10398"/>
				<updated>2007-03-13T11:45:39Z</updated>
		
		<summary type="html">&lt;p&gt;Inrfb2: /* Aufruf */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Programmiersprache C wurde 1971 als Gundlage für das Betriebssystem UNIX in den USA entwickelt (UNIX ist zu über 90% in C geschrieben). 1978 wurde von Brian Kernighan und Dennis Ritchie eine eindeutige Sprachdefinition entwickelt. Mittlerweile ist C von ANSI und ISO standardisiert.&lt;br /&gt;
&lt;br /&gt;
Heute sind C und ihr Nachfolger C++ die dominierenden Programmiersprachen. Sehr viele Anwendungen sind in C geschrieben, was inzwischen auch auf eingebettete Systeme zutrifft, die lange in Assembler programmiert werden mussten, da keine ausreichend leistungsfähigen Compiler zur Verfügung standen. &lt;br /&gt;
&lt;br /&gt;
Leider ist C nicht einfach zu lernen &amp;amp;ndash; es wurde weder von noch für Hobby-Programmierer entwickelt &amp;amp;ndash; und eignet sich daher nur bedingt für den Einsteiger. Mit etwas Übung und einem optimierenden Compiler kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
Vom Design her ist C eine Hardware-unabhängig Sprache. Das bedeutet, daß C-Programme mit vertretbarem Aufwand auf ein anderes System portiert werden können. Dazu benötigt man lediglich einen anderen Compiler, und Inline-Assembler-Anweisungen (Assembleranweisungen innerhalb eines C-Programmes) müssen der neuen Hardware (Prozessor) angepasst werden. &lt;br /&gt;
&lt;br /&gt;
==Geschichte==&lt;br /&gt;
;1971: C wird entwickelt&lt;br /&gt;
;1978: Kernighan und Ritchie definieren die Sprache.&lt;br /&gt;
;1983: ANSI und ISO standardisieren C.&lt;br /&gt;
;1992: Bjarne Stroustrup enwickelt die Nachfolgesprache C++.&lt;br /&gt;
&lt;br /&gt;
=Aufbau eines C-Programmes=&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
   C-Programme haben keinen fixen Aufbau wie z.B. Pascal. Es gibt zwar gewisse Regeln, aber sonst sind dem Programmierer alle Freiheiten überlassen. Der folgende &amp;quot;Beispiel-Aufbau&amp;quot; ist daher nicht zwingend und kann durchaus verändert werden.&lt;br /&gt;
&lt;br /&gt;
   Natürlich haben C-Programme einen fixen Aufbau! Ebenso wie Pascal-Programme auch unterliegen sie einer strikten Grammatik! &lt;br /&gt;
Auskommentiert --[[Benutzer:SprinterSB|SprinterSB]] 10:23, 17. Feb 2006 (CET)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Ein einfaches C-Programm könnte folgendermassen aussehen. Das Programm tut eigentlich nichts, aber das Beispiel zeigt den prinzipiellen Aufbau. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 int Zahl1;&lt;br /&gt;
 char Zeichen1;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int zahl2;&lt;br /&gt;
 &lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Beschreibung:'''&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndash; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
 {{comment|void-Definition von main ist nur beim Controller ueblich}}&lt;br /&gt;
 {{comment|spezielle Compilereinstellungen sind noetig, damit bei dieser Definition von main}}&lt;br /&gt;
 {{comment|kein Fehler/Warnung erzeugt wird.}}&lt;br /&gt;
 void main ()&lt;br /&gt;
 {&lt;br /&gt;
     ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
 int main (void)&lt;br /&gt;
 {  {{comment|der Block &amp;quot;main&amp;quot; beginnt}}&lt;br /&gt;
    int zahl;&lt;br /&gt;
    &lt;br /&gt;
    {   {{comment|ein Block beginnt}}&lt;br /&gt;
        {{comment|hier koennen Deklarationen und Anweisungen stehen}}&lt;br /&gt;
    }   {{comment|der Block endet}}&lt;br /&gt;
   &lt;br /&gt;
    return 0;&lt;br /&gt;
 }  {{comment|&amp;quot;main&amp;quot; endet}}&lt;br /&gt;
&lt;br /&gt;
=Datentypen=&lt;br /&gt;
==Elementare Datentypen==&lt;br /&gt;
Der Datentyp einer Variable gibt an, welche Werte eine Variable enthalten kann, welcher Art diese Daten sind und wie sie verarbeitet werden, etwa in arithmetischen Operationen wie einer Addition. So ist es zum Beispiel möglich, in eine Variable vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ganze Zahlen zwischen ca. -32000 und +32000 einzutragen. In einer char-Variable können ASCII-Zeichen gespeichert werden (alles, was Sie mit der Tastatur erzeugen können) oder ganze Zahlen von -128 bis 127.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da C plattformabhängig ist, hängt die Größe eines Datentypes zum Teil von der genutzten Hardware (z.B. 8, 16 oder 32 Bit-Controller) und dem Compiler und dessen Einstellungen ab!&lt;br /&gt;
&lt;br /&gt;
===int, char, short, long (ganze Zahlen)===&lt;br /&gt;
In Variable dieser Typen können Sie ganze Zahlen abspeichern, also z.B. 1, &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;2, 100, 12345. Jeden dieser Typen gibt es in zwei Ausprägungen: als &amp;quot;&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;quot;, also als vorzeichenbehafteten Typ, und als &amp;quot;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&amp;quot;, also ohne Vorzeichen, d.h. das Vorzeichen wird als 0 oder +1 genommen. &lt;br /&gt;
&lt;br /&gt;
Vorzeichenbehaftete Ganzzahl-Typen werden intern im &amp;lt;tt&amp;gt;n-1&amp;lt;/tt&amp;gt;-Komplement dargestellt, das Vorzeichen selbst findet sich also im höchstwertigen Bit. Werden zur Speicherung ''b'' Bits verwendet, dann reicht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;z.B. *zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==Enum==&lt;br /&gt;
&lt;br /&gt;
Über &amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt; können Aufzählungen definiert werden. Die Werte sind &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Werte und beginnen mit&amp;amp;nbsp;0. Der folgende enum hat einen um&amp;amp;nbsp;1 grösseren Wert. Mit einer Zuweisung können auch andere Werte zugeordnet werden. Klarer wird's im Beispiel:&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 enum Farben&lt;br /&gt;
 {&lt;br /&gt;
    ROT,&lt;br /&gt;
    GRUEN,&lt;br /&gt;
    BLAU,&lt;br /&gt;
    BRAUN = 5,&lt;br /&gt;
    SCHWARZ&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
Dies definiert die Konstanten &amp;lt;tt&amp;gt;ROT=0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;GRUEN=1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BLAU=2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BRAUN=5&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;SCHWARZ=6&amp;lt;/tt&amp;gt; und den Typ &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void foo (enum Farben farbe)&lt;br /&gt;
{&lt;br /&gt;
   switch (farbe)&lt;br /&gt;
   {&lt;br /&gt;
      case ROT:&lt;br /&gt;
         ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit kann man anstatt &amp;quot;magischer&amp;quot; Zahlen sprechende Namen im Code verwenden, etwa in Berechnungen und Zuweisungen, Vergleichen oder als Konstante hinter einem &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zusammengesetzte Datentypen==&lt;br /&gt;
===Arrays===&lt;br /&gt;
Oft muß man sehr viele Werte gleichzeitig abspeichern und betrachten, die alle der selben Aufgabe dienen. Man schreibt z.B. ein Programm, das 10 Zahlen einlesen und anschließend wieder ausgeben soll. Man könnte das natürlich mit 10 einzelnen Variablen bewerkstelligen, aber es ist sinnvoller, dabei Arrays &amp;amp;ndash; teilweise auch als ''Felder'' bezeichnet &amp;amp;ndash; zu verwenden.&lt;br /&gt;
&lt;br /&gt;
In einem Array werden mehrere Variablen gleichen Typs zusammengefasst und hintereinander im Speicher abgelegt. So kann man viele tausend Variablen anlegen mit nur einer Zeile Code. Doch es gibt noch größere Vorteile: Sie können das Array mit einer Schleife ganz einfach nach Werten durchsuchen. Stellen Sie sich vor, Sie müssten mit 100 verschiedenen Variablen &amp;lt;tt&amp;gt;Zahl_00&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;Zahl_99&amp;lt;/tt&amp;gt; arbeiten!&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}}&amp;amp;#91;{{Konstante}}&amp;amp;#93;;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 unsigned int werte[100];&lt;br /&gt;
&lt;br /&gt;
Der Name muß natürlich ein gültiger Bezeichner sein, als Datentyp kann jeder Typ genommen werden &amp;amp;ndash; sowohl elementare Datentypen als auch Zeiger, Strukturen, Unions oder selbst definierte Datentypen. In der eckigen Klammer wird die Anzahl der Elemente bekanntgegeben. Ein mit [3] definiertes Array hat Platz für drei Variablen. Da der Index immer bei 0 beginnt, greift man also mit &amp;lt;tt&amp;gt;[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;[1]&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;[2]&amp;lt;/tt&amp;gt; auf den jeweilige Inhalt zu. Um auf eine der im Array enthaltenen Variablen zugreifen zu können, müssen Sie den Variablennamen und in eckigen Klammern den Index (die &amp;quot;Nummer&amp;quot;) der Variablen angeben. Diese Variable verhält sich dann wie eine ganz normale Variable des jeweiligen Datentypes. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #define NZAHLEN 10&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int i;&lt;br /&gt;
    int zahlen[NZAHLEN];  {{comment|zahlen[0] ... zahlen[9]}}&lt;br /&gt;
  &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++)&lt;br /&gt;
    {&lt;br /&gt;
       printf (&amp;quot;Bitte Zahl %d eingeben: &amp;quot;, i);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; zahlen[i]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++) &lt;br /&gt;
       printf (&amp;quot;Zahl %d ist: %d\n&amp;quot;, i, zahlen[i]);&lt;br /&gt;
      &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 10 int-Variablen großes Array angelegt. &lt;br /&gt;
In dieses wird nun der Reihe nach 10 Zahlen eingelesen. &lt;br /&gt;
Anschließend werden alle 10 Zahlen ausgegeben. &lt;br /&gt;
&lt;br /&gt;
Dabei wird die Größe der Arrays und das Schleifenende über das Define &amp;quot;&amp;lt;tt&amp;gt;NZAHLEN&amp;lt;/tt&amp;gt;&amp;quot; angegeben. Dadurch muss nur ''eine Stelle'' im Code geändert werden, wenn die Größe des Arrays einmal einen anderer Wert als 10 haben soll &amp;amp;ndash; dies vermeidet Fehler die dadurch entstehen, wenn man beim Anpassen der Array-Größe eine Codestelle vergisst, zudem wird der Code lesbarer als wenn irgendwo die Zahl &amp;quot;10&amp;quot; auftaucht.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
:Wird ein ungültiger Index angeben (einer, der in der Deklaration nicht enthalten ist) können  undefinierte Dinge passieren, wenn dadurch andere Variableninhalte oder Programmcode überschrieben wird, der hinter oder vor dem Array im Speicher liegt. Schlimmstenfalls kann sogar der Computer/Controller abstürzen. Also darauf achten, daß keine ungültigen Werte als Index auftreten!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Strings (Zeichenketten)===&lt;br /&gt;
Ein String ist nichts anderes als ein Array, das aus einzelnen Zeichen (&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;) gebildet wird. Die Ausgabe auf dem Bildschirm funktioniert am einfachsten mittels Strings.&lt;br /&gt;
&lt;br /&gt;
Die Definition eines Strings erfolgt also genauso wie bei Arrays:&lt;br /&gt;
 char string[21];&lt;br /&gt;
&lt;br /&gt;
Nun haben Sie eine String, in dem Sie 21 Zeichen speichern können. Ganz richtig ist das jedoch nicht. C arbeitet mit &amp;quot;null-terminierten Strings&amp;quot;. Das beudeutet, dass die Länge des Strings nicht abgespeichert wird, sondern das Zeichen mit dem ASCII-Wert 0 das Stringende kennzeichnet. Daher auch die Bezeichnung  &amp;quot;null terminiert&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Das letzte Zeichen eines Strings muß daher immer das ASCII-Zeichen Nr. 0 sein. Ist es das nicht, hat der String kein definiertes Ende, und wenn Sie versuchen, ihn durch eine Standard-Funktion auszugeben zu lassen, könnte es eine Weile dauern, bis sich im Speicher zufällig irgendwo eine 0 befindet. Es stehen ihnen daher bei dem Beispiel nur 20 Zeichen zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
===Mehrdimensionale Arrays===&lt;br /&gt;
Manchmal benötigt man mehr als nur ein eindimensionales Array, wie Sie es bisher kennengelernt haben. Auch dies ist kein Problem. In der Deklaration geben Sie einfach mehrere eckige Klammern hintereinander an. Aber Vorsicht: der Speicherplatz ist begrenzt, ein &amp;quot;&amp;lt;tt&amp;gt;char feld[1024][1024]&amp;lt;/tt&amp;gt;&amp;quot; hat die Speicherplatzgrenzen vermutlich bereits weit überschritten, und der Compiler wird einen (bei gewissen Einstellung auch keinen) Fehler liefern.&lt;br /&gt;
Beim Zugriff auf mehrdimensionale Felder müssen auch mehrere Indizes angeben werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  int x,y;&lt;br /&gt;
  int feld[3][5];&lt;br /&gt;
 &lt;br /&gt;
  for (x=0; x&amp;lt;3; x++) &lt;br /&gt;
  {&lt;br /&gt;
     for (y=0; y&amp;lt;5; y++)&lt;br /&gt;
     {&lt;br /&gt;
       printf (&amp;quot;Feldwert x: %d,  y: %d &amp;quot;, x, y);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; feld[x][y]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  for(x=0; x&amp;lt;3; x++) &lt;br /&gt;
     for (y=0; y&amp;lt;5; y++) &lt;br /&gt;
        printf (&amp;quot;Wert: feld[%d][%d] = %d\n&amp;quot;, x, y, feld[x][y]);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 3 mal 5 &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array angelegt. &lt;br /&gt;
Dann werden die Werte eingegeben: zuerst &amp;lt;tt&amp;gt;feld[0][0]&amp;lt;/tt&amp;gt;, dann &amp;lt;tt&amp;gt;feld[0][1]&amp;lt;/tt&amp;gt;, usw. bis &amp;lt;tt&amp;gt;feld[2][4]&amp;lt;/tt&amp;gt;. &lt;br /&gt;
Zum Schluß werden alle Werte noch einmal ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===Strukturen===&lt;br /&gt;
In C können Sie sogenannte &amp;quot;Strukturen&amp;quot; definieren. Dabei handelt es sich um eine Zusammenfassung mehrerer Datentypen zu einem größeren. Im Unterschied zu Feldern können in Strukturen unterschiedliche Datentypen zusammengestellt und gespeichert werden: &lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 struct {{Bezeichner}}&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur 'Person'}}&lt;br /&gt;
 struct Person &lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;lt;tt&amp;gt;struct Person {&amp;lt;/tt&amp;gt;&amp;quot; leitet die Definition der Struktur mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;Person&amp;lt;/tt&amp;gt;&amp;quot; ein. &lt;br /&gt;
Dann werden in dieser Struktur fünf Komponenten definiert: drei Strings und zwei &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. &lt;br /&gt;
mit &amp;lt;tt&amp;gt;}&amp;lt;/tt&amp;gt; wird die Definition abgeschlossen. Sie haben damit einen Datentyp erstellt. Um eine Variable des Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach an&lt;br /&gt;
 struct Person {{Bezeichner}};&lt;br /&gt;
&lt;br /&gt;
Zum Zugriff auf eine Komponente der Struktur gibt man den Namen der Struktur-Variablen an (im folgenden Beispiel also &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;klaus&amp;lt;/tt&amp;gt;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
 {{comment|Definition zweier Struktur-Variablen}}&lt;br /&gt;
 struct Person hubert, klaus;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Zugriff auf Struktur-Komponenten}}&lt;br /&gt;
 hubert.alter = 32;&lt;br /&gt;
 klaus.alter = hubert.alter + 1;&lt;br /&gt;
&lt;br /&gt;
===Unions===&lt;br /&gt;
Eine Union wird ganz analog zu einer Struktur deklariert und verwendet. Sie unterscheidet sich von einer Struktur jedoch dadurch, daß ihre Elemente nicht nacheinander im Speicher abgelegt werden, sondern sich überlagern. Auf die in einer Union enthaltenen Daten gibt es also verschiedene Sichten: je nachdem, welche Sicht bzw. Interpretation der Daten man gerne hätte, wählt man den gewünschten Zugriff.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
union Daten &lt;br /&gt;
{&lt;br /&gt;
   int id;&lt;br /&gt;
&lt;br /&gt;
   struct Person u_person;&lt;br /&gt;
&lt;br /&gt;
   struct u_double&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      double wert;&lt;br /&gt;
   };&lt;br /&gt;
&lt;br /&gt;
   struct u_pointer&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      union Daten * p1;&lt;br /&gt;
      union Daten * p2;&lt;br /&gt;
   };&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
union Daten data;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies definiert eine Union mit den vier Zugriffsmöglichkeiten &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_double&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Größe der Union richtet sich dabei nach der grössten Komponente. In diesem Beispiel sind alle Komponenten so angelegt worden, daß sie an erster Stelle ein &amp;lt;tt&amp;gt;int id&amp;lt;/tt&amp;gt; enthalten. In &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; könnte man sich also merken, wie die Daten in der Union zu interpretieren sind. Würde &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; nicht dieses &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; enthalten, so würde sich &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; mit &amp;lt;tt&amp;gt;data.u_person.vname&amp;lt;/tt&amp;gt; überlagern. Ein Ändern der ersten Buchstaben von &amp;lt;tt&amp;gt;vname&amp;lt;/tt&amp;gt; hätte also ein Ändern von &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; zur Folge, und man könnte es nicht mehr als Merker verwenden. Mit diesem Feld überlagert das &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; die &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;-Felder der anderen Sichten, z.B. ist &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; der selbe Zugriff wie auf &amp;lt;tt&amp;gt;data.u_person.id&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein anderes Beispiel ist eine Union, die es ermöglicht, auf die einzelnen Bytes eines &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; zuzugreifen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef union&lt;br /&gt;
{&lt;br /&gt;
   unsigned long  as_long;&lt;br /&gt;
   unsignen short as_short[2];&lt;br /&gt;
   unsignen char  as_byte[4];&lt;br /&gt;
} data32_t;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies überlagert einen &amp;lt;tt&amp;gt;unsigned long&amp;lt;/tt&amp;gt; &amp;amp;ndash; also eine 32-Bit-Zahl &amp;amp;ndash; mit vier Bytes bzw. zwei Shorts.&lt;br /&gt;
 data32_t wert;&lt;br /&gt;
 &lt;br /&gt;
 wert.as_long = 0x12345678;&lt;br /&gt;
 wert.as_byte[0] = 0xab;&lt;br /&gt;
 {{comment|nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform)}}&lt;br /&gt;
&lt;br /&gt;
==Eigene Datentypen==&lt;br /&gt;
&lt;br /&gt;
=Variablen=&lt;br /&gt;
Eine Variable ist ein Synonym (=anderer Name) für eine Speicherstelle in einem Computer. Einfacher gesagt, eine Variable bietet Raum, um Daten wie Zahlen oder Zeichen zu speichern und wieder zu lesen.&lt;br /&gt;
&lt;br /&gt;
==Variablennamen==&lt;br /&gt;
Ein Variablenname kann zusammengesetzt werden aus den Buchstaben &amp;lt;tt&amp;gt;'''A'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''Z'''&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;'''a'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''z'''&amp;lt;/tt&amp;gt;, den Ziffern &amp;lt;tt&amp;gt;'''0'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''9'''&amp;lt;/tt&amp;gt;, sowie dem Sonderzeichen &amp;quot;Unterstrich&amp;quot; (underscore) &amp;lt;tt&amp;gt;'''_'''&amp;lt;/tt&amp;gt;. Dabei darf an erster Stelle keine Ziffer stehen. Die Bezeichner &amp;lt;tt&amp;gt;hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALLO&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALL0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;_123&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_HALLO&amp;lt;/tt&amp;gt; sind also alle gültige und unterschiedliche Variablennamen.&lt;br /&gt;
&lt;br /&gt;
==Anlegen von Variablen==&lt;br /&gt;
Um eine Variable verwenden zu können, muss sie zuerst vereinbart (&amp;quot;erzeugt&amp;quot;) werden. Dies wird auch als &amp;quot;''Definition der Variablen''&amp;quot; bezeichnet und geht so: Schreiben Sie zuerst den Datentyp, dann den Namen der Variablen. Zum Schluß kommt noch der Strichpunkt, wie nach jeder C-Anweisung oder Deklaration. Und nicht vergessen: C unterscheidet zwischen  Groß- und Kleinschreibung! &lt;br /&gt;
 int Zahl1, Zahl2;&lt;br /&gt;
 char Zeichen;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    float gleitZahl;&lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:'''&lt;br /&gt;
In einer Zeile können auch mehrere Variablen gleichen Types vereinbart werden, wenn man ein Komma dazwischen setzt. Variablen können in jedem Block vereinbart werden. Siehe [[#Gültigkeitsbereich|Gültigkeitsbereich]].&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen==&lt;br /&gt;
Man kann einer vereinbarten Variable Werte [[#Zuweisungen|zuweisen]]. Dazu schreibt man zuerst den Variablennamen, ein Gleichheitszeichen &amp;quot;&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;&amp;quot; und anschliessend den zuzuweisenden [[#Ausdrücke|Ausdruck]]. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, zahl2 = 12;&lt;br /&gt;
  char zeichen1 = 'A';&lt;br /&gt;
&lt;br /&gt;
  zahl1 = 52;&lt;br /&gt;
  zeichen1 = zeichen1 + 1; &lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Zuerst werden drei Variablen angelegt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;: wird gleich bei der Vereinbarung der Wert 12 zugewiesen. &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl1 = 52&amp;lt;/tt&amp;gt;: Hier wird der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; der Wert 52 zugewiesen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;: wird um 1 erhöht. Da in der Variablen &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; gespeichert ist, gibt sich ihr neuer Wert aus &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt;. Weil &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; dem Wert 65 entspricht, ist &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt; gleich 66, was dem Wert für &amp;lt;tt&amp;gt;'B'&amp;lt;/tt&amp;gt; entspricht.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei float==&lt;br /&gt;
Das funktioniert genau wie bei normale Zuweisungen. Nachkommastellen werden durch einen Punkt abgegrenzt: &lt;br /&gt;
 floatVariable = 3.14;&lt;br /&gt;
Zusätzlich kann eine Zehnerpotenz angegeben werden:&lt;br /&gt;
 floatVariable2 = -1.234E-6;&lt;br /&gt;
Dadurch wird der erst Wert mit 10&amp;lt;sup&amp;gt;&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;6&amp;lt;/sup&amp;gt; multipliziert, der Wert der Variablen ist also &lt;br /&gt;
:&amp;lt;math&amp;gt;-1{,}234\cdot10^{-6} = -0.000001234&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei logischen Variablen==&lt;br /&gt;
Wie bereits erwähnt, besitzt C keinen logischen Datentyp. Es müssen also &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; dafür genutzt werden. Die Zuweisung entpricht der Standard-Zuweisung. Wird der Wert 0 zugewiesen, dann ist die Variable &amp;quot;unwahr&amp;quot;, ansonsten ist sie &amp;quot;wahr&amp;quot;. &lt;br /&gt;
 intVariable = !0;   /* entspricht &amp;quot;wahr&amp;quot;   */&lt;br /&gt;
 intVariable = 0;    /* entspricht &amp;quot;unwahr&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
==Konstanten==&lt;br /&gt;
Konstanten können als Variable angesehen werden, die nicht beschrieben, sondern nur gelesen werden können. Ein typisches Beispiel dafür ist die Zahl &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; (rund 3,141592654). Niemand würde in der realen Welt versuchen, ihr einen anderen Wert zuzuweisen. Würde man &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; jedoch wie eine normale Variable anlegen, wäre dies ohne weiteres möglich. Um dies zu verhindern, gibt es das Schlüsselwort &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in C:&lt;br /&gt;
 const {{Type}} {{Bezeichner}} = {{Konstante}};  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Wichtig dabei ist, dass man Konstanten nur bei der Vereinbarung einen Wert zuweisen kann. &lt;br /&gt;
Da Konstanten gewöhnlich im gesamten Programm, zumindest einer Quelldatei genutzt werden, definiert man diese allerdings gewöhnlich außerhalb des main-Blockes entweder am Anfang eines Programmes, oder in einer sogenannten Header-Datei, die per &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; eingebunden wird.&lt;br /&gt;
 const float PI = 3.141592;  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Es sei jedoch erwähnt, daß auch einer Konstanten nachträglich ein anderer Wert zugewieden werden kann. Im obigen Beispiel könnte mit&lt;br /&gt;
 * ((float*) &amp;amp;PI) = 2;&lt;br /&gt;
der Wert von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; im Nachhinein verändert werden. Es wird die Adresse von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; genommen und diese Adresse durch den Cast in eine ganz normale &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;-Adresse umgewandelt, über welche der Wert geändert wird. Die sei der Vollständigkeit halber erwähnt.&lt;br /&gt;
&lt;br /&gt;
Je nachdem, an welcher Stelle sich das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; bei einer Pointer-Deklaration befindet, markiert es den Pointer als konstant oder das Objekt, auf das dieser Pointer zeigt. Eine häufige Parameterdeklaration in Ausgabe-Funktionen, die einen String erhalten, ist&lt;br /&gt;
 void foo (const char * str, ...);&lt;br /&gt;
Dadurch ist &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; der Zeiger auf eine Zeichenkette, die innerhalt der Funktion nicht verändert wird bzw. verändert werden darf. Eine Zuweisung wie &amp;lt;tt&amp;gt;*str = 'a'&amp;lt;/tt&amp;gt; ergibt also einen Fehler. &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; selbst kann aber sehr wohl verändert werden, etwa mit &amp;lt;tt&amp;gt;str++&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Soll ausgedrückt werden, daß &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; unveränderlich ist, dann so:&lt;br /&gt;
 void foo (char * const str, ...);&lt;br /&gt;
Jetzt wäre eine Änderung des Strings in Ordnung, etwa durch &amp;lt;tt&amp;gt;str[10] = 'a'&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Um sich zu merken, worauf das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; wirkt, trennt man die Deklaration in Gedanken beim&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf: Steht das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; links vom&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, dann gehört es zum &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, steht es rechts davon, dann gehört es zum Pointer. Natürlich ist es auch denkbar, beides &amp;amp;ndash; also den Zeiger und sein Ziel &amp;amp;ndash; als konstant zu markieren.&lt;br /&gt;
&lt;br /&gt;
==Gültigkeitsbereich==&lt;br /&gt;
In C können mehrere Variablen den gleichen Namen haben, solange eindeutig ist, welche in welchen Block gültig ist. Dabei gelten folgende Regeln: &lt;br /&gt;
&lt;br /&gt;
;Lokale Variablen: sind Variablen, die innerhalb eines Blockes definiert werden. Jede Variable ist nur in dem Block gültig, in dem sie vereinbart wurde, sowie in allen darin enthaltenen Blöcken; es sei denn, in einem Unter-Block wird eine Variable gleichen Namens definiert. Dann bezieht sich in diesem Unter-Block der Bezeichner auf die im Unter-Block angelegte Variable.&lt;br /&gt;
;Globale Variablen: werden ausserhalb jedes Blockes definiert und gelten ab der Stelle, an der sie deklariert werden, siehe auch [[#Deklaration und Definition|Deklaration und Definition]]. Wird jedoch in einem Block eine Variable gleichen Namens angelegt, gilt ab hier bis zum Ende des Blocks nicht mehr die globale Variable, sondern die im Block deklarierte. Das Spiel kann man weiterspielen: wird in einem Unter-Block wieder eine namensgleiche Variable angelegt, gilt diese in dem Unterblock.&lt;br /&gt;
&lt;br /&gt;
==Speicherklassen==&lt;br /&gt;
Jede Variable in C gehört zu einer bestimmten Speicherklasse&lt;br /&gt;
;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;: Lokale Variablen sind in aller Regal sogenannte ''automatische Variablen''. Das bedeutet, sie werden automatisch angelegt, wenn ein Block bzw. eine Funktion betreten wird und danach wieder entfernt. Das Schlüsselwort &amp;quot;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;&amp;quot; wird praktisch nie hingeschrieben, denn lokale Variablen ohne die ausdrückliche Angabe einer Speicherklasse, sind automatisch automatische Variablen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;: Eine externes Symbol ist im ganzen Programm bekannt bzw. in dem Block, in der die Deklaration steht. In unterschiedlichen Blöcken stehende Deklarationen beziehen sich auf das gleiche Symbol! Obgleich das Datum global zugreifbar ist, ist der Gültigkeitsbereich auf den deklarierenden Block begrenzt bzw. auf das deklarierende Quell-Modul, sofern das Symbol ausserhalb jedes Blocks des Moduls deklariert wird. Siehe auch [[#Deklaration und Definition|Deklaration und Definition]].&lt;br /&gt;
;&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;: Die Variable ist im Block gültig bzw. im Quell-Modul (also in der C-Datei, in der die angelegt wurde), wenn sie nicht innerhalb eines Blockes angelegt wurde. Statische Variablen werden nicht in Registern oder im Frame der Funktion angelegt, sondern im selben Speicherbereich, in dem auch die globalen Variablen liegen; Konstanten evtl. auch im Flash. Eine lokale Variable, die als &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; angelegt wird, &amp;quot;überlebt&amp;quot; also das Verlassen des Blocks und hat beim neuerlichen Betreten des Blockes ihren bisherigen Wert. In unterschiedlichen Blöcken angelegte lokale statische Variablen beziehen sich auf unterschiedliche Speicherstellen, genau wie bei lokalen Variablen auch.&lt;br /&gt;
;&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;: Durch diese Speicherklasse wird eine Variable &amp;amp;ndash; falls möglich &amp;amp;ndash; als Registervariable angelegt, also in einem Maschinenregister des Computer/Controllers gehalten. Dadurch kann auf solche Variablen besonders schnell zugegriffen werden. Dieses Schlüsselwort ist bei modernen Compilern weitgehend überflüssig, da die entsprechenden Optimierungen selbständig vorgenommen werden, wenn ausreichend Register vorhanden sind. Auch globale Variablen können als Register angelegt werden, davon ist dem Anfänger aber dringend abzuraten, weil leicht schwerauffindbare Fehler und Abstürze auftreten, wenn man nicht genau weiss, welche Implikationen in einer solchen Definition stecken!&lt;br /&gt;
;&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;: (FIXME: volatile ist ein Qualifier und keine Speicherklasse) Dies ist das genaue Gegenteil von &amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt; und bewirkt, dass die Variable auf keinen Fall in einem Register zwischengespeichert werden darf, sondern immer aus dem RAM gelesen und ins RAM geschrieben werden soll. &amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt; müssen alle ''globalen'' Variablen markiert werden, die in [[ISR | Interrupt-Handlern]] verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Ausdrücke=&lt;br /&gt;
Eine Variable oder eine Konstante in C stellen einfache Ausdrücke dar.&lt;br /&gt;
Diese elementaren Ausdrücke können durch Operatoren miteinander verknüpft werden und so zu neuen, komplexeren Ausdrücken zusammen gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Einfache Beispiele für Ausdrücke sind also z.B.:&lt;br /&gt;
 1&lt;br /&gt;
 a&lt;br /&gt;
 'a'&lt;br /&gt;
 1 + a&lt;br /&gt;
 a == 1&lt;br /&gt;
&lt;br /&gt;
Auch Funktionen können einen Wert zurückliefern und in Ausdrücken weiter benutzt werden.&lt;br /&gt;
In den folgenden Abschnitten wird gezeigt, welche Operatoren in C vorhanden sind,&lt;br /&gt;
und wei man damit neue Ausdrücke aufbauen kann.&lt;br /&gt;
&lt;br /&gt;
==Lvalues==&lt;br /&gt;
&lt;br /&gt;
Ein Lvalue in C ist ein Ausdruck, dem ein anderer Ausdruck zugewiesen werden kann, dessen Wert also durch eine Zuweisung verändert werden kann.&lt;br /&gt;
das 'L' leitet sich ab von 'left' bwz. 'links' und das 'value' bedeutet Wert: Ein Lvalue ist ein Ausdruck, der auf der linken Seite einer Zuweisung stehen darf. Ein Lvalue ist also immer auch ein gültiger Ausdruck, aber die Umkehrung gilt in alles Regel nicht.&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für einen Lvalue ist eine &amp;quot;normale&amp;quot; Variable, die nicht mit &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; als Konstante markiert ist:&lt;br /&gt;
 a = 1;&lt;br /&gt;
Hingegen ist der Ausdruck &amp;lt;tt&amp;gt;a+1&amp;lt;/tt&amp;gt; kein Lvalue, denn eine Zuweisung wie&lt;br /&gt;
 a+1 = 2;&lt;br /&gt;
die mathematisch durchaus sinnvoll ist, erzeugt einen Compilerfehler, der etwa lauten könnte &amp;quot;illegal lvalue in assignment&amp;quot;:&lt;br /&gt;
&amp;quot;ungültiger Wert in Zuweisung&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Andere Beipiele für Lvalues sind die Komponenten von (nicht-konstanten) [[#Strukturen|Strukturen]] und [[#Unions|Unions]], [[#Arrays|Array]]-Elemente und die Dereferenzierungen von Pointern: Die Konstante&amp;amp;nbsp;4 wird durch den Cast in eine Adresse umgewandelt. Über die Dereferenzierung&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; wird an die Adresse&amp;amp;nbsp;4 im Speicher eine&amp;amp;nbsp;3 geschrieben. Ob das erlaubt bzw. sinnvoll ist, ist abhängig von der jeweiligen Architektur.&lt;br /&gt;
 * ((unsigned int *) 4) = 3;&lt;br /&gt;
Hier ist der gesamte &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;-Ausdruck ein Lvalue&lt;br /&gt;
&lt;br /&gt;
==Logische (boolsche) Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp;amp;&amp;amp;amp; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr oder &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; || gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; || ungleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;= b&amp;lt;/tt&amp;gt; || kleiner oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt; b&amp;lt;/tt&amp;gt; || kleiner als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt;= b&amp;lt;/tt&amp;gt; || glösser oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt; b&amp;lt;/tt&amp;gt; || grösser als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; nicht wahr und vice versa&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine interessante Eigenschaft der Operatoren &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;amp;amp;&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; ist, dass&lt;br /&gt;
sie die Auswertung abbrechen, sobald das Ergebnis feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet. Ein oft anzutreffendes Codestück sieht so aus, dabei sei &amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
  if (p &amp;amp;&amp;amp; *p == 5)&lt;br /&gt;
  {&lt;br /&gt;
     {{comment|mach was}}&lt;br /&gt;
  }&lt;br /&gt;
Zuerst wird in der Bedinung geprüft, ob Zeiger&amp;amp;nbsp;&amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; einen Wert ungleich Null hat, also ob er überhaupt einen gültigen Wert enthält. Es ist weit verbreitete Konvention in C, daß Zeiger, die keinen gültigen Wert haben, die Adresse&amp;amp;nbsp;0 enthalten. '''Nur dann, wenn ein Zeiger nicht ein Null-Pointer ist, darf überhaupt ein Zugriff über ihn erfolgen!'''&lt;br /&gt;
&lt;br /&gt;
==Vergleich von Variablen==&lt;br /&gt;
Skalare Variablen (also ganze Zahlen, Gleitkommazahlen, Zeiger) können miteinander verglichen werden. Dazu gibt es die folgenden Operatoren in C: &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; || ist nicht gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;=&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;=&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das Ergebnis der Auswertung ist eine ganze Zahl. Ist die Bedingung erfüllt, dann ist der Wert ungleich&amp;amp;nbsp;0. Ist die Bedingung nicht erfüllt, dann ist ihr Wert gleich&amp;amp;nbsp;0.&lt;br /&gt;
Meistens wird man diese Operatoren in &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Konstrukten finden wie zum Beispiel&lt;br /&gt;
 if (x &amp;gt;= 10)&lt;br /&gt;
    x = 10;&lt;br /&gt;
oder in Abbruchbedingungen von Schleifen, wie sie weiter unten erklärt werden.&lt;br /&gt;
&lt;br /&gt;
Es ist auch möglich, das Ergebnis der Auswertung in einer &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Variablen zu speichern:&lt;br /&gt;
 int i;&lt;br /&gt;
 int z1, z2;&lt;br /&gt;
 &lt;br /&gt;
 z1 = 5;&lt;br /&gt;
 z2 = 100;&lt;br /&gt;
 i = z1 &amp;lt;= z2;  {{comment|Ein Vergleich. i wird &amp;quot;wahr&amp;quot;, da z1 kleinergleich z2 ist}}&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich&amp;amp;nbsp;0 (&amp;quot;wahr&amp;quot;), wenn &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; kleiner oder gleich &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt; ist. Ist &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; jedoch größer als &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt;, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich&amp;amp;nbsp;0 (&amp;quot;unwahr&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
==Arithmetische Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a + b&amp;lt;/tt&amp;gt; || Summe (Addition)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a - b&amp;lt;/tt&amp;gt; || Differenz (Subtraktion)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a * b&amp;lt;/tt&amp;gt; || Produkt (Multiplikation)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a / b&amp;lt;/tt&amp;gt; || Quotient (Division, evtl. mit Rest)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a % b&amp;lt;/tt&amp;gt; || Rest bei Division (Modulo)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;-a&amp;lt;/tt&amp;gt; || Vorzeichenumkehr (Zweierkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Bit-Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp; b&amp;lt;/tt&amp;gt; || bitweise und (and)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || bitweise oder (or)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a ^ b&amp;lt;/tt&amp;gt; || bitweise exclusiv-oder (xor, exor)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;~a&amp;lt;/tt&amp;gt; || jedes Bit in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; invertieren (not, Einerkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Index-Operator bei Arrays==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a[b]&amp;lt;/tt&amp;gt; || das (b+1)ste Element des Feldes a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Folgendes gilt es bei der Verwendung des Indexoperators zu beachten:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; muss ein [[C-Tutorial#Felder | Feld]] oder [[C-Tutorial#Zeiger | Zeiger]] sein&lt;br /&gt;
# &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; muss ein Integer sein oder ein Datentyp, der sich in einen int umwandeln läßt (z.B. char)&lt;br /&gt;
# Es wird nicht geprüft, ob der Index &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; im Feld &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gültig ist!&lt;br /&gt;
# Der erste Index eines Feldes ist immer 0. Daher ''(b+1)stes Element'' in der Beschreibung&lt;br /&gt;
&lt;br /&gt;
==Komponenten-Auswahl bei Structs und Unions==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a.b&amp;lt;/tt&amp;gt; || Element b der [[C-Tutorial#Strukturen | Struktur]] oder des Unions a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adress-Operator und Dereferenzierung==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&amp;amp;amp;a&amp;lt;/tt&amp;gt; || Speicheradresse der Variablen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;*a&amp;lt;/tt&amp;gt; || Wert, der an der Adresse &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a-&amp;amp;gt;b&amp;lt;/tt&amp;gt; || Wert des Elements &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; der Struktur, deren Adresse in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Adressoperator &amp;amp; kann auf Variablen angewendet werden und&lt;br /&gt;
gibt die Startadresse der Variablen im Speicher zurück.&lt;br /&gt;
&lt;br /&gt;
Handelt es sich bei einer Variable um einen [[C-Tutorial#Zeiger | Zeiger]], so enthält&lt;br /&gt;
sie eine Speicheradresse. Um an den '''Wert''' zu gelangen, der&lt;br /&gt;
an dieser Adresse steht, wird der Operator * vorangestellt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
&lt;br /&gt;
 {{comment|x ist eine Integervariable und hat den Wert 5}}&lt;br /&gt;
 int x = 5;&lt;br /&gt;
     &lt;br /&gt;
 {{comment|z ist ein Zeiger auf eine Integer-Variable und enthaelt somit}}&lt;br /&gt;
 {{comment|die Speicheradresse einer Integer-Variablen}}&lt;br /&gt;
 int *z;       &lt;br /&gt;
  &lt;br /&gt;
 {{comment|Verwendung des Adress-Operators: weist an z die Adresse von x zu}}&lt;br /&gt;
 z = &amp;amp;x;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Verwendung der Dereferenzierung}}&lt;br /&gt;
 {{comment|erhoehe den Wert, der bei Adresse z steht, um eins}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|da z auf x zeigt, hat x jetzt den Wert 6}}&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff auf Struktir- und Union-Elemente eine abkürzende Schreibweise möglich:&lt;br /&gt;
&lt;br /&gt;
Statt &lt;br /&gt;
  (*strukturZeiger).element&lt;br /&gt;
kann geschrieben werden&lt;br /&gt;
  strukturZeiger-&amp;gt;element&lt;br /&gt;
Beide Schreibweisen sind absolut gleichbedeutend, die Klammern bei der ersteren sind notwendig.&lt;br /&gt;
&lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
:Bei der Dereferenzierung durch &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; findet keine Prüfung statt, ob der Zeiger auch auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu einer Änderung '''irgendeiner''' Speicherstelle!&lt;br /&gt;
&lt;br /&gt;
 int *z; {{comment|z ist ein Zeiger auf einen int}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.}}&lt;br /&gt;
 {{comment|z enthaelt irgendeine ungueltige Adresse!!}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|&amp;quot;Erhoehe einen Integer _irgendwo_ im Speicher um 1&amp;quot; -&amp;gt; CRASH !!!}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
&lt;br /&gt;
==Cast-Operator==&lt;br /&gt;
&lt;br /&gt;
Der Cast Operator dient dazu, den Datentyp eines Wertes zu ändern. Dafür wird einfach der neue Datentyp in Klammern vor den Wert geschrieben.&lt;br /&gt;
&lt;br /&gt;
Um zum Beispiel aus einem Float ein Integer zu machen:&lt;br /&gt;
 var  = (int) 5.60;&lt;br /&gt;
Dabei wird der Wert aber auch gerundet, und es findet somit ein Informationsverlust statt.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Umwandeln einer ganzen Zahl in eine Adresse:&lt;br /&gt;
 int * addr;&lt;br /&gt;
 addr = (int*) 0x1234;&lt;br /&gt;
Damit ist &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; an Adresse 0x1234.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
Der Cast-Operator selbst führt ''keine Konvertierung'' von Darstellungen durch, etwa die Umwandlung der ganzen Zahl 123 ein den String &amp;lt;tt&amp;gt;&amp;quot;123&amp;quot;&amp;lt;/tt&amp;gt;, der diese Zahl darstellt! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
  int main(int argc, char ** argv)&lt;br /&gt;
  {&lt;br /&gt;
        char text[] = &amp;quot;5.6&amp;quot;;&lt;br /&gt;
        int zahl = (int) text;&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, zahl);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Anfangsadresse des Strings &amp;lt;tt&amp;gt;&amp;quot;5.6&amp;quot;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Komma-Operator==&lt;br /&gt;
Mit einem &amp;lt;tt&amp;gt;,&amp;lt;/tt&amp;gt; können mehrere Ausdrücke nacheinander ausgewertet werden.&lt;br /&gt;
Die Auswertung erfolgt von links nach rechts.&lt;br /&gt;
&lt;br /&gt;
Solche Konstrukte sieht man manchmal in Abfragen wie&lt;br /&gt;
 FILE  *file;&lt;br /&gt;
 if (file = fopen (&amp;quot;foo.exe&amp;quot;, &amp;quot;r&amp;quot;), file != NULL)&lt;br /&gt;
was erst an &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; einen Wert zuweist und den &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Block nur betritt,&lt;br /&gt;
wenn &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; nicht der Nullpointer ist.&lt;br /&gt;
&lt;br /&gt;
Bequem kann das auch in einer [[#for-Schleife|for-Schleife]] sein, wenn man zwei (oder mehr) Laufvariablen hat oder so:&lt;br /&gt;
 for (i=0, j=0; i &amp;lt; 10; i++, j += 2)&lt;br /&gt;
    &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Zuweisung===&lt;br /&gt;
=== ++ und -- ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; stellen einfachere Schreibweisen dar zum Addieren bzw. Subtrahieren von&amp;amp;nbsp;1.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; (Inkrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo++; &lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo + 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; 3}}&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; (Dekrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo--;&lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo - 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; -1}}&lt;br /&gt;
&lt;br /&gt;
Die beiden Operatoren können sowohl in der Präfix-Schreibweise (vor der Variablen) als auch als Postfix-Schreibweise (hinter der Variablen) notiert werden. &lt;br /&gt;
Der Unterschied liegt darin, dass beim Präfix der Wert zuerst neu berechnet wird und die Variable dann verwendet wird. Beim Postfix wird die Variable zuerst verwendet und erst nach Auswertung des Ausdrucks, in dem sie enthalten ist, neu berechnet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 int ausgabe1, ausgabe2, var1 = 10, var2 = 10;&lt;br /&gt;
 ausgabe1 = 3 * ++var1; {{comment|ausgabe1 &amp;amp;#61; 33; var1 &amp;amp;#61; 11;}}&lt;br /&gt;
 ausgabe2 = 3 * var2++; {{comment|ausgabe2 &amp;amp;#61; 30; var2 &amp;amp;#61; 11;}}&lt;br /&gt;
&lt;br /&gt;
Für Zeiger arbeiten diese Operatoren etwas anders, siehe dazu [[#Zeiger-Arithmetik|Zeiger-Arithmetik]].&lt;br /&gt;
&lt;br /&gt;
===Bedingter Ausdruck===&lt;br /&gt;
 ({{Bedingung}}) ? {{Ausdruck|1}} : {{Ausdruck|2}}&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; erfüllt ist, dann wertet dieser Ausdruck aus zu &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt;. Ist er nicht erfüllt, dann wertet er aus zu &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 x = (x &amp;gt;= 3) ? 0 : x+1;&lt;br /&gt;
Startet man &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; mit dem Wert 0, dann nimmt es bei mehrfacher Anwendung dieser Zeile (z.B. in einer Schleife) nacheinander die folgende Werte an:&lt;br /&gt;
:&amp;lt;tt&amp;gt;1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, ...&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&lt;br /&gt;
Wie auch in der Mathematik gibt es auch in C genaue Regeln über die Abarbeitungsreihenfolge (precedence)&lt;br /&gt;
der Operatoren. Dass sich alle C-Compiler genau an diesen ANSI-Vorschlag halten, ist leider nicht sicher.&lt;br /&gt;
Neben hat auch nicht jeder Programmierer diese Regel jederzeit im Kopf. &lt;br /&gt;
Daher ist es sinnvoll, Ausdrücke durch runde Klammern eindeutig zu kennzeichnen. &lt;br /&gt;
Nebenbei stören sich Compiler nicht an überflüssigen Klammerpaaren.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Priorität ||Operator||Assoziativität&lt;br /&gt;
|-&lt;br /&gt;
  &lt;br /&gt;
|&amp;lt;tt&amp;gt;15&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ( ) [ ] -&amp;gt; . &amp;lt;/tt&amp;gt;                      ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;14&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;! ~ ++ -- + - (TYP) * &amp;amp; sizeof &amp;lt;/tt&amp;gt;    ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;13&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; * / % (Rechenoperationen) &amp;lt;/tt&amp;gt;         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;12&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; + - (binär) &amp;lt;/tt&amp;gt;                       ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;11&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;&amp;lt; &amp;gt;&amp;gt; &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;10&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt; &amp;lt;= &amp;gt; &amp;gt;= &amp;lt;/tt&amp;gt;                         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 9&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; == != &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 8&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp; (bit-AND-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 7&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ^ (bit-XOR-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 6&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; (bit-OR-Operator)&amp;lt;/tt&amp;gt;   ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 5&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp;&amp;amp; &amp;lt;/tt&amp;gt;                                ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 4&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; &amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 3&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;? : &amp;lt;/tt&amp;gt;                               ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 2&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; = += -= /= *= %= &amp;gt;&amp;gt;= &amp;lt;&amp;lt;= &amp;amp;= &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;= ^= &amp;lt;/tt&amp;gt; ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 1&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; , (Sequenz-Operator) &amp;lt;/tt&amp;gt;              ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
&lt;br /&gt;
Peter Baeumle-Courth, ANSI-C im Überblick &amp;lt;p&amp;gt;&lt;br /&gt;
W. Alex, Einführung in C/C++&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
Eine Kontrollanweisung ist eine Anweisung, die Einfluss auf den Programmfluss hat. Normalerweise werden Anweisungen so ausgeführt, wie sie in der Quelldatei stehen: Von links nach rechts (falls mehrere Anweisungen in einer Zeile stehen sollten, wovon i.A. abzuraten ist) und von oben nach unten. Mit einer Kontrollanweisung kann dieser lineare Programmfluss durchbrochen werden: Die Codeausführung kann kann abhängig von einer Bedingung gemacht werden (&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;), kann wiederholt werden (Schleife) oder an einer anderen Stelle der Funktion fortgesetzt werden (&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==if-Anweisung==&lt;br /&gt;
Mit Hilfe des if-Befehls kann man Codeteile abhängig davon einer Bedingung ausführen lassen:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
oder mit else-Teil&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 if (x &amp;gt; 100)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;gt; 100 ist: Fehlerausgabe}}&lt;br /&gt;
    printf (&amp;quot;x = %d ist zu gross fuer die Berechnung!\n&amp;quot;, x);&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;lt;&amp;amp;#61; 100 ist: Berechne Summe der Zahlen 1...x}}&lt;br /&gt;
    {{comment|Die lokale Variable x2 lebt nur innerhalb dieses alse-Blocks}}&lt;br /&gt;
    int x2 = x;&lt;br /&gt;
 &lt;br /&gt;
    for (x = 0; x2 &amp;gt; 0; x2--)&lt;br /&gt;
       x += x2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Wenn die Bedingung wahr ist (&amp;lt;tt&amp;gt;x &amp;gt; 100&amp;lt;/tt&amp;gt;), dann wird eine Meldung ausgegeben; danach ist die if-Anweisung beendet. Der else-Block wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung nicht erfüllt (&amp;lt;tt&amp;gt;x &amp;amp;le; 100&amp;lt;/tt&amp;gt;), dann wird gleich zum else-Teil gesprungen, und nach dessen Ausführung der if-Befehl beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Ein häufiger Fehler ist es, statt &amp;lt;tt&amp;gt;if (a &amp;amp;#61;&amp;amp;#61; 23)&amp;lt;/tt&amp;gt; etwas wie &amp;lt;tt&amp;gt;if (a &amp;amp;#61; 23)&amp;lt;/tt&amp;gt; zu schreiben. &lt;br /&gt;
Dann wird allerdings nicht geprüft, ob die Variable&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gleich 23 ist, sondern der Variablen&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wird der Wert 23 zugewiesen. Der Ausdruck &amp;lt;tt&amp;gt;a &amp;amp;#61; 23&amp;lt;/tt&amp;gt; hat den Wert&amp;amp;nbsp;23 und ist damit immer &amp;quot;wahr&amp;quot;! Daher ist diese if-Bedingung immer erfüllt!&lt;br /&gt;
&lt;br /&gt;
Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken sondern bestenfalls eine Warnung. Damit ist dieser Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise &amp;lt;tt&amp;gt;if (23 &amp;amp;#61;&amp;amp;#61; a)&amp;lt;/tt&amp;gt;. Wenn man dort anstatt des Vergleichsoperators '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;amp;#61;&amp;lt;/tt&amp;gt;' den Zuweisungsoperator '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;lt;/tt&amp;gt;' verwendet, spuckt der Compiler sehr wohl einen Fehler aus! Ist die Zuweisung jedoch erwünscht und eine Compiler-Warnung lästig, dann wählt man eine Schreibweise wie &amp;lt;tt&amp;gt;if ((a &amp;amp;#61; b))&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;if (a &amp;amp;#61; b, a)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist zu schreiben &amp;lt;tt&amp;gt;if (Bedingung);&amp;lt;/tt&amp;gt; Richtig muss es heissen &amp;quot;&amp;lt;tt&amp;gt;if(Bedingung)&amp;lt;/tt&amp;gt;&amp;quot; Das Semikolon im ersten Fall ist eine leere Anweisung, die im if-Falle ausgeführt wird &amp;amp;ndash; sie bleibt also ohne Resultet. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt; ein auf das Semikolon folgende Anweisung die eigentlich zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören soll wird immer ausgeführt, die sie nicht mehr zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; dazu gehört.&lt;br /&gt;
}}&lt;br /&gt;
Bei verschachtelten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Konstrukten gehört ein &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zu letzten &amp;quot;freien&amp;quot; &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;. Soll in einer &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Folge das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zum ersten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören, dann ist das so zu hinzuschreiben:&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Ohne die geschweiften Klammern um das zweite &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehörte das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; dort hinzu.&lt;br /&gt;
&lt;br /&gt;
==switch-Anweisung==&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
&lt;br /&gt;
 switch ({{Ausdruck|}}) &lt;br /&gt;
 {&lt;br /&gt;
     case konstante1:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
    &lt;br /&gt;
     case konstante2:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 &lt;br /&gt;
     {{comment|weitere case-Marken}}&lt;br /&gt;
 &lt;br /&gt;
     default:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 } {{comment|Ende von switch}} &lt;br /&gt;
&lt;br /&gt;
Der Ausdruck muss ein skalarer Typ sein, er wird in die nächste ganze Zahl gewandelt und mit den Werten hinter den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Marken verglichen. Bei einer Übereinstimmung werden alle Befehle ab dem zutreffenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; ausgeführt. Stimmt der Ausdruck mit keinem der Werte überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt falls vorhanden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der nachfolgenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;- und des &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitts werden ausgeführt, wenn die Anweisungen des &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitts nicht mit dem Befehl &amp;lt;tt&amp;gt;break;&amp;lt;/tt&amp;gt; beendet werden!&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es dürfen beliebig viele &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitte angegeben werden, pro Vergleichswert jedoch nur einer.&lt;br /&gt;
Der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ist optional. Die Reihenfolge, in der &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt; angegeben werden, ist unerheblich.&lt;br /&gt;
&lt;br /&gt;
==Schleifen==&lt;br /&gt;
Um Anweisungen mehrmals hintereinander auszuführen, benötigt man Schleifen. Diese führen Anweisungen aus, bis oder solange Bedingungen erfüllt sind.&amp;lt;br&amp;gt; &lt;br /&gt;
Wichtig ist also, ob die Bedingung '''vor''' oder '''nach''' den Schleifen-Anweisungen geprüft wird. &lt;br /&gt;
&lt;br /&gt;
===while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 while ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Die while-Schleife wird solange durchlaufen, wie die Bedingung erfüllt ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Die Anweisung kann natürlich auch ein Block sein, der aus mehreren Deklarationen und Anweisungen besteht. &lt;br /&gt;
&lt;br /&gt;
 int zahl1 = 0;&lt;br /&gt;
 int zahl2 = 1;&lt;br /&gt;
 &lt;br /&gt;
 while (zahl1 &amp;lt; 3)&lt;br /&gt;
 {&lt;br /&gt;
    zahl1 = zahl1 + 1;&lt;br /&gt;
    zahl2 = zahl2 * 2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife drei mal durchlaufen. Zu Beginn des vierten Durchlaufs ist die Bedingung nicht mehr erfüllt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
&lt;br /&gt;
===do-while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
Die do-while-Schleife wird auf jeden Fall einmal durchlaufen und dann solange wiederholt, wie die Bedingung erfüllt ist.&lt;br /&gt;
 int i = 2;&lt;br /&gt;
 &lt;br /&gt;
 do &lt;br /&gt;
 {&lt;br /&gt;
     i = i*i;   {{comment|i quadrieren}}&lt;br /&gt;
     printf (&amp;quot;i = %d\n&amp;quot;, i);&lt;br /&gt;
 }&lt;br /&gt;
 while (i &amp;lt; 20);&lt;br /&gt;
&lt;br /&gt;
Die Schleife wird durchlaufen und wiederholt, solange &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; kleiner als 20 ist. Es werden also nacheinander die Werte 2, 4 und 16 ausgegeben. Nach der Schleife hat&amp;amp;nbsp;&amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; den Wert 256.&lt;br /&gt;
&lt;br /&gt;
===for-Schleife===&lt;br /&gt;
'''Syntax:''' &lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Bei den Ausdrücken wird es sich um einen Ausdrücke mit Nebeneffekt handeln wie etwa &amp;lt;tt&amp;gt;i=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;i=i+2&amp;lt;/tt&amp;gt;. Es werden folgende Aktionen ausgeführt:&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# falls die Bedingung wahr ist, dann führe &amp;lt;tt&amp;gt;Anweisung&amp;lt;/tt&amp;gt; aus.&lt;br /&gt;
# falls die Bedingung unwahr ist, dann sprinte zu 7 (Ende).&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# gehe zu 2&lt;br /&gt;
# nächste Anweisung nach der for-Schleife&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int lauf, summe;&lt;br /&gt;
 &lt;br /&gt;
 for (lauf=1, summe=0; lauf &amp;lt;= 10; lauf += 2) &lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel ist &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; ein [[#Komma-Operator|Komma-Ausdruck]], der zwei Anweisungen kombiniert und daher sogar zwei Nebeneffente hat: er setzt &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;1 und &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;0.&lt;br /&gt;
&lt;br /&gt;
Das Äquivalent als while-Schleife:&lt;br /&gt;
&lt;br /&gt;
 int lauf  = 1;                 {{comment|Anfangswerte}}&lt;br /&gt;
 int summe = 0;&lt;br /&gt;
 &lt;br /&gt;
 while (lauf &amp;lt;= 10)             {{comment|Bedingung}}&lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
    lauf  += 2;                 {{comment|Inkrement}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; in jedem Schleifendurchlauf um die Laufvariable &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; erhöht. Da &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nacheinander die ungeraden Werte von&amp;amp;nbsp;1 bis&amp;amp;nbsp;10 annimmt, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von&amp;amp;nbsp;1 bis kleinergleich 10 gespeichert, also der Wert&amp;amp;nbsp;25. &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; hat nach der Schleife den Wert&amp;amp;nbsp;11.&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf = 1&amp;lt;/tt&amp;gt; bedeutet, dass der Variablen &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; vor dem ersten Schleifendurchlauf der Wert&amp;amp;nbsp;1 zugewiesen wird. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf &amp;lt;= 10&amp;lt;/tt&amp;gt; ist die Schleifenbedingung; ist sie nicht erfüllt, wird die Schleife beendet. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf += 2&amp;lt;/tt&amp;gt; bedeutet, dass &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nach jedem Durchlauf um&amp;amp;nbsp;2 erhöht wird.&lt;br /&gt;
&lt;br /&gt;
===continue-Anweisung===&lt;br /&gt;
Innerhalb einer Schleife darf die &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die nachfolgenden Anweisungen übersprungen werden und mit dem nächsten Schleifendurchlauf fortgesetzt wird &amp;amp;ndash; vorausgesetzt die Schleifenbedingung ist noch erfüllt. Ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; etc. stehen, wenn dieses innerhalb einer Schleife steht.&lt;br /&gt;
&lt;br /&gt;
==break-Anweisung==&lt;br /&gt;
Innerhalb einer Schleife oder eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; darf die &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die Schleifen-/Switch-Anweisung sofort verlassen wird und das Programm dahinter weiter macht. Bei mehrfach geschachtelten Schleifen wird nur die innere verlassen. Ein &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; stehen, wenn dieses innerhalb einer Schleife/Switch-Anweisung steht.&lt;br /&gt;
&lt;br /&gt;
==goto-Anweisung==&lt;br /&gt;
&lt;br /&gt;
Innerhalb ein und derselben Funktion kann mit &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; an eine andere Stelle gesprungen werden. Dazu gibt man hinter dem &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einen Bezeichner an, der dadurch als Label fungiert:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 goto {{Bezeichner}};&lt;br /&gt;
Die Bezeichner selbst steht irgendwo in der Funktion und wird dadurch zur Sprungmarke (Label), daß er von einem Doppelpunkt (und mindestens einer C-Anweisung, die auch leer sein darf) gefolgt wird.&lt;br /&gt;
&lt;br /&gt;
Das Beispiel durchsucht das 2-dimensionale &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array &amp;lt;tt&amp;gt;feld&amp;lt;/tt&amp;gt; mit den &amp;lt;tt&amp;gt;SIZE_X &amp;amp;times; SIZE_Y&amp;lt;/tt&amp;gt; Werten nach dem Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;. Wird er gefunden, dann wird die 2-fach geschachtelte Suchschleife verlassen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int x, y;&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y; y++)&lt;br /&gt;
       if (feld[x][y] == 0)&lt;br /&gt;
          goto done;&lt;br /&gt;
 {{Label|done:}};&lt;br /&gt;
&lt;br /&gt;
Der folgende Code hat die gleiche Funktion, arbeitet jedoch ohne &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int x, y;&lt;br /&gt;
 int found = 0; {{comment|FALSE}}&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X &amp;amp;&amp;amp; !found; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y &amp;amp;&amp;amp; !found; y++)&lt;br /&gt;
       found = (0 == feld[x][y]);&lt;br /&gt;
Der Nachteil der &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-losen Variante ist, daß man eine Variable, die merkt, ob das Suchziel gefunden wurde, mitschleppen und in ''jedem'' Schleifendurchlauf abtesten muss. Dies bedeutet einen höheren Programmier- und Laufzeitaufwand und ist nicht so klar formuliert wie das &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-Beispiel.&lt;br /&gt;
&lt;br /&gt;
Gleichwohl sei angemerkt, daß die Verwendung von &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einem gewissen Dogmatismus unterliegt, der sich wie folgt subsummieren liesse:&lt;br /&gt;
:''goto ist böse und sollte keinesfalls verwendet werden! Wer es dennoch tut, offenbart dadurch seinen schlechten Geschmach sowie mangelhafte C-Kenntnis.'' &amp;lt;div align=&amp;quot;right&amp;quot;&amp;gt;http://www.roboternetz.de/phpBB2/images/smiles/icon_wink.gif&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Funktionen=&lt;br /&gt;
Stellen Dir vor, Du hast eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben &amp;amp;ndash; was Dich Zeit beim Erstellen des Programms und Speicherplatz im ausführbaren Programm kostet &amp;amp;ndash; kannst Du den Code-Abschnitt in eine Funktion schreiben und diese von jeder Stelle des Programms aus verwenden. Die Hauptgründe, um Funktionen zu verwenden, sind:&lt;br /&gt;
;Wiederverwendung von Code: Mehrfach verwendete Codestücke müssen nicht mehrfach implementiert werden. Oft unterscheiden sich die Codesequenzen nur in Kleinigkeiten, die man der Funktion über Parameter mitteilen kann.&lt;br /&gt;
;Übersichtlichkeit: Ein gut gegliedertes C-Programm implementiert klar umrissene Aufgaben in einer Funktion, auch wenn diese Funktion nur einmal im Code aufgerufen wird! Dadurch bleibt der Code um die Aufrufstelle besser verständlich, und man kann auf verschiedenen &amp;quot;Ebenen&amp;quot; denken. Eine Funktion wie &amp;quot;Datei öffnen&amp;quot; kann recht komplex sein. Auf höherer Ebene interessieren die Innereien nicht mehr, man möchte sich um andere Dinge kümmern und will den Code an der Stelle garnicht sehen...&lt;br /&gt;
;Rekursive Funktionen: Eine Funktion kann sich auch selbst aufrufen. In dem Falle nennt man die Funktion ''rekursiv''. Zwar lässt sich das, was eine rekursive Funktion tut, auch mit anderen Mitteln formulieren, die keine rekursiven Funktionen brauchen, aber oft ist der rekursive Weg knackiger und klarer formulierbar als eine nicht-rekursiven Ansatz, auch wenn es etwas mehr Resourcen verbraucht.&lt;br /&gt;
;Modulare Programmierung: Funktionen können anhand ihres Aufgabenbereichs auf verschiedene C-Quellen &amp;amp;ndash; sogenannte ''Module'' &amp;amp;ndash; verteilt werden. Funktionen, die etwas mit dem USB-Bus anstellen, werden in einem anderen Modul sein als mathematische Funktionen. Dies erhöht die Übersichtlichkeit und vereinfacht die Entwicklung im Team.&lt;br /&gt;
;Bibliotheken: Standard-Funktionen wie das hier oft auftauchende &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; sind in Bibliotheken gespeichert. Wenn das eigene Programm übersetzt wird, dann müssen nicht mehr alle Standard-Funktionen übersetzt werden, sondern werden nur noch aus der Bibliothek gelesen und ihr Code zum Programm dazugelinkt. Die Bibliotheks-Funktionen wurden schon zu einem früheren Zeitpunkt compiliert und liegen in dieser compilerten Form in der Bibliothek. Das spart mächtig Entwicklungszeit. Man kann auch selbst solche Bibliotheken erstellen und in diversen Projekten wiederverwenden.&lt;br /&gt;
;Generische Programmierung: In C ist es möglich, einer Funktion eine andere Funktion zu übergeben. (Damit ist nicht gemeint, ihr deren ''Rückgabewert'' zu übergeben (was auch ginge), sondern ''die Funktion selbst'' wird als Parameter übergeben und kann aufgerufen werden.) Ein typisches Beispiel dafür sind Sortieralgorithmen. Einem Sortieralgorithmus kann es egal sein, ''was'' er sortiert. Er muss lediglich wissen, ''wie'' er das Zeug zu sortieren hat: aufsteigend, absteigend, als Zahl, in lexikographischer Ordnung, nach der Quersumme, Körper nach Oberfläche, Durchmesser, Gewicht oder Volumen... Diese Vergleichsfunktion, die für zwei Objekte entscheidet, welches davon &amp;quot;kleiner&amp;quot; ist, kann man dem Sortierer übergeben. Will er zwei Werte vergleichen, dann muss er nur die Vergleichsfunktion aufrufen, ohne zu wissen, was diese tut. Damit kann der Sortieralgorithmus unanhängig von den Objekten gehalten werden, mit denen er hantieren soll.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Definition==&lt;br /&gt;
&lt;br /&gt;
In der ''Definition'' der Funktion wird gesagt, welche Werte sie liefern kann, wie sie heisst (Bezeichner) und wieviele und welche Parameter sie hat. Danach folgt ihre Implementierung:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}} ({{Parameterliste}})&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 &lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
Für Funktionen, die keinen Wert zurückliefern, gibt es den speziellen Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der besagt, daß die Funktion nichts zurückgibt. Die einfachste denkbare Funktion ist eine solch void-Funktion. Sie bekommt keine Parameter, gibt nicht zurück und ihr Body ist leer:&lt;br /&gt;
 void dummy()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==return-Anweisung==&lt;br /&gt;
An jeder Stelle des Programmflusses einer Funktion kann diese mit &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; beendet werden.&lt;br /&gt;
&lt;br /&gt;
'''bei void-Funktionen:'''&lt;br /&gt;
 return;&lt;br /&gt;
'''Funktionen mit Rückgabe-Wert:'''&lt;br /&gt;
 return {{Ausdruck|}};&lt;br /&gt;
Die zweite Variante gibt an, welcher Wert zurückgegeben wird.&lt;br /&gt;
 int main (int argc, char * argv[])&lt;br /&gt;
 {&lt;br /&gt;
    if (argc &amp;lt; 2)&lt;br /&gt;
       return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
Falls die letzte Anweisung einer void-Funktion ein &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; ist, kann es auch weggelassen werden wie oben bei der Funktion &amp;lt;tt&amp;gt;dummy&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Aufruf==&lt;br /&gt;
Um die Funktion aufzurufen gibt man ihren Namen an, gefolgt von den durch Komma getrennten Argumenten in runden Klammern wie im Beispiel unten das&lt;br /&gt;
 quadrat (5) &lt;br /&gt;
Da &amp;lt;tt&amp;gt;quadrat&amp;lt;/tt&amp;gt; einen Wert liefert, kann man damit weiter rechnen wie mit einem normalen Ausdruck:&lt;br /&gt;
 if (quadrat (a) + quadrat (b) == quadrat (c))&lt;br /&gt;
    c = quadrat (quadrat (a)); {{comment|c &amp;amp;#61; a hoch 4}}&lt;br /&gt;
&lt;br /&gt;
Ein Hinweis am Rande: &amp;lt;p&amp;gt; &lt;br /&gt;
Der Name einer Funktion ohne die beiden runden Klammern ist der Pointer/Zeiger auf ihren Anfang.&lt;br /&gt;
Damit kann ein Funktionsname überall dort verwendet werden, wo Pointer/Zeiger &lt;br /&gt;
zulässig sind. Insbesondere kann er als Argument einer weiteren Funktion dienen. &amp;lt;p&amp;gt; &lt;br /&gt;
&lt;br /&gt;
'''Quelle:'''&lt;br /&gt;
W. Alex, Einführung in C/C++&lt;br /&gt;
&lt;br /&gt;
==Rekursive Funktionen==&lt;br /&gt;
Eine Funktion die sich selbst &amp;amp;ndash; möglicheweise auch über andere Zwischenfunktionen &amp;amp;ndash; wieder selbst aufruft, wird als ''rekursive Funktion'' bezeichnet. In der Definition ist nichts besonderes zu beachten. Ist die Verschachtelungstiefe im laufenden Programm zu tief, dann gibt das natürlich Probleme, aber das gilt bei tief verschachtelten 'normalen' Funktionen abenso...&lt;br /&gt;
&lt;br /&gt;
Das Beispiel berechnet den Größten Gemeinsamen Teiler zweier Zahlen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int ggT (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
     if (0 == a)&lt;br /&gt;
        return b;&lt;br /&gt;
 &lt;br /&gt;
    return ggT (b % a, a);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Ein komplettes kleines Programm:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int quadrat (int param1)&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  zahl = param1 * param1;&lt;br /&gt;
  return zahl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl, ergebnis;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Bitte Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = quadrat (zahl);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, zahl, ergebnis);&lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, 5, quadrat (5));&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur ausserhalb von Blöcken. Geschachtelte Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen beim Aufruf die Klammern angeben werden:&lt;br /&gt;
 dummy();&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Prototypen==&lt;br /&gt;
Wie oben erwähnt, kann ein Unterprogramm an jeder beliebigen Stelle im Programm stehen. Damit ist jedoch eine Bedingung verknüpft: Das Unterprogramm muß in der Datei oberhalb des ersten Aufrufes definiert worden sein. Wenn Sie ein Unterprogramm in Zeile 10 zum ersten mal aufrufen, müssen Sie die Deklaration davor erledigt haben. Verstanden?&lt;br /&gt;
Um dies zu erreichen, gibt es zwei Möglichkeiten: &lt;br /&gt;
&lt;br /&gt;
Entweder Sie schreiben alle Unterprogramme vor &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; in die Datei. Dies muß jedoch wiederum so geschehen, dass Funktionen zum Zeitpunkt ihres Aufrufes bereits bekannt sind! &lt;br /&gt;
Wo dies nicht möglich ist (z.B. sich gegenseitig aufrufende Unterprogramme), oder wenn Sie das stört, müssen Sie Prototypen verwenden. &lt;br /&gt;
Wie definiert man nun Prototypen? Sie kopieren einfach die erste Zeile des Unterprogrammes (z.B. &amp;quot;&amp;lt;tt&amp;gt;void ausgeben (int zahl)&amp;lt;/tt&amp;gt;&amp;quot;), fügen einen Strichpunkt&amp;amp;nbsp;&amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;an und fügen es an einer geeigneten Stelle ein (so, dass alle Aufrufe später in der Datei kommen). &lt;br /&gt;
Solche Definitionen stehen gewöhnlich am Anfang der Quelldatei oder in einer Header-Datei, die eingebunden wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl);  /* Der Prototyp */&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
   ausgeben (12);&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl)   /* Die eigentliche Prozedur */&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Ausgabe: %d\n&amp;quot;, zahl);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Parameterübergabe==&lt;br /&gt;
&lt;br /&gt;
Alle Werte, die an Prozeduren und Funktionen übergeben werden, werden grundsätzlich '''kopiert'''.&lt;br /&gt;
Das hat folgende Auswirkungen:&lt;br /&gt;
&lt;br /&gt;
# Änderungen an einem Parameter in einer Funktion erscheinen ''nicht'' beim Aufrufer!&lt;br /&gt;
# Möchte man, dass eine Funktion einen Wert trotzdem dauerhaft ändern soll, so muss die Adresse des Wertes via [[#Zeiger|Zeiger]] übergeben werden.&lt;br /&gt;
# Werden [[#Strukturen|Strukturen]] übergeben, so wird von ihnen eine Kopie erstellt, was bei großen Strukturen viel Zeit und Arbeitsspeicher kostet. Deshalb wird häufig nur die Adresse von Strukturen übergeben, da die Adresse viel schneller und platzsparender als die Struktur selbst kopiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele:'''&lt;br /&gt;
 void erhoehe (int x)&lt;br /&gt;
 {&lt;br /&gt;
    x = x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe(a);&lt;br /&gt;
    {{comment|a ist immer noch 0}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Beim Aufruf von &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; wird eine Kopie des Wertes von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; (im Beispiel also 0) erstellt und der Prozedur als Parameter &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; übergeben. Weil dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat dies keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|erhoehe den Wert an der Adresse x um eins}}&lt;br /&gt;
    *x = *x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe (&amp;amp;a);&lt;br /&gt;
    {{comment|a ist jetzt 1}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Jetzt wird im Hauptprogramm mittels [[#Adress-Operator und Dereferenzierung|Adress-Operator]] &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; die Speicheradresse von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; bestimmt. Dann wird eine ''Kopie der Adresse'' an das Unterprogramm &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; übergeben. Jetzt kennt das Unterprogramm die&lt;br /&gt;
Adresse des Originals &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und kann direkt mit dem Inhalts-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&lt;br /&gt;
'''Besonderheit bei Feldern'''&lt;br /&gt;
&lt;br /&gt;
Bei der Übergabe von [[#Felder|Feldern]] gibt es eine Besonderheit. Schreibt man nämlich den Namen eines Feldes, so ist das nichts anderes als die '''Speicheradresse des ersten Elements'''.&lt;br /&gt;
Bei der Übergabe eines Feldes wird also eine Kopie der Startadresse übergeben. Somit kann das Unterprogramm auf den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 void erhoehe (int x[])&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
   int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
   erhoehe (a);&lt;br /&gt;
   {{comment|a hat jetzt folgenden Inhalte: 11, 23, 35}}&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Dass die Übergabe einer Adresse erfolgt, sieht man an folgendem Beispiel, das von der Funktionsweise '''absolut identisch''' mit dem vorhergehenden ist:&lt;br /&gt;
&lt;br /&gt;
 {{comment|Bei Parametern gibt es keinen Unterschied zwischen Zeiger und Feld}}&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
    int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
    erhoehe (a);&lt;br /&gt;
 &lt;br /&gt;
    {{comment|a hat jetzt folgenden Inhalt: 11, 23, 35}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
Die Länge des Feldes wird nicht automatisch übergeben. Dafür ist ggf. ein zusätzlicher Parameter notwendig.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Variable Argumentanzahl==&lt;br /&gt;
== Funktionen indirekt aufrufen ==&lt;br /&gt;
Siehe [[#Zeiger auf Funktionen|Zeiger auf Funktionen]]&lt;br /&gt;
&lt;br /&gt;
=Zeiger II=&lt;br /&gt;
&lt;br /&gt;
Zeiger haben wir bereits weiter oben kennen gelernt. Zeiger sind ein zentrales Konzept in C und sollen hier etwas eingehender behandelt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger-Arithmetik==&lt;br /&gt;
In C kann man den Wert eines Zeigers verändern. Betrachten wir dazu die Funktion &amp;lt;tt&amp;gt;suche_0&amp;lt;/tt&amp;gt;, die einen Zeiger auf einen &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; erhält. Die Funktion soll ab der gegebenen Adresse nach dem ersten long-Wert suchen, der 0 ist, und dessen Adresse zurückgeben:&lt;br /&gt;
 long * suche_0 (long * addr)&lt;br /&gt;
 {&lt;br /&gt;
    while (*addr != 0)&lt;br /&gt;
       addr = addr + 1;&lt;br /&gt;
 &lt;br /&gt;
    return addr;&lt;br /&gt;
 }&lt;br /&gt;
In der Bedingung der while-Schleife wird der Inhalt an der Speicherstelle &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf 0 getestet. Ist der Wert 0, dann wird die Schleife beendet und die Adresse zurückgeliefert. Ist der Wert ungleich 0, dann wird &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf den nächste long gesetzt, &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; also um 4 Bytes weitergezählt. &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ist ja ein Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, und ein &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; ist 4 Bytes lang.&lt;br /&gt;
&lt;br /&gt;
Die Bedeutung von&lt;br /&gt;
 address + n&lt;br /&gt;
ist also, die Adresse um das &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;-fache der Größe des Typs, auf den &amp;lt;tt&amp;gt;address&amp;lt;/tt&amp;gt; zeigt, zu erhöhen. Dabei ist &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; eine ganze Zahl und darf auch negativ sein.&lt;br /&gt;
&lt;br /&gt;
Hier noch ein Beispiel einer Funktion, die nach einer Person mit einer bestimmten ID sucht (für die Definition von &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; siehe [[#Strukturen|Strukturen]]). Der Parameter &amp;lt;tt&amp;gt;person&amp;lt;/tt&amp;gt; ist dabei ein Array von Strukturen. Eine Person mit der gesuchten ID muss existieren, ansonsten hat die Suchfunktion kein definiertes Verhalten.&lt;br /&gt;
 {{comment|Sucht nach einer Person mit der ID person_id}}&lt;br /&gt;
 struct Person * &lt;br /&gt;
 suche_person_id (struct Person * person, int person_id)&lt;br /&gt;
 {&lt;br /&gt;
    while (person-&amp;gt;id != person_id)&lt;br /&gt;
       person++;&lt;br /&gt;
 &lt;br /&gt;
    return person;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:1em; padding:1em; border:solid 2px #FF0040;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- Vorlage:FarbigerRahmen funzt hier net --&amp;gt;&lt;br /&gt;
Beachte, daß es nicht sinnvoll ist, zwei Zeiger zu addieren oder zu multiplizieren. Ausserdem ist das &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt; der Zeiger-Arithmetik nicht kommutativ. Eine Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, der an Adresse 1 im Speicher zeigt, wird man schreiben als&lt;br /&gt;
 (long *) 1&lt;br /&gt;
Addiert man darauf eine ganze Zahl, dann haben die entstehenden Ausdrücke unterschiedliche Werte:&lt;br /&gt;
 (long *) 1 + 2    {{comment|zeigt zu Adresse 9}}&lt;br /&gt;
 (long *) 2 + 1    {{comment|zeigt zu Adresse 6}}&lt;br /&gt;
 (long *) (1 + 2)  {{comment|zeigt zu Adresse 3}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==void-Pointer==&lt;br /&gt;
Eine besondere Art von Zeiger ist der void-Pointer&lt;br /&gt;
 void * addr;&lt;br /&gt;
Ein void-Pointer ist ein &amp;quot;Zeiger auf irgendwas&amp;quot;, dementsprechend kann er nicht dereferenziert werden, Anwenden von &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf einen solchen Zeiger gibt also einen Fehler. Ausserdem ist es nicht möglich, mit einem void-Pointer Zeigerarithmetik zu machen, weil er nicht auf eine definierte Art von Objekt zeigt. Der Vorteil eines void-Pointers ist, daß er jede Art von Zeiger aufnehmen kann.&lt;br /&gt;
&lt;br /&gt;
Dazu betrachten wir die Funktion &amp;lt;tt&amp;gt;send_buf&amp;lt;/tt&amp;gt;, die eine Adresse erhält und ab dieser Adresse &amp;lt;tt&amp;gt;num&amp;lt;/tt&amp;gt; Bytes versenden soll. Wir könnten die Funktion so schreiben:&lt;br /&gt;
 void send_buf (unsigned char * buf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   ...&lt;br /&gt;
Das ist jedoch hässlich, wenn wir damit etwas anderes verschicken wollen als &amp;lt;tt&amp;gt; unsigned char&amp;lt;/tt&amp;gt;, etwa eine Struktur wie &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; (vom Typ &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;):&lt;br /&gt;
 send_buf ((unsigned char*) &amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
Ohne den Cast der Adresse von &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; zu einem Zeiger auf &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt; bekommt man eine Warnung oder gar einen Compilerfehler.&lt;br /&gt;
Dieses Zeiger gecaste ist mühsam und hässlich, es muss bei jedem Aufruf der Funktion explizit hingeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Besser ist es, den ersten Parameter der Funktion als void-Pointer zu definieren und den Cast in der Funktion zu machen:&lt;br /&gt;
 void send_buf (void * vbuf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   unsigned char *buf = (unsigned char*) vbuf;&lt;br /&gt;
   ...&lt;br /&gt;
Durch den Cast in der Funktion kann auf den Inhalt des Zeigers zugegriffen werden. Man muss nur festlegen, ''wie'' man zugreifen will, nämlich als &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Der Aufruf kann jetzt ohne Pointer-Cast erfolgen: &lt;br /&gt;
 send_buf (&amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
&lt;br /&gt;
==Null-Pointer==&lt;br /&gt;
==Zeiger als Parameter==&lt;br /&gt;
Wenn Sie ein Unterprogramm aufrufen, können Sie diesem Parameter übergeben, aber keine Werte zurückgekommen (außer den Funktionswert bei Funktionen). Dies hat einen guten Grund: beim Aufruf werden nicht die aufgerufenen Parameter benutzt, sondern es werden deren Werte in neue Variablen kopiert. Diese Variablen werden am Ende des Unterprogrammes &amp;quot;zerstört&amp;quot;, ohne ihre Werte an die aufrufenden Parameter zu übergeben. Jede Veränderung eines Parameters hat daher keine Auswirkung auf den Parameter.&lt;br /&gt;
&lt;br /&gt;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der C-Compiler legt dann immer noch Kopien an. In dieser Kopie steht aber kein Wert, sondern die Adresse einer Varaiblen. Und auf diese können Sie dann zugreifen. Denken Sie nur an &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; &amp;amp;ndash; da übergeben Sie ja auch die Adresse einer Variablen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void erhoehe (int *zeiger)&lt;br /&gt;
{&lt;br /&gt;
  *zeiger = 1 + *zeiger;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  erhoehe (&amp;amp;zahl);&lt;br /&gt;
  printf (&amp;quot;\nDie erhoehte Zahl lautet: %d\n&amp;quot;, zahl);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Zeiger auf Funktionen==&lt;br /&gt;
&lt;br /&gt;
Stell dir vor, du willst einen Sortieralgorithmus wie Bubble-Sort oder Quick-Sort oder wie sie alle heissen implementieren. Für den Sortieralgorithmus ist eigentlich egal, ''was'' er zu sortieren hat. Ihm ist es egal, ob er Zahlen aufwärts sortieren soll oder Strings in lexikographischer Reihenfolge, ob Objekte nach Größe oder Gewicht, Personen nach Alter oder Adressen nach Postleitzahl. Das einzige, was der Algorithmus wissen muss, ist ''wie'' er zwei Objekte zu vergleichen hat und wann eines davon &amp;quot;kleiner&amp;quot; (im Sinne der Ordnung, nach der sortiert werden soll) ist. &lt;br /&gt;
&lt;br /&gt;
Eine einfache Sortierfunktion, die nur zwei Zahlen sortiert, könnte man also so schreiben: &lt;br /&gt;
 {{comment|Sortiert ein Array von 2 int-Zeigern nach den Inhalten &lt;br /&gt;
  * an den Zeiger-Adressen}}&lt;br /&gt;
 void sort2_a (int * p[])&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Inhalte vergleichen...}}&lt;br /&gt;
    if (*p[0] &amp;gt; *p[1])&lt;br /&gt;
    {&lt;br /&gt;
       {{comment|... und ggf. Dreieckstausch der 2 Zeiger}}&lt;br /&gt;
       int * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Die Funktion bekommt ein Array der Länge&amp;amp;nbsp;2. In diesem Array stehen Zeiger auf die zu sortierenden Zahlen. Ein Array mit Zeigern zu verwenden und nicht ein Array von &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; scheint recht umständlich, und das ist es hier auch. Aber stell dir vor, du willst Strukturen wie &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; sortieren. Das Tauschen zweier Strukturen würde bedeuten, ihre kompletten Inhalte umzukopieren! Das wäre sehr aufwändig. Viel einfacher ist das Kopieren, wenn nur die Adressen zu kopieren sind.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; könnte dann so aussehen:&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void sortiere (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|p[] enthält 2 int-Zeiger: die Adressen von a und b}}&lt;br /&gt;
    int * p[2];&lt;br /&gt;
    p[0] = &amp;amp;a; &lt;br /&gt;
    p[1] = &amp;amp;b; &lt;br /&gt;
 &lt;br /&gt;
    {{comment|Sortiere die Zeiger}} &lt;br /&gt;
    sort2_a (p);&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Sortiert: %d, %d\n&amp;quot;, *p[0], *p[1]);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Für den nächsten Schritt überlegen wir uns, daß das Array in &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; ebensogut void-Pointer enthalten kann. Die einzige Stelle, an der wir auf die endgültigen int-Objekte zugreifen, ist der Vergleich. Diesen Vergleich lagern wir in die Funktion &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; aus:&lt;br /&gt;
 {{comment|Bekommt zwei void-Pointer und vergleicht die Inhalte.&lt;br /&gt;
  * Liefert 0 bei Gleichheit,&lt;br /&gt;
  * -1 wenn der erste Wert kleiner ist als der zweite und&lt;br /&gt;
  * 1  wenn der erste Wert größer ist als der zweite}}&lt;br /&gt;
 int compare_int (void * p0, void * p1)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Um über die Zeiger zugreifen zu können müssen wir diese&lt;br /&gt;
     * erst zu int-Zeigern casten}}&lt;br /&gt;
    int a0 = * (int*) p0;&lt;br /&gt;
    int a1 = * (int*) p1;&lt;br /&gt;
 &lt;br /&gt;
    if (a0 &amp;gt; a1)  return  1;&lt;br /&gt;
    if (a0 &amp;lt; a1)  return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void sort2_b (void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare_int (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Ein Aufruf von &amp;lt;tt&amp;gt;sort2_b&amp;lt;/tt&amp;gt; sieht dann genauso aus wie ein Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt definieren wir uns den neuen Datentyp &amp;lt;tt&amp;gt;comparator_t&amp;lt;/tt&amp;gt;. Dieser ist ein Zeiger auf eine Funktion, die zwei void-Pointer erhält und einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; zurückliefert, also analog arbeitet zu &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; von oben. &lt;br /&gt;
&lt;br /&gt;
Unsere Sortierfunktion bekommt nun neben dem zu sortierenden Zeiger-Array auch eine Vergleichsfunktion &amp;lt;tt&amp;gt;compare&amp;lt;/tt&amp;gt; mitgeliefert, die sie aufruft, wenn sie zwei Objekte vergleichen will&lt;br /&gt;
 {{comment|comparator_t sind Zeiger auf Funktionen, die 2 void-Pointer&lt;br /&gt;
  * erhalten und einen int zurückliefern}}&lt;br /&gt;
 typedef int (*comparator_t) (void*, void*);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Der Sortierer bekommt einen Funktionszeiger auf den Vergleicher.&lt;br /&gt;
  * Der Aufruf vom compare geht so als wäre es eine &amp;quot;normale&amp;quot; Funktion&lt;br /&gt;
  * (ist es im Endeffekt ja auch)}}&lt;br /&gt;
 void sort2_c (comparator_t compare, void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Bei einem Aufruf von &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; muss man dann einen Komparator mit angeben. In einem Beispiel analog zu &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; von oben ist das:&lt;br /&gt;
 sort2_c (compare_int, p);&lt;br /&gt;
Um zwei Strings lexikographisch zu sortieren nehmen wie die Standard-Funktion &amp;lt;tt&amp;gt;strcmp&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void foo()&lt;br /&gt;
 {&lt;br /&gt;
    char * worte[] = { &amp;quot;Wort1&amp;quot;, &amp;quot;Wort2&amp;quot; };&lt;br /&gt;
 &lt;br /&gt;
    sort2_c ((comparator_t) strcmp, (void**) worte);&lt;br /&gt;
 }&lt;br /&gt;
Die Casts sind hier erforderlich. Alternativ könnte man &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; mit reinen void-Pointern versorgen und diese dann dort umcasten.&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
&lt;br /&gt;
Die Syntax zur Definition/Deklaration von Funktionszeigern ist etwas verzwackt. Zur Verdeutlichung ein paar Beispiele. Dabei legt das linke &amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt; jeweils den Return-Typ fest.&lt;br /&gt;
 {{comment|definiert einen neuen Funktionszeiger-Typ}}&lt;br /&gt;
 typedef {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert einen Funktionszeiger}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert ein Array von Funktionszeigern (mit Initializer)}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}[]) ({{type}}, {{type}}, ...) = { wert1, wert2, ... };&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer}}&lt;br /&gt;
 ({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer und ruft die Funktion auf}}&lt;br /&gt;
 (({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}) (arg1, arg2, ...);&lt;br /&gt;
&lt;br /&gt;
=Standard-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==String-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===strcpy===&lt;br /&gt;
Bei vielen Compilern können sie einem String nicht direkt einen Wert (Text) zuweisen. Dazu müssen Sie dann die Prozedur strcpy() benutzen. Diese erwartet als ersten Parameter den Namen einer String-Variablen (ohne eckige Klammern) und als zweiten Parameter den eines (anderen) Strings. Letzterer kann auch ein in doppelten Hochkommas (&amp;quot;) eingeschlossener Text sein. Die Funktion fügt am Ende automatisch ein 0-Zeichen ein. Um diese Funktion nutzen zu können, müssen Sie die Datei string.h includieren! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri1[21], eingabe[21];&lt;br /&gt;
&lt;br /&gt;
  strcpy (stri1, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Der 1. String: %s\n&amp;quot;, stri1);&lt;br /&gt;
  printf (&amp;quot;Bitte geben Sie maximal 20 Zeichen ein: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%s&amp;quot;, eingabe);&lt;br /&gt;
  strcpy (stri1, eingabe);&lt;br /&gt;
  printf (&amp;quot;\n%s = %s&amp;quot;, stri1, eingabe);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis:''' &lt;br /&gt;
Da ein String, wie jedes Feld, eigentlich ein Zeiger ist, dürfen Sie kein &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; bei &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; angeben!&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
Es werden zwei gleich große Strings definiert: &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;eingabe&amp;lt;/tt&amp;gt;, mit je 20 &amp;quot;nutzbaren&amp;quot; Zeichen. &lt;br /&gt;
In &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; wird die Zeichenkette &amp;lt;tt&amp;gt;&amp;quot;hallo&amp;quot;&amp;lt;/tt&amp;gt; hineinkopiert. Das 0-Zeichen am Ende wird automatisch angefügt. &lt;br /&gt;
Der String wird ausgegeben. Als neues &amp;quot;Sonderzeichen&amp;quot; kommt &amp;lt;tt&amp;gt;%s&amp;lt;/tt&amp;gt; ins Spiel. Es hat die gleiche Aufgabe wie &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt;, nur für Strings. &lt;br /&gt;
Sie werden gebeten, eine String einzugeben. &lt;br /&gt;
Dieser String wird danach in die Variable &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; kopiert. &lt;br /&gt;
Beide Strings, die ja nun die gleiche Zeichenkette enthalten, werden ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===strlen===&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;strlen&amp;lt;/tt&amp;gt;, die als Parameter eine String-Variable erwartet, liefert die Länge diese Strings zurück. Sie werden jetzt vermutlich sagen: &amp;quot;Das ist doch klar, wie lang der String ist. Ich habe es ja bei der Deklaratin angegeben&amp;quot;. Das stimmt schon, aber denken Sie noch einmal an die null-terminierten Strings. Das 0-Zeichen steht am Ende des Strings (am Ende der gültigen Zeichenfolge), aber nicht unbedingt am Ende des reservierten Speicherplatzes. Haben Sie eine Variable &amp;quot;char Variable[21];&amp;quot;, und ihr den Wert &amp;quot;hallo&amp;quot; zugewiesen, dann steht das null-Zeichen in Variable[5]. Der &amp;quot;gültige&amp;quot; String ist also 5 Zeichen (0-4) lang. Und genau das (5) würde strlen zurück liefern. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri[21];&lt;br /&gt;
  &lt;br /&gt;
  strcpy (stri, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
  printf (&amp;quot;Der String ist %d Zeichen lang&amp;quot;, strlen (stri));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird vor allem gebraucht, wenn Sie direkt auf den String zugreifen, mittels &amp;lt;tt&amp;gt;stri[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;stri[1]&amp;lt;/tt&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
==Ein- und Ausgabe-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===Bildschirm-Ausgabe===&lt;br /&gt;
Bisher war das Tutorial trotz aller Beispiele reine Theorie. Sie konnten zwar Programme schreiben, aber die Funktion nicht testen. Hier lernen Sie nun, wie Sie etwas am Bildschirm ausgeben.&lt;br /&gt;
&lt;br /&gt;
Die dazu notwendige Funktione heisst &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (das '&amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt;' ist kein Fehler!). Diese Anweisung gibt die ihr übergebenen Parameter auf das Standard-Ausgabegerät aus, in der Regel also auf den Bildschirm. Sie kann beliebig viele Parameter übernehmen. Es müssen jedoch Standard-Datentypen (z.B. &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;...) sein! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
    int zahl1 = 12;&lt;br /&gt;
    char zeichen1 = 'A';&lt;br /&gt;
    &lt;br /&gt;
    printf (&amp;quot;Das ist Text, und er wird als solcher ausgegeben. \n&amp;quot;);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zahl1' ist: %d \n&amp;quot;, zahl1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %c \n&amp;quot;, zeichen1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %d \n&amp;quot;, zeichen1);&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt Text aus. Das Zeichen am Ende (&amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;) bedeutet &amp;quot;New Line&amp;quot;, es bewegt den Cursor an den Anfang der nächsten Zeile. &lt;br /&gt;
&lt;br /&gt;
Der zweite &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt auch Text aus, am Ende befindet sich wieder das &amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;, um einen Zeilenvorschub zu erreichen. Das &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; wird vom Compiler durch den ersten Parameter ersetzt, der nach dem Text angegeben wird. In diesem Fall wird &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; also durch den Wert der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ersetzt. Das &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; im &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; bedeutet &amp;quot;Dezimalzahl&amp;quot;, der Computer gibt also eine ganze Zahl aus. &lt;br /&gt;
&lt;br /&gt;
In der dritten Ausgabe wird ein Zeichen ausgegeben. Diesmal bedeutet &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; &amp;quot;char&amp;quot; (Zeichen). Es wird also &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; durch ein &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt; ersetzt, denn die Variable &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; wird als Character interpretiert. &lt;br /&gt;
&lt;br /&gt;
Die letzte Ausgabe interpretiert den Inhalt von &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; als Zahl, und gibt dager den ASCII-Wert von &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, also 65 aus. Das ist ein typisches Beispiel für das mögliche unterschiedliche Interpretieren einer  Variablen!&lt;br /&gt;
&lt;br /&gt;
===Tastatur-Eingabe===&lt;br /&gt;
&lt;br /&gt;
Um ein &amp;quot;gscheites&amp;quot; Programm schreiben zu können, muß man wissen, wie der Benutzer über die Tastatur Befehle eingeben kann. Die dafür notwendigen Funktionen stelle ich in diesem Kapitel vor.&lt;br /&gt;
Die wichtigste Funktion ist &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt;. Er liest Daten von der Tastatur. Die Syntax entspricht derer von &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int  zahl1;&lt;br /&gt;
char zeichen1;&lt;br /&gt;
&lt;br /&gt;
printf (&amp;quot;Bitte geben Sie eine Zahl ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl1);&lt;br /&gt;
printf (&amp;quot;Geben Sie einen Zeichen ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%c&amp;quot;, &amp;amp;zeichen1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Programm gibt eine Eingabeaufforderung aus. Dann erwartet es vom Benutzer, daß er eine Zahl eingibt, die mit [ENTER] bestätigt wird. Dieser Wert wird in &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; abgespeichert. Danach erfolgt wiederum eine Aufforderung zur Eingabe, diesmal eines einzelnen Zeichens. Dieses kann man nun eingeben und ebenfalls mit [ENTER] bestätigen.&lt;br /&gt;
&lt;br /&gt;
Macht man keine dem Datentyp der erwarteten Variable entsprechende Eingabe, dann bricht das Programm mit einer Fehlermeldung ab (wenn man z.B. &amp;quot;1_T2&amp;quot; eingibt, wenn eine Zahl erwartet wird)!&lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; vor den Parametern ist notwendig. Warum, das erfahren Sie im Kapitel &amp;quot;Unterprogramme&amp;quot;. Für die Profis eine Kurz-Erklärung: Das Unterprogramm &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; bekommt zwar einen Wert übergeben, kann aber keinen zurückliefern (&amp;quot;call by value&amp;quot;). Daher wird kein Wert, sondern ein Zeiger auf eine Variable übergeben. Mit dem &amp;amp; Zeichen bekommen Sie die Adresse einer Variablen (&amp;quot;call by reference&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=Parameter von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;=&lt;br /&gt;
Das Unterprogramm &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; kann, wie jede andere Funktion, Parameter besitzen. Doch keine selbst gewählten, sondern nur bestimmte. Doch warum braucht main Parameter? Denken Sie einmal an alle Betriebssystembefehle:&lt;br /&gt;
&amp;lt;tt&amp;gt;dir *.exe &amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;copy *.* a:&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;ls -la &amp;lt;/tt&amp;gt;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;&amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen!&lt;br /&gt;
&lt;br /&gt;
=Kurzreferenz=&lt;br /&gt;
==Syntax-Bausteine==&lt;br /&gt;
&lt;br /&gt;
Die Erklärung des Aufbaus von C-Befehlen erfolgt neben einfachen Beispielen auch durch ihren prinzipellen Aufbau. In diesen Syntax-Beschreibungen finden sich immer wieder die gleichen Bausteine, die hier näher erklärt werden sollen. Falls die solch ein Syntax-Baustein begegnet, kannst Du ihn anclicken und kommst dann zu seiner Erläuterung. &lt;br /&gt;
&lt;br /&gt;
In den Beispielen selbst gehören auch die spitzen Klammern zu dem Baustein (was daran zu erkennen ist, daß auch die Klammern eingefärbt sind). Die Klammern dürfen in einem konkreten C-Programm daher nicht eingetippt werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bezeichner&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Bezeichner in C dienen dazu, Variablen zu identifizieren und ihnen sprechende Namen zu geben, um die Quelle lesbarer zu machen. Man braucht Bezeichner auch, um selbstdefinierte Datentypen zu benennen und zum Benennen von Struct- und Union-Komponenten sowie als Namen für Funktionen und Sprungmarken (Labels).&lt;br /&gt;
&lt;br /&gt;
Bezeichner dürfen aus den Kleinbuchstaben &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;z&amp;lt;/tt&amp;gt;, den Großbuchstaben &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;Z&amp;lt;/tt&amp;gt;, dem Unterstrich&amp;amp;nbsp;&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt; und den Ziffern &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;9&amp;lt;/tt&amp;gt; aufgebaut werden, wobei an erster Stelle jedoch keine Ziffer stehen darf.&lt;br /&gt;
&lt;br /&gt;
Es wird zwischen Groß- und Kleinschreibung unterschieden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Ausdruck in C ist ein Konstrukt, das einen Wert hat. Ob dieser Wert eine ganze Zahl ist, eine Kommazahl oder ein Zeiger, etc. ist dabei egal. Die einfachsten Ausdrücke sind Konstanten wie&lt;br /&gt;
 2&lt;br /&gt;
oder Variablen wie&lt;br /&gt;
 ein_zahl&lt;br /&gt;
Mehrere Ausdrücke können durch [[#Liste der Operatoren|Operatoren]] zu komplexeren Ausdrücken kombiniert werden, etwa&lt;br /&gt;
 eine_zahl + andere_zahl == 2&lt;br /&gt;
oder &lt;br /&gt;
 eine_zahl = 2&lt;br /&gt;
Letzterer hat den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; und den Nebeneffekt, daß er diesen Wert an &amp;lt;tt&amp;gt;eine_zahl&amp;lt;/tt&amp;gt; zuweist.&lt;br /&gt;
&lt;br /&gt;
Auch der Aufruf einer Funktion, die einen Rückgabewert liefert, ist ein Ausdruck:&lt;br /&gt;
 sin (1.2)&lt;br /&gt;
und kann zum Aufbau komplexerer Ausdrüche verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bedingung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Bedingung ist ein Ausdruck, bei der nur interessiert, ob dieser zu&amp;amp;nbsp;0 (unwahr) auswertet oder zu ungleich&amp;amp;nbsp;0 (wahr). Solche Ausdrücke findet man in if-Anweisungen, in Schleifenbedingungen und bedingten Zuweisungen&lt;br /&gt;
 (ein_wert &amp;lt; 2) || (ein_wert &amp;gt; 40)&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Lvalue ist ein Ausdruck, dem etwas zugewiesen werden kann. Der Name ''Lvalue'' kommt aus dem Englischen. Das ''L'' steht abkürzend für left. Ein Lvalue ist damit ein Ausdruck, der auf der linken Seite eine Zuweisung in C stehen darf. Das &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; in den folgenden Beispiel-Ausdrücken muss ein Lvalue sein:&lt;br /&gt;
 x = y-1&lt;br /&gt;
&lt;br /&gt;
 x++&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Konstante&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Konstante ist ein Ausdruck, dessen Wert dem Compiler bekannt ist. Beispiele für Konstanten sind etwa&lt;br /&gt;
 7&lt;br /&gt;
 'B'&lt;br /&gt;
 -13.98e12&lt;br /&gt;
 1+(2*3)&lt;br /&gt;
und die Werte von [[#Enum|Enum]]s. &lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; aus dem folgenden Codestück definiert jedoch keine Konstante in diesem Sinne&lt;br /&gt;
 const double Pi = 3.14159256;&lt;br /&gt;
denn in einem anderen Quellmodul könnte durch die Deklaration&lt;br /&gt;
 extern const double Pi;&lt;br /&gt;
das Symbol &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; bekannt sein, ohne daß sein Wert bekannt ist!&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Adresse&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Adresse ist ein Ausdruck, der einen Speicherort (physikalisch oder virtuell) halten kann. Adressen erhält man dadurch, daß man einem Bezeichner den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt;voranstellt, Adressen durch Arithmetik berechnet oder Zahlen zu Adressen castet. Folgende Ausdrücke sind Adressen (eine sinnvolle Deklaration der auftretenden Variablen vorausgesetzt)&lt;br /&gt;
 &amp;amp; eine_zahl&lt;br /&gt;
 &amp;amp; ein_array[10]&lt;br /&gt;
 &amp;amp; ein_struct&lt;br /&gt;
 &amp;amp; ein_struct.komponente&lt;br /&gt;
 (int *) 0x1234&lt;br /&gt;
 (int *) eine_zahl&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Deklaration&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Anweisungen sind gewissermassen die Atome (oder Moleküle?), aus denen ein C-Programm besteht. Jedes C-Programm ist eine Abfolge von Deklarationen und Anweisungen. Einfache Anweisungen erhält man, in dem man einen Ausdruck nimmt und einen Strichpunkt dahinter schreibt:&lt;br /&gt;
 {{Ausdruck|}};&lt;br /&gt;
wie in&lt;br /&gt;
 x = x+1;&lt;br /&gt;
&lt;br /&gt;
Andere Anweisungen sind die unten aufgeführten Schleifen und die if- sowie die switch-Anweisung.&lt;br /&gt;
&lt;br /&gt;
Mehrere Deklarationen und Anweisungen können zu einem Block zusammengefasst werden. Dieser Block stellt dann wieder eine einzelne Anweisung dar und kann genau so gehandhabt werden!&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
In diesem Sinne ist auch z.B. die Syntax der if-Anweisung zu verstehen&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
besagt, daß der abhängig ausgeführte Code eine einzelne Anweisung sein darf oder eben ein kompletter Block oder die Verschachtelung mehrerer Blöcke etc.&lt;br /&gt;
&lt;br /&gt;
Eine Anweisung kann auch &amp;quot;leer&amp;quot; sein, also nichts tun. Diese Anweisungen sind der leere Block&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
und der Strichpunkt&lt;br /&gt;
 ;&lt;br /&gt;
die man gelegentlich in Schleifen findet:&lt;br /&gt;
 while (!timeout())&lt;br /&gt;
    {}&lt;br /&gt;
oder hinter Sprungmarken, die sonst direkt vor einer schliessenden Blockklammer stünden:&lt;br /&gt;
 {&lt;br /&gt;
    ...&lt;br /&gt;
    goto ein_label;&lt;br /&gt;
    ...&lt;br /&gt;
    {{Label|ein_label}}:;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Nicht jede Anweisung ist an jeder Stelle eines C-Programms erlaubt, so darf ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; nut innerhalb einer Schleife stehen. Gleiches gilt für &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;, das aber auch innerhalb eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; vorkommen darf.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Dies steht für einen Datentyp. Es kann ein elementarer Typ sein wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;, ein Zeiger darauf wie &amp;lt;tt&amp;gt;char*&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;void*&amp;lt;/tt&amp;gt;, und auch Qualifier enthalten wie das &amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt; im Typ &amp;lt;tt&amp;gt;unsigned long long&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Zu den Typen gehören auch zusammengesetzte Datentypen wie Strukturen und Unions, mit &amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt; selbst definierte Typen und natürlich Zeiger darauf, wie aus dem Abschnitt [[#Datentypen|Datentypen]]:&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person *&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;data32_t&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;&lt;br /&gt;
und Zeiger auf Funktionen.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Parameterliste&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
Die Parameterliste bei einer Funktionsdefinition gibt an, wieviel Übergabeparameter sie bekommt, wie diese heissen und welchen Typs diese sind. Der prinzipielle Aufbau ist&lt;br /&gt;
 {{Type}} {{Bezeichner}}, {{Type}} {{Bezeichner}}, ...&lt;br /&gt;
Falls die Funktion keine Parameter hat, dann ist die Parameterliste leer.&lt;br /&gt;
&lt;br /&gt;
Hier als Beispiel die zweiparametrige Funktion &amp;lt;tt&amp;gt;produkt&amp;lt;/tt&amp;gt;. Der erste Parameter heisst&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und ist ein &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;. Der zweite namens&amp;amp;nbsp;&amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; ist vom Typ &amp;quot;Zeiger auf double&amp;quot;, der Inhalt &amp;lt;tt&amp;gt;*b&amp;lt;/tt&amp;gt; ist also auch ein double.&lt;br /&gt;
&lt;br /&gt;
'''Definition der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b)&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
In älteren C-Quellen findet man noch eine andere Syntax für die Deklaration der Parameter, die aber heute praktisch nicht mehr verwendet wird:&lt;br /&gt;
'''alte Definition der Funktion:'''&lt;br /&gt;
 double produkt (a, b)&lt;br /&gt;
 double a, *b;&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Um die Funktion bekannt zu machen, werdendet man eine Deklaration bzw. den Prototypen, der dem Compiler nur mitteilt, welche Parameter die Funktion bekommt und was sie zurückliefert. Für den Aufruf der Funktion muss der Compiler nur diesen Prototyp kennen, ''was'' die Funktion im Endeffekt macht und wie sie implementiert wurde ist egal, sie wird als BlackBox angesehen.&lt;br /&gt;
&lt;br /&gt;
'''Prototyp der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b);&lt;br /&gt;
Hier dürfen die Bezeichner auch fehlen:&lt;br /&gt;
 double produkt (double, double*);&lt;br /&gt;
&lt;br /&gt;
==if==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==if-else==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==for==&lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Eine for-Schleife entspricht folgendem Konstrukt. Dabei sind die drei Ausdrücke optional. Fehlt die Bedingung, dann wird diese als &amp;quot;wahr&amp;quot; angenommen. Die beiden anderen Ausdrücke wird man als Ausdrücke mit Nebeneffekt wählen wie z.B. &amp;lt;tt&amp;gt;x=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;x=x-2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
 {&lt;br /&gt;
    {{Ausdruck|1}};&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_loop}}:&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
    else&lt;br /&gt;
       goto _break;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_continue}}:&lt;br /&gt;
    {{Ausdruck|2}};&lt;br /&gt;
    goto _loop;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_break}}:;&lt;br /&gt;
 }&lt;br /&gt;
Die Labels &amp;lt;tt&amp;gt;_break&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_continue&amp;lt;/tt&amp;gt; entsprechen den Sprungzielen einer &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Anweisung innerhalb von &amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==do-while==&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while  ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
==while==&lt;br /&gt;
 while  ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==switch==&lt;br /&gt;
 switch  ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    ...&lt;br /&gt;
  &lt;br /&gt;
    default:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#break-Anweisung|&amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Konstanten|&amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#continue-Anweisung|&amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#do-while-Schleife|&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Enum|&amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#for-Schleife|&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#goto-Anweisung|&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#return-Anweisung|&amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Liste der Operatoren|sizeof]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Strukturen|&amp;lt;tt&amp;gt;struct&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Eigene Datentypen|&amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Unions|&amp;lt;tt&amp;gt;union&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#while-Schleife|&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund2}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Arithmetische Operatoren&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Dies sind die &amp;quot;normalen&amp;quot; arithmetischen Operationen, wie man sie aus der Schule kennt. Man kann damit und allen anderen Operatoren auch komplexere Ausdrücke aufbauen. Die Prioritäten sind so, wie man sie kennt, also &amp;quot;Punktrechnung vor Strichrechnung&amp;quot;. Will man dies ändern, dann mit den runden Klammern:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;1+2*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 7&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(1+2)*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 9&amp;lt;br/&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}}&amp;amp;nbsp;+&amp;amp;nbsp;{{Ausdruck|}}&amp;lt;/tt&amp;gt; || Addition&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} - {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Subtraktion&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} * {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Multiplikation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} / {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Division&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} % {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Rest der Division (modulo)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;- {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Vorzeichenumkehr, Zweier-Komplement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Logische Operatoren und Vergleiche&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die logischen und die vergleichenden Operatoren liefern als Ergebnis den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (wahr) oder einen Wert ungleich&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (falsch, um genau zu sein den Wert &amp;lt;tt&amp;gt;!0&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Man kann das Ergebnis zwar einer Variablen zuweisen, in aller Regel wird man solche Ausdrücke jedoch in Bedingungen zu &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder in Abbruch-Bedingungen von Schleifen finden.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;&amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches AND: beides wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124;&amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches OR: mind. eines ist wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;! {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches NOT (0 &amp;amp;harr; ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} == {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} != {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist nicht gleich&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bitweise Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~ {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise NOT (Einser-Komplement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise AND&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise ODER&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} ^ {{Ausdruck|}}&amp;lt;/tt&amp;gt; ||bitweise XOR&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Shift-Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;lt;&amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Bits nach links schieben&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;gt;&amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Schieben nach rechts schieben&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Typen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Ein Cast in C kann dazu verwendet werden, den Typ eines Ausdruckes zu ändern oder den Ausdruck mit einer bestimmten Genauigkeit zu berechnen. Wird z.B. eine Berechnung standardmässig in 16 Bit ausgeführt, dann kann man mit einem Cast &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(long) &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
ausdrücken, daß die Berechnung in 32 Bit erfolgen soll. Des weiteren kann man Zeiger und ganze Zahlen und Gleitkommazahlen ineinander umwandeln.&lt;br /&gt;
&lt;br /&gt;
Casts können ''nicht'' dazu verwendet werden, um z.B. eine Zahl in einen String zu konvertieren, der diese Zahl darstellt! Dafür gibt es spezielle Funktionen wie &amp;lt;tt&amp;gt;itoa&amp;lt;/tt&amp;gt;!&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Type}}) {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Cast, Typwandlung&lt;br /&gt;
|-&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;| &amp;lt;tt&amp;gt;sizeof ({{Type}})&amp;lt;/tt&amp;gt; || Eine Konstante, deren Wert die Größe (in Bytes) des Typs ist. &amp;lt;tt&amp;gt;sizeof&amp;lt;/tt&amp;gt; ist auch auf Objekte anwendbar wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, Arrays bekannter Größe, Strukturen und Unions,  Array-, Struktur- und Union-Komponenten, Pointer, etc. Beispiel:&amp;lt;br/&amp;gt;&lt;br /&gt;
 int i, sum=0, array[] = { 1, -13, 4, 0, sizeof (int*) };&lt;br /&gt;
 &lt;br /&gt;
 for (i=0; i&amp;lt; sizeof (array) / sizeof (array[0]); i++)&lt;br /&gt;
    sum += array[i];&lt;br /&gt;
Alle Elemente des Arrays werden aufaddiert, ohne daß deren Anzahl explizit in der Schleife genannt ist.&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zeiger und Adressen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;* {{Adresse}}&amp;lt;/tt&amp;gt; || der Inhalt an Adresse&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp; {{Lvalue}}&amp;lt;/tt&amp;gt; || Adresse von&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Strukturen, Unions, Arrays&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Struct&amp;gt;}}.{{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Zeiger-auf-Struct&amp;gt;}} -&amp;gt; {{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union, deren Adresse man hat&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Adresse}}&amp;amp;#91;{{Ausdruck|}}&amp;amp;#93;&amp;lt;/tt&amp;gt; || Array-Element&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bedingte Auswertung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Bedingung}}) ? {{Ausdruck|}} : {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Auswahl des Wertes abhängig von der Bedingung&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zuweisung und Operatoren mit Nebeneffekt&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die Unterschiede der post- und pre-Varianten der Increment/Decrement kommen in Konstrukten wie &amp;lt;tt&amp;gt;x = *p++&amp;lt;/tt&amp;gt; zum tragen:&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *p++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; p = p+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *++p;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; p = p+1; x = *p;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = (*p)++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; *p = (*p)+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = ++(*p);&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; *p = (*p)+1; x = *p;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} = {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Zuweisung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++ {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-- {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Decrement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ++&amp;lt;/tt&amp;gt; || Post-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} --&amp;lt;/tt&amp;gt; || Post-Decrement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Kurzschreibweisen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Für ganz Faule gibt es anstatt&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a = a @ b&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
für viele Operatoren (hier dargestellt durch ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;@&amp;lt;/tt&amp;gt;) die abkürzende Schreibweise&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a @= b&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} += {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} -= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} *= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} /= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} %= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ^= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;lt;&amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;gt;&amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Autoren'''&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
* Kernighan und Ritchie - Buch&lt;br /&gt;
* Christian Wirth , C Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://wwwuser.gwdg.de/~kboehm/ebook/inhalt.html C-Programmieren unter Linux]&lt;br /&gt;
* [http://www.gdv.uni-hannover.de/documentation.php Skripte zum Selbststudium: C, C++, Java, etc]&lt;br /&gt;
* [http://info.baeumle.com/ansic.html Einführung in ANSI-C]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Quellcode C|!]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Inrfb2</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10397</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10397"/>
				<updated>2007-03-13T11:41:00Z</updated>
		
		<summary type="html">&lt;p&gt;Inrfb2: /* Aufruf */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Programmiersprache C wurde 1971 als Gundlage für das Betriebssystem UNIX in den USA entwickelt (UNIX ist zu über 90% in C geschrieben). 1978 wurde von Brian Kernighan und Dennis Ritchie eine eindeutige Sprachdefinition entwickelt. Mittlerweile ist C von ANSI und ISO standardisiert.&lt;br /&gt;
&lt;br /&gt;
Heute sind C und ihr Nachfolger C++ die dominierenden Programmiersprachen. Sehr viele Anwendungen sind in C geschrieben, was inzwischen auch auf eingebettete Systeme zutrifft, die lange in Assembler programmiert werden mussten, da keine ausreichend leistungsfähigen Compiler zur Verfügung standen. &lt;br /&gt;
&lt;br /&gt;
Leider ist C nicht einfach zu lernen &amp;amp;ndash; es wurde weder von noch für Hobby-Programmierer entwickelt &amp;amp;ndash; und eignet sich daher nur bedingt für den Einsteiger. Mit etwas Übung und einem optimierenden Compiler kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
Vom Design her ist C eine Hardware-unabhängig Sprache. Das bedeutet, daß C-Programme mit vertretbarem Aufwand auf ein anderes System portiert werden können. Dazu benötigt man lediglich einen anderen Compiler, und Inline-Assembler-Anweisungen (Assembleranweisungen innerhalb eines C-Programmes) müssen der neuen Hardware (Prozessor) angepasst werden. &lt;br /&gt;
&lt;br /&gt;
==Geschichte==&lt;br /&gt;
;1971: C wird entwickelt&lt;br /&gt;
;1978: Kernighan und Ritchie definieren die Sprache.&lt;br /&gt;
;1983: ANSI und ISO standardisieren C.&lt;br /&gt;
;1992: Bjarne Stroustrup enwickelt die Nachfolgesprache C++.&lt;br /&gt;
&lt;br /&gt;
=Aufbau eines C-Programmes=&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
   C-Programme haben keinen fixen Aufbau wie z.B. Pascal. Es gibt zwar gewisse Regeln, aber sonst sind dem Programmierer alle Freiheiten überlassen. Der folgende &amp;quot;Beispiel-Aufbau&amp;quot; ist daher nicht zwingend und kann durchaus verändert werden.&lt;br /&gt;
&lt;br /&gt;
   Natürlich haben C-Programme einen fixen Aufbau! Ebenso wie Pascal-Programme auch unterliegen sie einer strikten Grammatik! &lt;br /&gt;
Auskommentiert --[[Benutzer:SprinterSB|SprinterSB]] 10:23, 17. Feb 2006 (CET)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Ein einfaches C-Programm könnte folgendermassen aussehen. Das Programm tut eigentlich nichts, aber das Beispiel zeigt den prinzipiellen Aufbau. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 int Zahl1;&lt;br /&gt;
 char Zeichen1;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int zahl2;&lt;br /&gt;
 &lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Beschreibung:'''&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndash; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
 {{comment|void-Definition von main ist nur beim Controller ueblich}}&lt;br /&gt;
 {{comment|spezielle Compilereinstellungen sind noetig, damit bei dieser Definition von main}}&lt;br /&gt;
 {{comment|kein Fehler/Warnung erzeugt wird.}}&lt;br /&gt;
 void main ()&lt;br /&gt;
 {&lt;br /&gt;
     ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
 int main (void)&lt;br /&gt;
 {  {{comment|der Block &amp;quot;main&amp;quot; beginnt}}&lt;br /&gt;
    int zahl;&lt;br /&gt;
    &lt;br /&gt;
    {   {{comment|ein Block beginnt}}&lt;br /&gt;
        {{comment|hier koennen Deklarationen und Anweisungen stehen}}&lt;br /&gt;
    }   {{comment|der Block endet}}&lt;br /&gt;
   &lt;br /&gt;
    return 0;&lt;br /&gt;
 }  {{comment|&amp;quot;main&amp;quot; endet}}&lt;br /&gt;
&lt;br /&gt;
=Datentypen=&lt;br /&gt;
==Elementare Datentypen==&lt;br /&gt;
Der Datentyp einer Variable gibt an, welche Werte eine Variable enthalten kann, welcher Art diese Daten sind und wie sie verarbeitet werden, etwa in arithmetischen Operationen wie einer Addition. So ist es zum Beispiel möglich, in eine Variable vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ganze Zahlen zwischen ca. -32000 und +32000 einzutragen. In einer char-Variable können ASCII-Zeichen gespeichert werden (alles, was Sie mit der Tastatur erzeugen können) oder ganze Zahlen von -128 bis 127.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da C plattformabhängig ist, hängt die Größe eines Datentypes zum Teil von der genutzten Hardware (z.B. 8, 16 oder 32 Bit-Controller) und dem Compiler und dessen Einstellungen ab!&lt;br /&gt;
&lt;br /&gt;
===int, char, short, long (ganze Zahlen)===&lt;br /&gt;
In Variable dieser Typen können Sie ganze Zahlen abspeichern, also z.B. 1, &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;2, 100, 12345. Jeden dieser Typen gibt es in zwei Ausprägungen: als &amp;quot;&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;quot;, also als vorzeichenbehafteten Typ, und als &amp;quot;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&amp;quot;, also ohne Vorzeichen, d.h. das Vorzeichen wird als 0 oder +1 genommen. &lt;br /&gt;
&lt;br /&gt;
Vorzeichenbehaftete Ganzzahl-Typen werden intern im &amp;lt;tt&amp;gt;n-1&amp;lt;/tt&amp;gt;-Komplement dargestellt, das Vorzeichen selbst findet sich also im höchstwertigen Bit. Werden zur Speicherung ''b'' Bits verwendet, dann reicht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;z.B. *zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==Enum==&lt;br /&gt;
&lt;br /&gt;
Über &amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt; können Aufzählungen definiert werden. Die Werte sind &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Werte und beginnen mit&amp;amp;nbsp;0. Der folgende enum hat einen um&amp;amp;nbsp;1 grösseren Wert. Mit einer Zuweisung können auch andere Werte zugeordnet werden. Klarer wird's im Beispiel:&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 enum Farben&lt;br /&gt;
 {&lt;br /&gt;
    ROT,&lt;br /&gt;
    GRUEN,&lt;br /&gt;
    BLAU,&lt;br /&gt;
    BRAUN = 5,&lt;br /&gt;
    SCHWARZ&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
Dies definiert die Konstanten &amp;lt;tt&amp;gt;ROT=0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;GRUEN=1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BLAU=2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BRAUN=5&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;SCHWARZ=6&amp;lt;/tt&amp;gt; und den Typ &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void foo (enum Farben farbe)&lt;br /&gt;
{&lt;br /&gt;
   switch (farbe)&lt;br /&gt;
   {&lt;br /&gt;
      case ROT:&lt;br /&gt;
         ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit kann man anstatt &amp;quot;magischer&amp;quot; Zahlen sprechende Namen im Code verwenden, etwa in Berechnungen und Zuweisungen, Vergleichen oder als Konstante hinter einem &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zusammengesetzte Datentypen==&lt;br /&gt;
===Arrays===&lt;br /&gt;
Oft muß man sehr viele Werte gleichzeitig abspeichern und betrachten, die alle der selben Aufgabe dienen. Man schreibt z.B. ein Programm, das 10 Zahlen einlesen und anschließend wieder ausgeben soll. Man könnte das natürlich mit 10 einzelnen Variablen bewerkstelligen, aber es ist sinnvoller, dabei Arrays &amp;amp;ndash; teilweise auch als ''Felder'' bezeichnet &amp;amp;ndash; zu verwenden.&lt;br /&gt;
&lt;br /&gt;
In einem Array werden mehrere Variablen gleichen Typs zusammengefasst und hintereinander im Speicher abgelegt. So kann man viele tausend Variablen anlegen mit nur einer Zeile Code. Doch es gibt noch größere Vorteile: Sie können das Array mit einer Schleife ganz einfach nach Werten durchsuchen. Stellen Sie sich vor, Sie müssten mit 100 verschiedenen Variablen &amp;lt;tt&amp;gt;Zahl_00&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;Zahl_99&amp;lt;/tt&amp;gt; arbeiten!&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}}&amp;amp;#91;{{Konstante}}&amp;amp;#93;;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 unsigned int werte[100];&lt;br /&gt;
&lt;br /&gt;
Der Name muß natürlich ein gültiger Bezeichner sein, als Datentyp kann jeder Typ genommen werden &amp;amp;ndash; sowohl elementare Datentypen als auch Zeiger, Strukturen, Unions oder selbst definierte Datentypen. In der eckigen Klammer wird die Anzahl der Elemente bekanntgegeben. Ein mit [3] definiertes Array hat Platz für drei Variablen. Da der Index immer bei 0 beginnt, greift man also mit &amp;lt;tt&amp;gt;[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;[1]&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;[2]&amp;lt;/tt&amp;gt; auf den jeweilige Inhalt zu. Um auf eine der im Array enthaltenen Variablen zugreifen zu können, müssen Sie den Variablennamen und in eckigen Klammern den Index (die &amp;quot;Nummer&amp;quot;) der Variablen angeben. Diese Variable verhält sich dann wie eine ganz normale Variable des jeweiligen Datentypes. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #define NZAHLEN 10&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int i;&lt;br /&gt;
    int zahlen[NZAHLEN];  {{comment|zahlen[0] ... zahlen[9]}}&lt;br /&gt;
  &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++)&lt;br /&gt;
    {&lt;br /&gt;
       printf (&amp;quot;Bitte Zahl %d eingeben: &amp;quot;, i);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; zahlen[i]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++) &lt;br /&gt;
       printf (&amp;quot;Zahl %d ist: %d\n&amp;quot;, i, zahlen[i]);&lt;br /&gt;
      &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 10 int-Variablen großes Array angelegt. &lt;br /&gt;
In dieses wird nun der Reihe nach 10 Zahlen eingelesen. &lt;br /&gt;
Anschließend werden alle 10 Zahlen ausgegeben. &lt;br /&gt;
&lt;br /&gt;
Dabei wird die Größe der Arrays und das Schleifenende über das Define &amp;quot;&amp;lt;tt&amp;gt;NZAHLEN&amp;lt;/tt&amp;gt;&amp;quot; angegeben. Dadurch muss nur ''eine Stelle'' im Code geändert werden, wenn die Größe des Arrays einmal einen anderer Wert als 10 haben soll &amp;amp;ndash; dies vermeidet Fehler die dadurch entstehen, wenn man beim Anpassen der Array-Größe eine Codestelle vergisst, zudem wird der Code lesbarer als wenn irgendwo die Zahl &amp;quot;10&amp;quot; auftaucht.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
:Wird ein ungültiger Index angeben (einer, der in der Deklaration nicht enthalten ist) können  undefinierte Dinge passieren, wenn dadurch andere Variableninhalte oder Programmcode überschrieben wird, der hinter oder vor dem Array im Speicher liegt. Schlimmstenfalls kann sogar der Computer/Controller abstürzen. Also darauf achten, daß keine ungültigen Werte als Index auftreten!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Strings (Zeichenketten)===&lt;br /&gt;
Ein String ist nichts anderes als ein Array, das aus einzelnen Zeichen (&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;) gebildet wird. Die Ausgabe auf dem Bildschirm funktioniert am einfachsten mittels Strings.&lt;br /&gt;
&lt;br /&gt;
Die Definition eines Strings erfolgt also genauso wie bei Arrays:&lt;br /&gt;
 char string[21];&lt;br /&gt;
&lt;br /&gt;
Nun haben Sie eine String, in dem Sie 21 Zeichen speichern können. Ganz richtig ist das jedoch nicht. C arbeitet mit &amp;quot;null-terminierten Strings&amp;quot;. Das beudeutet, dass die Länge des Strings nicht abgespeichert wird, sondern das Zeichen mit dem ASCII-Wert 0 das Stringende kennzeichnet. Daher auch die Bezeichnung  &amp;quot;null terminiert&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Das letzte Zeichen eines Strings muß daher immer das ASCII-Zeichen Nr. 0 sein. Ist es das nicht, hat der String kein definiertes Ende, und wenn Sie versuchen, ihn durch eine Standard-Funktion auszugeben zu lassen, könnte es eine Weile dauern, bis sich im Speicher zufällig irgendwo eine 0 befindet. Es stehen ihnen daher bei dem Beispiel nur 20 Zeichen zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
===Mehrdimensionale Arrays===&lt;br /&gt;
Manchmal benötigt man mehr als nur ein eindimensionales Array, wie Sie es bisher kennengelernt haben. Auch dies ist kein Problem. In der Deklaration geben Sie einfach mehrere eckige Klammern hintereinander an. Aber Vorsicht: der Speicherplatz ist begrenzt, ein &amp;quot;&amp;lt;tt&amp;gt;char feld[1024][1024]&amp;lt;/tt&amp;gt;&amp;quot; hat die Speicherplatzgrenzen vermutlich bereits weit überschritten, und der Compiler wird einen (bei gewissen Einstellung auch keinen) Fehler liefern.&lt;br /&gt;
Beim Zugriff auf mehrdimensionale Felder müssen auch mehrere Indizes angeben werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  int x,y;&lt;br /&gt;
  int feld[3][5];&lt;br /&gt;
 &lt;br /&gt;
  for (x=0; x&amp;lt;3; x++) &lt;br /&gt;
  {&lt;br /&gt;
     for (y=0; y&amp;lt;5; y++)&lt;br /&gt;
     {&lt;br /&gt;
       printf (&amp;quot;Feldwert x: %d,  y: %d &amp;quot;, x, y);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; feld[x][y]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  for(x=0; x&amp;lt;3; x++) &lt;br /&gt;
     for (y=0; y&amp;lt;5; y++) &lt;br /&gt;
        printf (&amp;quot;Wert: feld[%d][%d] = %d\n&amp;quot;, x, y, feld[x][y]);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 3 mal 5 &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array angelegt. &lt;br /&gt;
Dann werden die Werte eingegeben: zuerst &amp;lt;tt&amp;gt;feld[0][0]&amp;lt;/tt&amp;gt;, dann &amp;lt;tt&amp;gt;feld[0][1]&amp;lt;/tt&amp;gt;, usw. bis &amp;lt;tt&amp;gt;feld[2][4]&amp;lt;/tt&amp;gt;. &lt;br /&gt;
Zum Schluß werden alle Werte noch einmal ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===Strukturen===&lt;br /&gt;
In C können Sie sogenannte &amp;quot;Strukturen&amp;quot; definieren. Dabei handelt es sich um eine Zusammenfassung mehrerer Datentypen zu einem größeren. Im Unterschied zu Feldern können in Strukturen unterschiedliche Datentypen zusammengestellt und gespeichert werden: &lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 struct {{Bezeichner}}&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur 'Person'}}&lt;br /&gt;
 struct Person &lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;lt;tt&amp;gt;struct Person {&amp;lt;/tt&amp;gt;&amp;quot; leitet die Definition der Struktur mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;Person&amp;lt;/tt&amp;gt;&amp;quot; ein. &lt;br /&gt;
Dann werden in dieser Struktur fünf Komponenten definiert: drei Strings und zwei &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. &lt;br /&gt;
mit &amp;lt;tt&amp;gt;}&amp;lt;/tt&amp;gt; wird die Definition abgeschlossen. Sie haben damit einen Datentyp erstellt. Um eine Variable des Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach an&lt;br /&gt;
 struct Person {{Bezeichner}};&lt;br /&gt;
&lt;br /&gt;
Zum Zugriff auf eine Komponente der Struktur gibt man den Namen der Struktur-Variablen an (im folgenden Beispiel also &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;klaus&amp;lt;/tt&amp;gt;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
 {{comment|Definition zweier Struktur-Variablen}}&lt;br /&gt;
 struct Person hubert, klaus;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Zugriff auf Struktur-Komponenten}}&lt;br /&gt;
 hubert.alter = 32;&lt;br /&gt;
 klaus.alter = hubert.alter + 1;&lt;br /&gt;
&lt;br /&gt;
===Unions===&lt;br /&gt;
Eine Union wird ganz analog zu einer Struktur deklariert und verwendet. Sie unterscheidet sich von einer Struktur jedoch dadurch, daß ihre Elemente nicht nacheinander im Speicher abgelegt werden, sondern sich überlagern. Auf die in einer Union enthaltenen Daten gibt es also verschiedene Sichten: je nachdem, welche Sicht bzw. Interpretation der Daten man gerne hätte, wählt man den gewünschten Zugriff.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
union Daten &lt;br /&gt;
{&lt;br /&gt;
   int id;&lt;br /&gt;
&lt;br /&gt;
   struct Person u_person;&lt;br /&gt;
&lt;br /&gt;
   struct u_double&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      double wert;&lt;br /&gt;
   };&lt;br /&gt;
&lt;br /&gt;
   struct u_pointer&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      union Daten * p1;&lt;br /&gt;
      union Daten * p2;&lt;br /&gt;
   };&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
union Daten data;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies definiert eine Union mit den vier Zugriffsmöglichkeiten &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_double&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Größe der Union richtet sich dabei nach der grössten Komponente. In diesem Beispiel sind alle Komponenten so angelegt worden, daß sie an erster Stelle ein &amp;lt;tt&amp;gt;int id&amp;lt;/tt&amp;gt; enthalten. In &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; könnte man sich also merken, wie die Daten in der Union zu interpretieren sind. Würde &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; nicht dieses &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; enthalten, so würde sich &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; mit &amp;lt;tt&amp;gt;data.u_person.vname&amp;lt;/tt&amp;gt; überlagern. Ein Ändern der ersten Buchstaben von &amp;lt;tt&amp;gt;vname&amp;lt;/tt&amp;gt; hätte also ein Ändern von &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; zur Folge, und man könnte es nicht mehr als Merker verwenden. Mit diesem Feld überlagert das &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; die &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;-Felder der anderen Sichten, z.B. ist &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; der selbe Zugriff wie auf &amp;lt;tt&amp;gt;data.u_person.id&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein anderes Beispiel ist eine Union, die es ermöglicht, auf die einzelnen Bytes eines &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; zuzugreifen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef union&lt;br /&gt;
{&lt;br /&gt;
   unsigned long  as_long;&lt;br /&gt;
   unsignen short as_short[2];&lt;br /&gt;
   unsignen char  as_byte[4];&lt;br /&gt;
} data32_t;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies überlagert einen &amp;lt;tt&amp;gt;unsigned long&amp;lt;/tt&amp;gt; &amp;amp;ndash; also eine 32-Bit-Zahl &amp;amp;ndash; mit vier Bytes bzw. zwei Shorts.&lt;br /&gt;
 data32_t wert;&lt;br /&gt;
 &lt;br /&gt;
 wert.as_long = 0x12345678;&lt;br /&gt;
 wert.as_byte[0] = 0xab;&lt;br /&gt;
 {{comment|nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform)}}&lt;br /&gt;
&lt;br /&gt;
==Eigene Datentypen==&lt;br /&gt;
&lt;br /&gt;
=Variablen=&lt;br /&gt;
Eine Variable ist ein Synonym (=anderer Name) für eine Speicherstelle in einem Computer. Einfacher gesagt, eine Variable bietet Raum, um Daten wie Zahlen oder Zeichen zu speichern und wieder zu lesen.&lt;br /&gt;
&lt;br /&gt;
==Variablennamen==&lt;br /&gt;
Ein Variablenname kann zusammengesetzt werden aus den Buchstaben &amp;lt;tt&amp;gt;'''A'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''Z'''&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;'''a'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''z'''&amp;lt;/tt&amp;gt;, den Ziffern &amp;lt;tt&amp;gt;'''0'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''9'''&amp;lt;/tt&amp;gt;, sowie dem Sonderzeichen &amp;quot;Unterstrich&amp;quot; (underscore) &amp;lt;tt&amp;gt;'''_'''&amp;lt;/tt&amp;gt;. Dabei darf an erster Stelle keine Ziffer stehen. Die Bezeichner &amp;lt;tt&amp;gt;hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALLO&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALL0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;_123&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_HALLO&amp;lt;/tt&amp;gt; sind also alle gültige und unterschiedliche Variablennamen.&lt;br /&gt;
&lt;br /&gt;
==Anlegen von Variablen==&lt;br /&gt;
Um eine Variable verwenden zu können, muss sie zuerst vereinbart (&amp;quot;erzeugt&amp;quot;) werden. Dies wird auch als &amp;quot;''Definition der Variablen''&amp;quot; bezeichnet und geht so: Schreiben Sie zuerst den Datentyp, dann den Namen der Variablen. Zum Schluß kommt noch der Strichpunkt, wie nach jeder C-Anweisung oder Deklaration. Und nicht vergessen: C unterscheidet zwischen  Groß- und Kleinschreibung! &lt;br /&gt;
 int Zahl1, Zahl2;&lt;br /&gt;
 char Zeichen;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    float gleitZahl;&lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:'''&lt;br /&gt;
In einer Zeile können auch mehrere Variablen gleichen Types vereinbart werden, wenn man ein Komma dazwischen setzt. Variablen können in jedem Block vereinbart werden. Siehe [[#Gültigkeitsbereich|Gültigkeitsbereich]].&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen==&lt;br /&gt;
Man kann einer vereinbarten Variable Werte [[#Zuweisungen|zuweisen]]. Dazu schreibt man zuerst den Variablennamen, ein Gleichheitszeichen &amp;quot;&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;&amp;quot; und anschliessend den zuzuweisenden [[#Ausdrücke|Ausdruck]]. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, zahl2 = 12;&lt;br /&gt;
  char zeichen1 = 'A';&lt;br /&gt;
&lt;br /&gt;
  zahl1 = 52;&lt;br /&gt;
  zeichen1 = zeichen1 + 1; &lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Zuerst werden drei Variablen angelegt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;: wird gleich bei der Vereinbarung der Wert 12 zugewiesen. &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl1 = 52&amp;lt;/tt&amp;gt;: Hier wird der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; der Wert 52 zugewiesen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;: wird um 1 erhöht. Da in der Variablen &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; gespeichert ist, gibt sich ihr neuer Wert aus &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt;. Weil &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; dem Wert 65 entspricht, ist &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt; gleich 66, was dem Wert für &amp;lt;tt&amp;gt;'B'&amp;lt;/tt&amp;gt; entspricht.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei float==&lt;br /&gt;
Das funktioniert genau wie bei normale Zuweisungen. Nachkommastellen werden durch einen Punkt abgegrenzt: &lt;br /&gt;
 floatVariable = 3.14;&lt;br /&gt;
Zusätzlich kann eine Zehnerpotenz angegeben werden:&lt;br /&gt;
 floatVariable2 = -1.234E-6;&lt;br /&gt;
Dadurch wird der erst Wert mit 10&amp;lt;sup&amp;gt;&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;6&amp;lt;/sup&amp;gt; multipliziert, der Wert der Variablen ist also &lt;br /&gt;
:&amp;lt;math&amp;gt;-1{,}234\cdot10^{-6} = -0.000001234&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei logischen Variablen==&lt;br /&gt;
Wie bereits erwähnt, besitzt C keinen logischen Datentyp. Es müssen also &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; dafür genutzt werden. Die Zuweisung entpricht der Standard-Zuweisung. Wird der Wert 0 zugewiesen, dann ist die Variable &amp;quot;unwahr&amp;quot;, ansonsten ist sie &amp;quot;wahr&amp;quot;. &lt;br /&gt;
 intVariable = !0;   /* entspricht &amp;quot;wahr&amp;quot;   */&lt;br /&gt;
 intVariable = 0;    /* entspricht &amp;quot;unwahr&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
==Konstanten==&lt;br /&gt;
Konstanten können als Variable angesehen werden, die nicht beschrieben, sondern nur gelesen werden können. Ein typisches Beispiel dafür ist die Zahl &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; (rund 3,141592654). Niemand würde in der realen Welt versuchen, ihr einen anderen Wert zuzuweisen. Würde man &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; jedoch wie eine normale Variable anlegen, wäre dies ohne weiteres möglich. Um dies zu verhindern, gibt es das Schlüsselwort &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in C:&lt;br /&gt;
 const {{Type}} {{Bezeichner}} = {{Konstante}};  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Wichtig dabei ist, dass man Konstanten nur bei der Vereinbarung einen Wert zuweisen kann. &lt;br /&gt;
Da Konstanten gewöhnlich im gesamten Programm, zumindest einer Quelldatei genutzt werden, definiert man diese allerdings gewöhnlich außerhalb des main-Blockes entweder am Anfang eines Programmes, oder in einer sogenannten Header-Datei, die per &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; eingebunden wird.&lt;br /&gt;
 const float PI = 3.141592;  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Es sei jedoch erwähnt, daß auch einer Konstanten nachträglich ein anderer Wert zugewieden werden kann. Im obigen Beispiel könnte mit&lt;br /&gt;
 * ((float*) &amp;amp;PI) = 2;&lt;br /&gt;
der Wert von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; im Nachhinein verändert werden. Es wird die Adresse von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; genommen und diese Adresse durch den Cast in eine ganz normale &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;-Adresse umgewandelt, über welche der Wert geändert wird. Die sei der Vollständigkeit halber erwähnt.&lt;br /&gt;
&lt;br /&gt;
Je nachdem, an welcher Stelle sich das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; bei einer Pointer-Deklaration befindet, markiert es den Pointer als konstant oder das Objekt, auf das dieser Pointer zeigt. Eine häufige Parameterdeklaration in Ausgabe-Funktionen, die einen String erhalten, ist&lt;br /&gt;
 void foo (const char * str, ...);&lt;br /&gt;
Dadurch ist &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; der Zeiger auf eine Zeichenkette, die innerhalt der Funktion nicht verändert wird bzw. verändert werden darf. Eine Zuweisung wie &amp;lt;tt&amp;gt;*str = 'a'&amp;lt;/tt&amp;gt; ergibt also einen Fehler. &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; selbst kann aber sehr wohl verändert werden, etwa mit &amp;lt;tt&amp;gt;str++&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Soll ausgedrückt werden, daß &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; unveränderlich ist, dann so:&lt;br /&gt;
 void foo (char * const str, ...);&lt;br /&gt;
Jetzt wäre eine Änderung des Strings in Ordnung, etwa durch &amp;lt;tt&amp;gt;str[10] = 'a'&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Um sich zu merken, worauf das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; wirkt, trennt man die Deklaration in Gedanken beim&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf: Steht das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; links vom&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, dann gehört es zum &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, steht es rechts davon, dann gehört es zum Pointer. Natürlich ist es auch denkbar, beides &amp;amp;ndash; also den Zeiger und sein Ziel &amp;amp;ndash; als konstant zu markieren.&lt;br /&gt;
&lt;br /&gt;
==Gültigkeitsbereich==&lt;br /&gt;
In C können mehrere Variablen den gleichen Namen haben, solange eindeutig ist, welche in welchen Block gültig ist. Dabei gelten folgende Regeln: &lt;br /&gt;
&lt;br /&gt;
;Lokale Variablen: sind Variablen, die innerhalb eines Blockes definiert werden. Jede Variable ist nur in dem Block gültig, in dem sie vereinbart wurde, sowie in allen darin enthaltenen Blöcken; es sei denn, in einem Unter-Block wird eine Variable gleichen Namens definiert. Dann bezieht sich in diesem Unter-Block der Bezeichner auf die im Unter-Block angelegte Variable.&lt;br /&gt;
;Globale Variablen: werden ausserhalb jedes Blockes definiert und gelten ab der Stelle, an der sie deklariert werden, siehe auch [[#Deklaration und Definition|Deklaration und Definition]]. Wird jedoch in einem Block eine Variable gleichen Namens angelegt, gilt ab hier bis zum Ende des Blocks nicht mehr die globale Variable, sondern die im Block deklarierte. Das Spiel kann man weiterspielen: wird in einem Unter-Block wieder eine namensgleiche Variable angelegt, gilt diese in dem Unterblock.&lt;br /&gt;
&lt;br /&gt;
==Speicherklassen==&lt;br /&gt;
Jede Variable in C gehört zu einer bestimmten Speicherklasse&lt;br /&gt;
;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;: Lokale Variablen sind in aller Regal sogenannte ''automatische Variablen''. Das bedeutet, sie werden automatisch angelegt, wenn ein Block bzw. eine Funktion betreten wird und danach wieder entfernt. Das Schlüsselwort &amp;quot;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;&amp;quot; wird praktisch nie hingeschrieben, denn lokale Variablen ohne die ausdrückliche Angabe einer Speicherklasse, sind automatisch automatische Variablen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;: Eine externes Symbol ist im ganzen Programm bekannt bzw. in dem Block, in der die Deklaration steht. In unterschiedlichen Blöcken stehende Deklarationen beziehen sich auf das gleiche Symbol! Obgleich das Datum global zugreifbar ist, ist der Gültigkeitsbereich auf den deklarierenden Block begrenzt bzw. auf das deklarierende Quell-Modul, sofern das Symbol ausserhalb jedes Blocks des Moduls deklariert wird. Siehe auch [[#Deklaration und Definition|Deklaration und Definition]].&lt;br /&gt;
;&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;: Die Variable ist im Block gültig bzw. im Quell-Modul (also in der C-Datei, in der die angelegt wurde), wenn sie nicht innerhalb eines Blockes angelegt wurde. Statische Variablen werden nicht in Registern oder im Frame der Funktion angelegt, sondern im selben Speicherbereich, in dem auch die globalen Variablen liegen; Konstanten evtl. auch im Flash. Eine lokale Variable, die als &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; angelegt wird, &amp;quot;überlebt&amp;quot; also das Verlassen des Blocks und hat beim neuerlichen Betreten des Blockes ihren bisherigen Wert. In unterschiedlichen Blöcken angelegte lokale statische Variablen beziehen sich auf unterschiedliche Speicherstellen, genau wie bei lokalen Variablen auch.&lt;br /&gt;
;&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;: Durch diese Speicherklasse wird eine Variable &amp;amp;ndash; falls möglich &amp;amp;ndash; als Registervariable angelegt, also in einem Maschinenregister des Computer/Controllers gehalten. Dadurch kann auf solche Variablen besonders schnell zugegriffen werden. Dieses Schlüsselwort ist bei modernen Compilern weitgehend überflüssig, da die entsprechenden Optimierungen selbständig vorgenommen werden, wenn ausreichend Register vorhanden sind. Auch globale Variablen können als Register angelegt werden, davon ist dem Anfänger aber dringend abzuraten, weil leicht schwerauffindbare Fehler und Abstürze auftreten, wenn man nicht genau weiss, welche Implikationen in einer solchen Definition stecken!&lt;br /&gt;
;&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;: (FIXME: volatile ist ein Qualifier und keine Speicherklasse) Dies ist das genaue Gegenteil von &amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt; und bewirkt, dass die Variable auf keinen Fall in einem Register zwischengespeichert werden darf, sondern immer aus dem RAM gelesen und ins RAM geschrieben werden soll. &amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt; müssen alle ''globalen'' Variablen markiert werden, die in [[ISR | Interrupt-Handlern]] verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Ausdrücke=&lt;br /&gt;
Eine Variable oder eine Konstante in C stellen einfache Ausdrücke dar.&lt;br /&gt;
Diese elementaren Ausdrücke können durch Operatoren miteinander verknüpft werden und so zu neuen, komplexeren Ausdrücken zusammen gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Einfache Beispiele für Ausdrücke sind also z.B.:&lt;br /&gt;
 1&lt;br /&gt;
 a&lt;br /&gt;
 'a'&lt;br /&gt;
 1 + a&lt;br /&gt;
 a == 1&lt;br /&gt;
&lt;br /&gt;
Auch Funktionen können einen Wert zurückliefern und in Ausdrücken weiter benutzt werden.&lt;br /&gt;
In den folgenden Abschnitten wird gezeigt, welche Operatoren in C vorhanden sind,&lt;br /&gt;
und wei man damit neue Ausdrücke aufbauen kann.&lt;br /&gt;
&lt;br /&gt;
==Lvalues==&lt;br /&gt;
&lt;br /&gt;
Ein Lvalue in C ist ein Ausdruck, dem ein anderer Ausdruck zugewiesen werden kann, dessen Wert also durch eine Zuweisung verändert werden kann.&lt;br /&gt;
das 'L' leitet sich ab von 'left' bwz. 'links' und das 'value' bedeutet Wert: Ein Lvalue ist ein Ausdruck, der auf der linken Seite einer Zuweisung stehen darf. Ein Lvalue ist also immer auch ein gültiger Ausdruck, aber die Umkehrung gilt in alles Regel nicht.&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für einen Lvalue ist eine &amp;quot;normale&amp;quot; Variable, die nicht mit &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; als Konstante markiert ist:&lt;br /&gt;
 a = 1;&lt;br /&gt;
Hingegen ist der Ausdruck &amp;lt;tt&amp;gt;a+1&amp;lt;/tt&amp;gt; kein Lvalue, denn eine Zuweisung wie&lt;br /&gt;
 a+1 = 2;&lt;br /&gt;
die mathematisch durchaus sinnvoll ist, erzeugt einen Compilerfehler, der etwa lauten könnte &amp;quot;illegal lvalue in assignment&amp;quot;:&lt;br /&gt;
&amp;quot;ungültiger Wert in Zuweisung&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Andere Beipiele für Lvalues sind die Komponenten von (nicht-konstanten) [[#Strukturen|Strukturen]] und [[#Unions|Unions]], [[#Arrays|Array]]-Elemente und die Dereferenzierungen von Pointern: Die Konstante&amp;amp;nbsp;4 wird durch den Cast in eine Adresse umgewandelt. Über die Dereferenzierung&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; wird an die Adresse&amp;amp;nbsp;4 im Speicher eine&amp;amp;nbsp;3 geschrieben. Ob das erlaubt bzw. sinnvoll ist, ist abhängig von der jeweiligen Architektur.&lt;br /&gt;
 * ((unsigned int *) 4) = 3;&lt;br /&gt;
Hier ist der gesamte &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;-Ausdruck ein Lvalue&lt;br /&gt;
&lt;br /&gt;
==Logische (boolsche) Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp;amp;&amp;amp;amp; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr oder &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; || gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; || ungleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;= b&amp;lt;/tt&amp;gt; || kleiner oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt; b&amp;lt;/tt&amp;gt; || kleiner als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt;= b&amp;lt;/tt&amp;gt; || glösser oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt; b&amp;lt;/tt&amp;gt; || grösser als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; nicht wahr und vice versa&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine interessante Eigenschaft der Operatoren &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;amp;amp;&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; ist, dass&lt;br /&gt;
sie die Auswertung abbrechen, sobald das Ergebnis feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet. Ein oft anzutreffendes Codestück sieht so aus, dabei sei &amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
  if (p &amp;amp;&amp;amp; *p == 5)&lt;br /&gt;
  {&lt;br /&gt;
     {{comment|mach was}}&lt;br /&gt;
  }&lt;br /&gt;
Zuerst wird in der Bedinung geprüft, ob Zeiger&amp;amp;nbsp;&amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; einen Wert ungleich Null hat, also ob er überhaupt einen gültigen Wert enthält. Es ist weit verbreitete Konvention in C, daß Zeiger, die keinen gültigen Wert haben, die Adresse&amp;amp;nbsp;0 enthalten. '''Nur dann, wenn ein Zeiger nicht ein Null-Pointer ist, darf überhaupt ein Zugriff über ihn erfolgen!'''&lt;br /&gt;
&lt;br /&gt;
==Vergleich von Variablen==&lt;br /&gt;
Skalare Variablen (also ganze Zahlen, Gleitkommazahlen, Zeiger) können miteinander verglichen werden. Dazu gibt es die folgenden Operatoren in C: &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; || ist nicht gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;=&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;=&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das Ergebnis der Auswertung ist eine ganze Zahl. Ist die Bedingung erfüllt, dann ist der Wert ungleich&amp;amp;nbsp;0. Ist die Bedingung nicht erfüllt, dann ist ihr Wert gleich&amp;amp;nbsp;0.&lt;br /&gt;
Meistens wird man diese Operatoren in &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Konstrukten finden wie zum Beispiel&lt;br /&gt;
 if (x &amp;gt;= 10)&lt;br /&gt;
    x = 10;&lt;br /&gt;
oder in Abbruchbedingungen von Schleifen, wie sie weiter unten erklärt werden.&lt;br /&gt;
&lt;br /&gt;
Es ist auch möglich, das Ergebnis der Auswertung in einer &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Variablen zu speichern:&lt;br /&gt;
 int i;&lt;br /&gt;
 int z1, z2;&lt;br /&gt;
 &lt;br /&gt;
 z1 = 5;&lt;br /&gt;
 z2 = 100;&lt;br /&gt;
 i = z1 &amp;lt;= z2;  {{comment|Ein Vergleich. i wird &amp;quot;wahr&amp;quot;, da z1 kleinergleich z2 ist}}&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich&amp;amp;nbsp;0 (&amp;quot;wahr&amp;quot;), wenn &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; kleiner oder gleich &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt; ist. Ist &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; jedoch größer als &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt;, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich&amp;amp;nbsp;0 (&amp;quot;unwahr&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
==Arithmetische Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a + b&amp;lt;/tt&amp;gt; || Summe (Addition)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a - b&amp;lt;/tt&amp;gt; || Differenz (Subtraktion)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a * b&amp;lt;/tt&amp;gt; || Produkt (Multiplikation)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a / b&amp;lt;/tt&amp;gt; || Quotient (Division, evtl. mit Rest)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a % b&amp;lt;/tt&amp;gt; || Rest bei Division (Modulo)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;-a&amp;lt;/tt&amp;gt; || Vorzeichenumkehr (Zweierkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Bit-Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp; b&amp;lt;/tt&amp;gt; || bitweise und (and)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || bitweise oder (or)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a ^ b&amp;lt;/tt&amp;gt; || bitweise exclusiv-oder (xor, exor)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;~a&amp;lt;/tt&amp;gt; || jedes Bit in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; invertieren (not, Einerkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Index-Operator bei Arrays==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a[b]&amp;lt;/tt&amp;gt; || das (b+1)ste Element des Feldes a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Folgendes gilt es bei der Verwendung des Indexoperators zu beachten:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; muss ein [[C-Tutorial#Felder | Feld]] oder [[C-Tutorial#Zeiger | Zeiger]] sein&lt;br /&gt;
# &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; muss ein Integer sein oder ein Datentyp, der sich in einen int umwandeln läßt (z.B. char)&lt;br /&gt;
# Es wird nicht geprüft, ob der Index &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; im Feld &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gültig ist!&lt;br /&gt;
# Der erste Index eines Feldes ist immer 0. Daher ''(b+1)stes Element'' in der Beschreibung&lt;br /&gt;
&lt;br /&gt;
==Komponenten-Auswahl bei Structs und Unions==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a.b&amp;lt;/tt&amp;gt; || Element b der [[C-Tutorial#Strukturen | Struktur]] oder des Unions a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adress-Operator und Dereferenzierung==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&amp;amp;amp;a&amp;lt;/tt&amp;gt; || Speicheradresse der Variablen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;*a&amp;lt;/tt&amp;gt; || Wert, der an der Adresse &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a-&amp;amp;gt;b&amp;lt;/tt&amp;gt; || Wert des Elements &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; der Struktur, deren Adresse in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Adressoperator &amp;amp; kann auf Variablen angewendet werden und&lt;br /&gt;
gibt die Startadresse der Variablen im Speicher zurück.&lt;br /&gt;
&lt;br /&gt;
Handelt es sich bei einer Variable um einen [[C-Tutorial#Zeiger | Zeiger]], so enthält&lt;br /&gt;
sie eine Speicheradresse. Um an den '''Wert''' zu gelangen, der&lt;br /&gt;
an dieser Adresse steht, wird der Operator * vorangestellt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
&lt;br /&gt;
 {{comment|x ist eine Integervariable und hat den Wert 5}}&lt;br /&gt;
 int x = 5;&lt;br /&gt;
     &lt;br /&gt;
 {{comment|z ist ein Zeiger auf eine Integer-Variable und enthaelt somit}}&lt;br /&gt;
 {{comment|die Speicheradresse einer Integer-Variablen}}&lt;br /&gt;
 int *z;       &lt;br /&gt;
  &lt;br /&gt;
 {{comment|Verwendung des Adress-Operators: weist an z die Adresse von x zu}}&lt;br /&gt;
 z = &amp;amp;x;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Verwendung der Dereferenzierung}}&lt;br /&gt;
 {{comment|erhoehe den Wert, der bei Adresse z steht, um eins}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|da z auf x zeigt, hat x jetzt den Wert 6}}&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff auf Struktir- und Union-Elemente eine abkürzende Schreibweise möglich:&lt;br /&gt;
&lt;br /&gt;
Statt &lt;br /&gt;
  (*strukturZeiger).element&lt;br /&gt;
kann geschrieben werden&lt;br /&gt;
  strukturZeiger-&amp;gt;element&lt;br /&gt;
Beide Schreibweisen sind absolut gleichbedeutend, die Klammern bei der ersteren sind notwendig.&lt;br /&gt;
&lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
:Bei der Dereferenzierung durch &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; findet keine Prüfung statt, ob der Zeiger auch auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu einer Änderung '''irgendeiner''' Speicherstelle!&lt;br /&gt;
&lt;br /&gt;
 int *z; {{comment|z ist ein Zeiger auf einen int}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.}}&lt;br /&gt;
 {{comment|z enthaelt irgendeine ungueltige Adresse!!}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|&amp;quot;Erhoehe einen Integer _irgendwo_ im Speicher um 1&amp;quot; -&amp;gt; CRASH !!!}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
&lt;br /&gt;
==Cast-Operator==&lt;br /&gt;
&lt;br /&gt;
Der Cast Operator dient dazu, den Datentyp eines Wertes zu ändern. Dafür wird einfach der neue Datentyp in Klammern vor den Wert geschrieben.&lt;br /&gt;
&lt;br /&gt;
Um zum Beispiel aus einem Float ein Integer zu machen:&lt;br /&gt;
 var  = (int) 5.60;&lt;br /&gt;
Dabei wird der Wert aber auch gerundet, und es findet somit ein Informationsverlust statt.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Umwandeln einer ganzen Zahl in eine Adresse:&lt;br /&gt;
 int * addr;&lt;br /&gt;
 addr = (int*) 0x1234;&lt;br /&gt;
Damit ist &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; an Adresse 0x1234.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
Der Cast-Operator selbst führt ''keine Konvertierung'' von Darstellungen durch, etwa die Umwandlung der ganzen Zahl 123 ein den String &amp;lt;tt&amp;gt;&amp;quot;123&amp;quot;&amp;lt;/tt&amp;gt;, der diese Zahl darstellt! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
  int main(int argc, char ** argv)&lt;br /&gt;
  {&lt;br /&gt;
        char text[] = &amp;quot;5.6&amp;quot;;&lt;br /&gt;
        int zahl = (int) text;&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, zahl);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Anfangsadresse des Strings &amp;lt;tt&amp;gt;&amp;quot;5.6&amp;quot;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Komma-Operator==&lt;br /&gt;
Mit einem &amp;lt;tt&amp;gt;,&amp;lt;/tt&amp;gt; können mehrere Ausdrücke nacheinander ausgewertet werden.&lt;br /&gt;
Die Auswertung erfolgt von links nach rechts.&lt;br /&gt;
&lt;br /&gt;
Solche Konstrukte sieht man manchmal in Abfragen wie&lt;br /&gt;
 FILE  *file;&lt;br /&gt;
 if (file = fopen (&amp;quot;foo.exe&amp;quot;, &amp;quot;r&amp;quot;), file != NULL)&lt;br /&gt;
was erst an &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; einen Wert zuweist und den &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Block nur betritt,&lt;br /&gt;
wenn &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; nicht der Nullpointer ist.&lt;br /&gt;
&lt;br /&gt;
Bequem kann das auch in einer [[#for-Schleife|for-Schleife]] sein, wenn man zwei (oder mehr) Laufvariablen hat oder so:&lt;br /&gt;
 for (i=0, j=0; i &amp;lt; 10; i++, j += 2)&lt;br /&gt;
    &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Zuweisung===&lt;br /&gt;
=== ++ und -- ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; stellen einfachere Schreibweisen dar zum Addieren bzw. Subtrahieren von&amp;amp;nbsp;1.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; (Inkrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo++; &lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo + 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; 3}}&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; (Dekrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo--;&lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo - 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; -1}}&lt;br /&gt;
&lt;br /&gt;
Die beiden Operatoren können sowohl in der Präfix-Schreibweise (vor der Variablen) als auch als Postfix-Schreibweise (hinter der Variablen) notiert werden. &lt;br /&gt;
Der Unterschied liegt darin, dass beim Präfix der Wert zuerst neu berechnet wird und die Variable dann verwendet wird. Beim Postfix wird die Variable zuerst verwendet und erst nach Auswertung des Ausdrucks, in dem sie enthalten ist, neu berechnet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 int ausgabe1, ausgabe2, var1 = 10, var2 = 10;&lt;br /&gt;
 ausgabe1 = 3 * ++var1; {{comment|ausgabe1 &amp;amp;#61; 33; var1 &amp;amp;#61; 11;}}&lt;br /&gt;
 ausgabe2 = 3 * var2++; {{comment|ausgabe2 &amp;amp;#61; 30; var2 &amp;amp;#61; 11;}}&lt;br /&gt;
&lt;br /&gt;
Für Zeiger arbeiten diese Operatoren etwas anders, siehe dazu [[#Zeiger-Arithmetik|Zeiger-Arithmetik]].&lt;br /&gt;
&lt;br /&gt;
===Bedingter Ausdruck===&lt;br /&gt;
 ({{Bedingung}}) ? {{Ausdruck|1}} : {{Ausdruck|2}}&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; erfüllt ist, dann wertet dieser Ausdruck aus zu &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt;. Ist er nicht erfüllt, dann wertet er aus zu &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 x = (x &amp;gt;= 3) ? 0 : x+1;&lt;br /&gt;
Startet man &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; mit dem Wert 0, dann nimmt es bei mehrfacher Anwendung dieser Zeile (z.B. in einer Schleife) nacheinander die folgende Werte an:&lt;br /&gt;
:&amp;lt;tt&amp;gt;1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, ...&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&lt;br /&gt;
Wie auch in der Mathematik gibt es auch in C genaue Regeln über die Abarbeitungsreihenfolge (precedence)&lt;br /&gt;
der Operatoren. Dass sich alle C-Compiler genau an diesen ANSI-Vorschlag halten, ist leider nicht sicher.&lt;br /&gt;
Neben hat auch nicht jeder Programmierer diese Regel jederzeit im Kopf. &lt;br /&gt;
Daher ist es sinnvoll, Ausdrücke durch runde Klammern eindeutig zu kennzeichnen. &lt;br /&gt;
Nebenbei stören sich Compiler nicht an überflüssigen Klammerpaaren.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Priorität ||Operator||Assoziativität&lt;br /&gt;
|-&lt;br /&gt;
  &lt;br /&gt;
|&amp;lt;tt&amp;gt;15&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ( ) [ ] -&amp;gt; . &amp;lt;/tt&amp;gt;                      ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;14&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;! ~ ++ -- + - (TYP) * &amp;amp; sizeof &amp;lt;/tt&amp;gt;    ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;13&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; * / % (Rechenoperationen) &amp;lt;/tt&amp;gt;         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;12&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; + - (binär) &amp;lt;/tt&amp;gt;                       ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;11&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;&amp;lt; &amp;gt;&amp;gt; &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;10&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt; &amp;lt;= &amp;gt; &amp;gt;= &amp;lt;/tt&amp;gt;                         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 9&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; == != &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 8&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp; (bit-AND-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 7&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ^ (bit-XOR-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 6&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; (bit-OR-Operator)&amp;lt;/tt&amp;gt;   ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 5&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp;&amp;amp; &amp;lt;/tt&amp;gt;                                ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 4&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; &amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 3&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;? : &amp;lt;/tt&amp;gt;                               ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 2&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; = += -= /= *= %= &amp;gt;&amp;gt;= &amp;lt;&amp;lt;= &amp;amp;= &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;= ^= &amp;lt;/tt&amp;gt; ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 1&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; , (Sequenz-Operator) &amp;lt;/tt&amp;gt;              ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
&lt;br /&gt;
Peter Baeumle-Courth, ANSI-C im Überblick &amp;lt;p&amp;gt;&lt;br /&gt;
W. Alex, Einführung in C/C++&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
Eine Kontrollanweisung ist eine Anweisung, die Einfluss auf den Programmfluss hat. Normalerweise werden Anweisungen so ausgeführt, wie sie in der Quelldatei stehen: Von links nach rechts (falls mehrere Anweisungen in einer Zeile stehen sollten, wovon i.A. abzuraten ist) und von oben nach unten. Mit einer Kontrollanweisung kann dieser lineare Programmfluss durchbrochen werden: Die Codeausführung kann kann abhängig von einer Bedingung gemacht werden (&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;), kann wiederholt werden (Schleife) oder an einer anderen Stelle der Funktion fortgesetzt werden (&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==if-Anweisung==&lt;br /&gt;
Mit Hilfe des if-Befehls kann man Codeteile abhängig davon einer Bedingung ausführen lassen:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
oder mit else-Teil&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 if (x &amp;gt; 100)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;gt; 100 ist: Fehlerausgabe}}&lt;br /&gt;
    printf (&amp;quot;x = %d ist zu gross fuer die Berechnung!\n&amp;quot;, x);&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;lt;&amp;amp;#61; 100 ist: Berechne Summe der Zahlen 1...x}}&lt;br /&gt;
    {{comment|Die lokale Variable x2 lebt nur innerhalb dieses alse-Blocks}}&lt;br /&gt;
    int x2 = x;&lt;br /&gt;
 &lt;br /&gt;
    for (x = 0; x2 &amp;gt; 0; x2--)&lt;br /&gt;
       x += x2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Wenn die Bedingung wahr ist (&amp;lt;tt&amp;gt;x &amp;gt; 100&amp;lt;/tt&amp;gt;), dann wird eine Meldung ausgegeben; danach ist die if-Anweisung beendet. Der else-Block wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung nicht erfüllt (&amp;lt;tt&amp;gt;x &amp;amp;le; 100&amp;lt;/tt&amp;gt;), dann wird gleich zum else-Teil gesprungen, und nach dessen Ausführung der if-Befehl beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Ein häufiger Fehler ist es, statt &amp;lt;tt&amp;gt;if (a &amp;amp;#61;&amp;amp;#61; 23)&amp;lt;/tt&amp;gt; etwas wie &amp;lt;tt&amp;gt;if (a &amp;amp;#61; 23)&amp;lt;/tt&amp;gt; zu schreiben. &lt;br /&gt;
Dann wird allerdings nicht geprüft, ob die Variable&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gleich 23 ist, sondern der Variablen&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wird der Wert 23 zugewiesen. Der Ausdruck &amp;lt;tt&amp;gt;a &amp;amp;#61; 23&amp;lt;/tt&amp;gt; hat den Wert&amp;amp;nbsp;23 und ist damit immer &amp;quot;wahr&amp;quot;! Daher ist diese if-Bedingung immer erfüllt!&lt;br /&gt;
&lt;br /&gt;
Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken sondern bestenfalls eine Warnung. Damit ist dieser Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise &amp;lt;tt&amp;gt;if (23 &amp;amp;#61;&amp;amp;#61; a)&amp;lt;/tt&amp;gt;. Wenn man dort anstatt des Vergleichsoperators '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;amp;#61;&amp;lt;/tt&amp;gt;' den Zuweisungsoperator '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;lt;/tt&amp;gt;' verwendet, spuckt der Compiler sehr wohl einen Fehler aus! Ist die Zuweisung jedoch erwünscht und eine Compiler-Warnung lästig, dann wählt man eine Schreibweise wie &amp;lt;tt&amp;gt;if ((a &amp;amp;#61; b))&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;if (a &amp;amp;#61; b, a)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist zu schreiben &amp;lt;tt&amp;gt;if (Bedingung);&amp;lt;/tt&amp;gt; Richtig muss es heissen &amp;quot;&amp;lt;tt&amp;gt;if(Bedingung)&amp;lt;/tt&amp;gt;&amp;quot; Das Semikolon im ersten Fall ist eine leere Anweisung, die im if-Falle ausgeführt wird &amp;amp;ndash; sie bleibt also ohne Resultet. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt; ein auf das Semikolon folgende Anweisung die eigentlich zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören soll wird immer ausgeführt, die sie nicht mehr zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; dazu gehört.&lt;br /&gt;
}}&lt;br /&gt;
Bei verschachtelten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Konstrukten gehört ein &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zu letzten &amp;quot;freien&amp;quot; &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;. Soll in einer &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Folge das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zum ersten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören, dann ist das so zu hinzuschreiben:&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Ohne die geschweiften Klammern um das zweite &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehörte das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; dort hinzu.&lt;br /&gt;
&lt;br /&gt;
==switch-Anweisung==&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
&lt;br /&gt;
 switch ({{Ausdruck|}}) &lt;br /&gt;
 {&lt;br /&gt;
     case konstante1:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
    &lt;br /&gt;
     case konstante2:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 &lt;br /&gt;
     {{comment|weitere case-Marken}}&lt;br /&gt;
 &lt;br /&gt;
     default:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 } {{comment|Ende von switch}} &lt;br /&gt;
&lt;br /&gt;
Der Ausdruck muss ein skalarer Typ sein, er wird in die nächste ganze Zahl gewandelt und mit den Werten hinter den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Marken verglichen. Bei einer Übereinstimmung werden alle Befehle ab dem zutreffenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; ausgeführt. Stimmt der Ausdruck mit keinem der Werte überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt falls vorhanden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der nachfolgenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;- und des &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitts werden ausgeführt, wenn die Anweisungen des &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitts nicht mit dem Befehl &amp;lt;tt&amp;gt;break;&amp;lt;/tt&amp;gt; beendet werden!&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es dürfen beliebig viele &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitte angegeben werden, pro Vergleichswert jedoch nur einer.&lt;br /&gt;
Der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ist optional. Die Reihenfolge, in der &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt; angegeben werden, ist unerheblich.&lt;br /&gt;
&lt;br /&gt;
==Schleifen==&lt;br /&gt;
Um Anweisungen mehrmals hintereinander auszuführen, benötigt man Schleifen. Diese führen Anweisungen aus, bis oder solange Bedingungen erfüllt sind.&amp;lt;br&amp;gt; &lt;br /&gt;
Wichtig ist also, ob die Bedingung '''vor''' oder '''nach''' den Schleifen-Anweisungen geprüft wird. &lt;br /&gt;
&lt;br /&gt;
===while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 while ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Die while-Schleife wird solange durchlaufen, wie die Bedingung erfüllt ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Die Anweisung kann natürlich auch ein Block sein, der aus mehreren Deklarationen und Anweisungen besteht. &lt;br /&gt;
&lt;br /&gt;
 int zahl1 = 0;&lt;br /&gt;
 int zahl2 = 1;&lt;br /&gt;
 &lt;br /&gt;
 while (zahl1 &amp;lt; 3)&lt;br /&gt;
 {&lt;br /&gt;
    zahl1 = zahl1 + 1;&lt;br /&gt;
    zahl2 = zahl2 * 2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife drei mal durchlaufen. Zu Beginn des vierten Durchlaufs ist die Bedingung nicht mehr erfüllt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
&lt;br /&gt;
===do-while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
Die do-while-Schleife wird auf jeden Fall einmal durchlaufen und dann solange wiederholt, wie die Bedingung erfüllt ist.&lt;br /&gt;
 int i = 2;&lt;br /&gt;
 &lt;br /&gt;
 do &lt;br /&gt;
 {&lt;br /&gt;
     i = i*i;   {{comment|i quadrieren}}&lt;br /&gt;
     printf (&amp;quot;i = %d\n&amp;quot;, i);&lt;br /&gt;
 }&lt;br /&gt;
 while (i &amp;lt; 20);&lt;br /&gt;
&lt;br /&gt;
Die Schleife wird durchlaufen und wiederholt, solange &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; kleiner als 20 ist. Es werden also nacheinander die Werte 2, 4 und 16 ausgegeben. Nach der Schleife hat&amp;amp;nbsp;&amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; den Wert 256.&lt;br /&gt;
&lt;br /&gt;
===for-Schleife===&lt;br /&gt;
'''Syntax:''' &lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Bei den Ausdrücken wird es sich um einen Ausdrücke mit Nebeneffekt handeln wie etwa &amp;lt;tt&amp;gt;i=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;i=i+2&amp;lt;/tt&amp;gt;. Es werden folgende Aktionen ausgeführt:&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# falls die Bedingung wahr ist, dann führe &amp;lt;tt&amp;gt;Anweisung&amp;lt;/tt&amp;gt; aus.&lt;br /&gt;
# falls die Bedingung unwahr ist, dann sprinte zu 7 (Ende).&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# gehe zu 2&lt;br /&gt;
# nächste Anweisung nach der for-Schleife&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int lauf, summe;&lt;br /&gt;
 &lt;br /&gt;
 for (lauf=1, summe=0; lauf &amp;lt;= 10; lauf += 2) &lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel ist &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; ein [[#Komma-Operator|Komma-Ausdruck]], der zwei Anweisungen kombiniert und daher sogar zwei Nebeneffente hat: er setzt &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;1 und &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;0.&lt;br /&gt;
&lt;br /&gt;
Das Äquivalent als while-Schleife:&lt;br /&gt;
&lt;br /&gt;
 int lauf  = 1;                 {{comment|Anfangswerte}}&lt;br /&gt;
 int summe = 0;&lt;br /&gt;
 &lt;br /&gt;
 while (lauf &amp;lt;= 10)             {{comment|Bedingung}}&lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
    lauf  += 2;                 {{comment|Inkrement}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; in jedem Schleifendurchlauf um die Laufvariable &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; erhöht. Da &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nacheinander die ungeraden Werte von&amp;amp;nbsp;1 bis&amp;amp;nbsp;10 annimmt, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von&amp;amp;nbsp;1 bis kleinergleich 10 gespeichert, also der Wert&amp;amp;nbsp;25. &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; hat nach der Schleife den Wert&amp;amp;nbsp;11.&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf = 1&amp;lt;/tt&amp;gt; bedeutet, dass der Variablen &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; vor dem ersten Schleifendurchlauf der Wert&amp;amp;nbsp;1 zugewiesen wird. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf &amp;lt;= 10&amp;lt;/tt&amp;gt; ist die Schleifenbedingung; ist sie nicht erfüllt, wird die Schleife beendet. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf += 2&amp;lt;/tt&amp;gt; bedeutet, dass &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nach jedem Durchlauf um&amp;amp;nbsp;2 erhöht wird.&lt;br /&gt;
&lt;br /&gt;
===continue-Anweisung===&lt;br /&gt;
Innerhalb einer Schleife darf die &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die nachfolgenden Anweisungen übersprungen werden und mit dem nächsten Schleifendurchlauf fortgesetzt wird &amp;amp;ndash; vorausgesetzt die Schleifenbedingung ist noch erfüllt. Ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; etc. stehen, wenn dieses innerhalb einer Schleife steht.&lt;br /&gt;
&lt;br /&gt;
==break-Anweisung==&lt;br /&gt;
Innerhalb einer Schleife oder eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; darf die &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die Schleifen-/Switch-Anweisung sofort verlassen wird und das Programm dahinter weiter macht. Bei mehrfach geschachtelten Schleifen wird nur die innere verlassen. Ein &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; stehen, wenn dieses innerhalb einer Schleife/Switch-Anweisung steht.&lt;br /&gt;
&lt;br /&gt;
==goto-Anweisung==&lt;br /&gt;
&lt;br /&gt;
Innerhalb ein und derselben Funktion kann mit &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; an eine andere Stelle gesprungen werden. Dazu gibt man hinter dem &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einen Bezeichner an, der dadurch als Label fungiert:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 goto {{Bezeichner}};&lt;br /&gt;
Die Bezeichner selbst steht irgendwo in der Funktion und wird dadurch zur Sprungmarke (Label), daß er von einem Doppelpunkt (und mindestens einer C-Anweisung, die auch leer sein darf) gefolgt wird.&lt;br /&gt;
&lt;br /&gt;
Das Beispiel durchsucht das 2-dimensionale &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array &amp;lt;tt&amp;gt;feld&amp;lt;/tt&amp;gt; mit den &amp;lt;tt&amp;gt;SIZE_X &amp;amp;times; SIZE_Y&amp;lt;/tt&amp;gt; Werten nach dem Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;. Wird er gefunden, dann wird die 2-fach geschachtelte Suchschleife verlassen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int x, y;&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y; y++)&lt;br /&gt;
       if (feld[x][y] == 0)&lt;br /&gt;
          goto done;&lt;br /&gt;
 {{Label|done:}};&lt;br /&gt;
&lt;br /&gt;
Der folgende Code hat die gleiche Funktion, arbeitet jedoch ohne &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int x, y;&lt;br /&gt;
 int found = 0; {{comment|FALSE}}&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X &amp;amp;&amp;amp; !found; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y &amp;amp;&amp;amp; !found; y++)&lt;br /&gt;
       found = (0 == feld[x][y]);&lt;br /&gt;
Der Nachteil der &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-losen Variante ist, daß man eine Variable, die merkt, ob das Suchziel gefunden wurde, mitschleppen und in ''jedem'' Schleifendurchlauf abtesten muss. Dies bedeutet einen höheren Programmier- und Laufzeitaufwand und ist nicht so klar formuliert wie das &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-Beispiel.&lt;br /&gt;
&lt;br /&gt;
Gleichwohl sei angemerkt, daß die Verwendung von &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einem gewissen Dogmatismus unterliegt, der sich wie folgt subsummieren liesse:&lt;br /&gt;
:''goto ist böse und sollte keinesfalls verwendet werden! Wer es dennoch tut, offenbart dadurch seinen schlechten Geschmach sowie mangelhafte C-Kenntnis.'' &amp;lt;div align=&amp;quot;right&amp;quot;&amp;gt;http://www.roboternetz.de/phpBB2/images/smiles/icon_wink.gif&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Funktionen=&lt;br /&gt;
Stellen Dir vor, Du hast eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben &amp;amp;ndash; was Dich Zeit beim Erstellen des Programms und Speicherplatz im ausführbaren Programm kostet &amp;amp;ndash; kannst Du den Code-Abschnitt in eine Funktion schreiben und diese von jeder Stelle des Programms aus verwenden. Die Hauptgründe, um Funktionen zu verwenden, sind:&lt;br /&gt;
;Wiederverwendung von Code: Mehrfach verwendete Codestücke müssen nicht mehrfach implementiert werden. Oft unterscheiden sich die Codesequenzen nur in Kleinigkeiten, die man der Funktion über Parameter mitteilen kann.&lt;br /&gt;
;Übersichtlichkeit: Ein gut gegliedertes C-Programm implementiert klar umrissene Aufgaben in einer Funktion, auch wenn diese Funktion nur einmal im Code aufgerufen wird! Dadurch bleibt der Code um die Aufrufstelle besser verständlich, und man kann auf verschiedenen &amp;quot;Ebenen&amp;quot; denken. Eine Funktion wie &amp;quot;Datei öffnen&amp;quot; kann recht komplex sein. Auf höherer Ebene interessieren die Innereien nicht mehr, man möchte sich um andere Dinge kümmern und will den Code an der Stelle garnicht sehen...&lt;br /&gt;
;Rekursive Funktionen: Eine Funktion kann sich auch selbst aufrufen. In dem Falle nennt man die Funktion ''rekursiv''. Zwar lässt sich das, was eine rekursive Funktion tut, auch mit anderen Mitteln formulieren, die keine rekursiven Funktionen brauchen, aber oft ist der rekursive Weg knackiger und klarer formulierbar als eine nicht-rekursiven Ansatz, auch wenn es etwas mehr Resourcen verbraucht.&lt;br /&gt;
;Modulare Programmierung: Funktionen können anhand ihres Aufgabenbereichs auf verschiedene C-Quellen &amp;amp;ndash; sogenannte ''Module'' &amp;amp;ndash; verteilt werden. Funktionen, die etwas mit dem USB-Bus anstellen, werden in einem anderen Modul sein als mathematische Funktionen. Dies erhöht die Übersichtlichkeit und vereinfacht die Entwicklung im Team.&lt;br /&gt;
;Bibliotheken: Standard-Funktionen wie das hier oft auftauchende &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; sind in Bibliotheken gespeichert. Wenn das eigene Programm übersetzt wird, dann müssen nicht mehr alle Standard-Funktionen übersetzt werden, sondern werden nur noch aus der Bibliothek gelesen und ihr Code zum Programm dazugelinkt. Die Bibliotheks-Funktionen wurden schon zu einem früheren Zeitpunkt compiliert und liegen in dieser compilerten Form in der Bibliothek. Das spart mächtig Entwicklungszeit. Man kann auch selbst solche Bibliotheken erstellen und in diversen Projekten wiederverwenden.&lt;br /&gt;
;Generische Programmierung: In C ist es möglich, einer Funktion eine andere Funktion zu übergeben. (Damit ist nicht gemeint, ihr deren ''Rückgabewert'' zu übergeben (was auch ginge), sondern ''die Funktion selbst'' wird als Parameter übergeben und kann aufgerufen werden.) Ein typisches Beispiel dafür sind Sortieralgorithmen. Einem Sortieralgorithmus kann es egal sein, ''was'' er sortiert. Er muss lediglich wissen, ''wie'' er das Zeug zu sortieren hat: aufsteigend, absteigend, als Zahl, in lexikographischer Ordnung, nach der Quersumme, Körper nach Oberfläche, Durchmesser, Gewicht oder Volumen... Diese Vergleichsfunktion, die für zwei Objekte entscheidet, welches davon &amp;quot;kleiner&amp;quot; ist, kann man dem Sortierer übergeben. Will er zwei Werte vergleichen, dann muss er nur die Vergleichsfunktion aufrufen, ohne zu wissen, was diese tut. Damit kann der Sortieralgorithmus unanhängig von den Objekten gehalten werden, mit denen er hantieren soll.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Definition==&lt;br /&gt;
&lt;br /&gt;
In der ''Definition'' der Funktion wird gesagt, welche Werte sie liefern kann, wie sie heisst (Bezeichner) und wieviele und welche Parameter sie hat. Danach folgt ihre Implementierung:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}} ({{Parameterliste}})&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 &lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
Für Funktionen, die keinen Wert zurückliefern, gibt es den speziellen Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der besagt, daß die Funktion nichts zurückgibt. Die einfachste denkbare Funktion ist eine solch void-Funktion. Sie bekommt keine Parameter, gibt nicht zurück und ihr Body ist leer:&lt;br /&gt;
 void dummy()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==return-Anweisung==&lt;br /&gt;
An jeder Stelle des Programmflusses einer Funktion kann diese mit &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; beendet werden.&lt;br /&gt;
&lt;br /&gt;
'''bei void-Funktionen:'''&lt;br /&gt;
 return;&lt;br /&gt;
'''Funktionen mit Rückgabe-Wert:'''&lt;br /&gt;
 return {{Ausdruck|}};&lt;br /&gt;
Die zweite Variante gibt an, welcher Wert zurückgegeben wird.&lt;br /&gt;
 int main (int argc, char * argv[])&lt;br /&gt;
 {&lt;br /&gt;
    if (argc &amp;lt; 2)&lt;br /&gt;
       return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
Falls die letzte Anweisung einer void-Funktion ein &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; ist, kann es auch weggelassen werden wie oben bei der Funktion &amp;lt;tt&amp;gt;dummy&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Aufruf==&lt;br /&gt;
Um die Funktion aufzurufen gibt man ihren Namen an, gefolgt von den durch Komma getrennten Argumenten in runden Klammern wie im Beispiel unten das&lt;br /&gt;
 quadrat (5) &lt;br /&gt;
Da &amp;lt;tt&amp;gt;quadrat&amp;lt;/tt&amp;gt; einen Wert liefert, kann man damit weiter rechnen wie mit einem normalen Ausdruck:&lt;br /&gt;
 if (quadrat (a) + quadrat (b) == quadrat (c))&lt;br /&gt;
    c = quadrat (quadrat (a)); {{comment|c &amp;amp;#61; a hoch 4}}&lt;br /&gt;
&lt;br /&gt;
Ein Hinweis am Rande:&amp;lt;p&amp;gt;&lt;br /&gt;
Der Name einer Funktion ohne die beiden runden Klammern ist der Pointer/Zeiger auf ihren Anfang.&lt;br /&gt;
Damit kann ein Funktionsname überall dort verwendet werden, wo Pointer/Zeiger &lt;br /&gt;
zulässig sind. Insbesondere kann er als Argument einer weiteren Funktion dienen.&lt;br /&gt;
&lt;br /&gt;
==Rekursive Funktionen==&lt;br /&gt;
Eine Funktion die sich selbst &amp;amp;ndash; möglicheweise auch über andere Zwischenfunktionen &amp;amp;ndash; wieder selbst aufruft, wird als ''rekursive Funktion'' bezeichnet. In der Definition ist nichts besonderes zu beachten. Ist die Verschachtelungstiefe im laufenden Programm zu tief, dann gibt das natürlich Probleme, aber das gilt bei tief verschachtelten 'normalen' Funktionen abenso...&lt;br /&gt;
&lt;br /&gt;
Das Beispiel berechnet den Größten Gemeinsamen Teiler zweier Zahlen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int ggT (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
     if (0 == a)&lt;br /&gt;
        return b;&lt;br /&gt;
 &lt;br /&gt;
    return ggT (b % a, a);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Ein komplettes kleines Programm:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int quadrat (int param1)&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  zahl = param1 * param1;&lt;br /&gt;
  return zahl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl, ergebnis;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Bitte Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = quadrat (zahl);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, zahl, ergebnis);&lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, 5, quadrat (5));&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur ausserhalb von Blöcken. Geschachtelte Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen beim Aufruf die Klammern angeben werden:&lt;br /&gt;
 dummy();&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Prototypen==&lt;br /&gt;
Wie oben erwähnt, kann ein Unterprogramm an jeder beliebigen Stelle im Programm stehen. Damit ist jedoch eine Bedingung verknüpft: Das Unterprogramm muß in der Datei oberhalb des ersten Aufrufes definiert worden sein. Wenn Sie ein Unterprogramm in Zeile 10 zum ersten mal aufrufen, müssen Sie die Deklaration davor erledigt haben. Verstanden?&lt;br /&gt;
Um dies zu erreichen, gibt es zwei Möglichkeiten: &lt;br /&gt;
&lt;br /&gt;
Entweder Sie schreiben alle Unterprogramme vor &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; in die Datei. Dies muß jedoch wiederum so geschehen, dass Funktionen zum Zeitpunkt ihres Aufrufes bereits bekannt sind! &lt;br /&gt;
Wo dies nicht möglich ist (z.B. sich gegenseitig aufrufende Unterprogramme), oder wenn Sie das stört, müssen Sie Prototypen verwenden. &lt;br /&gt;
Wie definiert man nun Prototypen? Sie kopieren einfach die erste Zeile des Unterprogrammes (z.B. &amp;quot;&amp;lt;tt&amp;gt;void ausgeben (int zahl)&amp;lt;/tt&amp;gt;&amp;quot;), fügen einen Strichpunkt&amp;amp;nbsp;&amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;an und fügen es an einer geeigneten Stelle ein (so, dass alle Aufrufe später in der Datei kommen). &lt;br /&gt;
Solche Definitionen stehen gewöhnlich am Anfang der Quelldatei oder in einer Header-Datei, die eingebunden wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl);  /* Der Prototyp */&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
   ausgeben (12);&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl)   /* Die eigentliche Prozedur */&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Ausgabe: %d\n&amp;quot;, zahl);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Parameterübergabe==&lt;br /&gt;
&lt;br /&gt;
Alle Werte, die an Prozeduren und Funktionen übergeben werden, werden grundsätzlich '''kopiert'''.&lt;br /&gt;
Das hat folgende Auswirkungen:&lt;br /&gt;
&lt;br /&gt;
# Änderungen an einem Parameter in einer Funktion erscheinen ''nicht'' beim Aufrufer!&lt;br /&gt;
# Möchte man, dass eine Funktion einen Wert trotzdem dauerhaft ändern soll, so muss die Adresse des Wertes via [[#Zeiger|Zeiger]] übergeben werden.&lt;br /&gt;
# Werden [[#Strukturen|Strukturen]] übergeben, so wird von ihnen eine Kopie erstellt, was bei großen Strukturen viel Zeit und Arbeitsspeicher kostet. Deshalb wird häufig nur die Adresse von Strukturen übergeben, da die Adresse viel schneller und platzsparender als die Struktur selbst kopiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele:'''&lt;br /&gt;
 void erhoehe (int x)&lt;br /&gt;
 {&lt;br /&gt;
    x = x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe(a);&lt;br /&gt;
    {{comment|a ist immer noch 0}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Beim Aufruf von &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; wird eine Kopie des Wertes von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; (im Beispiel also 0) erstellt und der Prozedur als Parameter &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; übergeben. Weil dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat dies keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|erhoehe den Wert an der Adresse x um eins}}&lt;br /&gt;
    *x = *x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe (&amp;amp;a);&lt;br /&gt;
    {{comment|a ist jetzt 1}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Jetzt wird im Hauptprogramm mittels [[#Adress-Operator und Dereferenzierung|Adress-Operator]] &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; die Speicheradresse von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; bestimmt. Dann wird eine ''Kopie der Adresse'' an das Unterprogramm &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; übergeben. Jetzt kennt das Unterprogramm die&lt;br /&gt;
Adresse des Originals &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und kann direkt mit dem Inhalts-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&lt;br /&gt;
'''Besonderheit bei Feldern'''&lt;br /&gt;
&lt;br /&gt;
Bei der Übergabe von [[#Felder|Feldern]] gibt es eine Besonderheit. Schreibt man nämlich den Namen eines Feldes, so ist das nichts anderes als die '''Speicheradresse des ersten Elements'''.&lt;br /&gt;
Bei der Übergabe eines Feldes wird also eine Kopie der Startadresse übergeben. Somit kann das Unterprogramm auf den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 void erhoehe (int x[])&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
   int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
   erhoehe (a);&lt;br /&gt;
   {{comment|a hat jetzt folgenden Inhalte: 11, 23, 35}}&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Dass die Übergabe einer Adresse erfolgt, sieht man an folgendem Beispiel, das von der Funktionsweise '''absolut identisch''' mit dem vorhergehenden ist:&lt;br /&gt;
&lt;br /&gt;
 {{comment|Bei Parametern gibt es keinen Unterschied zwischen Zeiger und Feld}}&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
    int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
    erhoehe (a);&lt;br /&gt;
 &lt;br /&gt;
    {{comment|a hat jetzt folgenden Inhalt: 11, 23, 35}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
Die Länge des Feldes wird nicht automatisch übergeben. Dafür ist ggf. ein zusätzlicher Parameter notwendig.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Variable Argumentanzahl==&lt;br /&gt;
== Funktionen indirekt aufrufen ==&lt;br /&gt;
Siehe [[#Zeiger auf Funktionen|Zeiger auf Funktionen]]&lt;br /&gt;
&lt;br /&gt;
=Zeiger II=&lt;br /&gt;
&lt;br /&gt;
Zeiger haben wir bereits weiter oben kennen gelernt. Zeiger sind ein zentrales Konzept in C und sollen hier etwas eingehender behandelt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger-Arithmetik==&lt;br /&gt;
In C kann man den Wert eines Zeigers verändern. Betrachten wir dazu die Funktion &amp;lt;tt&amp;gt;suche_0&amp;lt;/tt&amp;gt;, die einen Zeiger auf einen &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; erhält. Die Funktion soll ab der gegebenen Adresse nach dem ersten long-Wert suchen, der 0 ist, und dessen Adresse zurückgeben:&lt;br /&gt;
 long * suche_0 (long * addr)&lt;br /&gt;
 {&lt;br /&gt;
    while (*addr != 0)&lt;br /&gt;
       addr = addr + 1;&lt;br /&gt;
 &lt;br /&gt;
    return addr;&lt;br /&gt;
 }&lt;br /&gt;
In der Bedingung der while-Schleife wird der Inhalt an der Speicherstelle &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf 0 getestet. Ist der Wert 0, dann wird die Schleife beendet und die Adresse zurückgeliefert. Ist der Wert ungleich 0, dann wird &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf den nächste long gesetzt, &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; also um 4 Bytes weitergezählt. &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ist ja ein Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, und ein &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; ist 4 Bytes lang.&lt;br /&gt;
&lt;br /&gt;
Die Bedeutung von&lt;br /&gt;
 address + n&lt;br /&gt;
ist also, die Adresse um das &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;-fache der Größe des Typs, auf den &amp;lt;tt&amp;gt;address&amp;lt;/tt&amp;gt; zeigt, zu erhöhen. Dabei ist &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; eine ganze Zahl und darf auch negativ sein.&lt;br /&gt;
&lt;br /&gt;
Hier noch ein Beispiel einer Funktion, die nach einer Person mit einer bestimmten ID sucht (für die Definition von &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; siehe [[#Strukturen|Strukturen]]). Der Parameter &amp;lt;tt&amp;gt;person&amp;lt;/tt&amp;gt; ist dabei ein Array von Strukturen. Eine Person mit der gesuchten ID muss existieren, ansonsten hat die Suchfunktion kein definiertes Verhalten.&lt;br /&gt;
 {{comment|Sucht nach einer Person mit der ID person_id}}&lt;br /&gt;
 struct Person * &lt;br /&gt;
 suche_person_id (struct Person * person, int person_id)&lt;br /&gt;
 {&lt;br /&gt;
    while (person-&amp;gt;id != person_id)&lt;br /&gt;
       person++;&lt;br /&gt;
 &lt;br /&gt;
    return person;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:1em; padding:1em; border:solid 2px #FF0040;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- Vorlage:FarbigerRahmen funzt hier net --&amp;gt;&lt;br /&gt;
Beachte, daß es nicht sinnvoll ist, zwei Zeiger zu addieren oder zu multiplizieren. Ausserdem ist das &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt; der Zeiger-Arithmetik nicht kommutativ. Eine Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, der an Adresse 1 im Speicher zeigt, wird man schreiben als&lt;br /&gt;
 (long *) 1&lt;br /&gt;
Addiert man darauf eine ganze Zahl, dann haben die entstehenden Ausdrücke unterschiedliche Werte:&lt;br /&gt;
 (long *) 1 + 2    {{comment|zeigt zu Adresse 9}}&lt;br /&gt;
 (long *) 2 + 1    {{comment|zeigt zu Adresse 6}}&lt;br /&gt;
 (long *) (1 + 2)  {{comment|zeigt zu Adresse 3}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==void-Pointer==&lt;br /&gt;
Eine besondere Art von Zeiger ist der void-Pointer&lt;br /&gt;
 void * addr;&lt;br /&gt;
Ein void-Pointer ist ein &amp;quot;Zeiger auf irgendwas&amp;quot;, dementsprechend kann er nicht dereferenziert werden, Anwenden von &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf einen solchen Zeiger gibt also einen Fehler. Ausserdem ist es nicht möglich, mit einem void-Pointer Zeigerarithmetik zu machen, weil er nicht auf eine definierte Art von Objekt zeigt. Der Vorteil eines void-Pointers ist, daß er jede Art von Zeiger aufnehmen kann.&lt;br /&gt;
&lt;br /&gt;
Dazu betrachten wir die Funktion &amp;lt;tt&amp;gt;send_buf&amp;lt;/tt&amp;gt;, die eine Adresse erhält und ab dieser Adresse &amp;lt;tt&amp;gt;num&amp;lt;/tt&amp;gt; Bytes versenden soll. Wir könnten die Funktion so schreiben:&lt;br /&gt;
 void send_buf (unsigned char * buf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   ...&lt;br /&gt;
Das ist jedoch hässlich, wenn wir damit etwas anderes verschicken wollen als &amp;lt;tt&amp;gt; unsigned char&amp;lt;/tt&amp;gt;, etwa eine Struktur wie &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; (vom Typ &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;):&lt;br /&gt;
 send_buf ((unsigned char*) &amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
Ohne den Cast der Adresse von &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; zu einem Zeiger auf &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt; bekommt man eine Warnung oder gar einen Compilerfehler.&lt;br /&gt;
Dieses Zeiger gecaste ist mühsam und hässlich, es muss bei jedem Aufruf der Funktion explizit hingeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Besser ist es, den ersten Parameter der Funktion als void-Pointer zu definieren und den Cast in der Funktion zu machen:&lt;br /&gt;
 void send_buf (void * vbuf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   unsigned char *buf = (unsigned char*) vbuf;&lt;br /&gt;
   ...&lt;br /&gt;
Durch den Cast in der Funktion kann auf den Inhalt des Zeigers zugegriffen werden. Man muss nur festlegen, ''wie'' man zugreifen will, nämlich als &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Der Aufruf kann jetzt ohne Pointer-Cast erfolgen: &lt;br /&gt;
 send_buf (&amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
&lt;br /&gt;
==Null-Pointer==&lt;br /&gt;
==Zeiger als Parameter==&lt;br /&gt;
Wenn Sie ein Unterprogramm aufrufen, können Sie diesem Parameter übergeben, aber keine Werte zurückgekommen (außer den Funktionswert bei Funktionen). Dies hat einen guten Grund: beim Aufruf werden nicht die aufgerufenen Parameter benutzt, sondern es werden deren Werte in neue Variablen kopiert. Diese Variablen werden am Ende des Unterprogrammes &amp;quot;zerstört&amp;quot;, ohne ihre Werte an die aufrufenden Parameter zu übergeben. Jede Veränderung eines Parameters hat daher keine Auswirkung auf den Parameter.&lt;br /&gt;
&lt;br /&gt;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der C-Compiler legt dann immer noch Kopien an. In dieser Kopie steht aber kein Wert, sondern die Adresse einer Varaiblen. Und auf diese können Sie dann zugreifen. Denken Sie nur an &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; &amp;amp;ndash; da übergeben Sie ja auch die Adresse einer Variablen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void erhoehe (int *zeiger)&lt;br /&gt;
{&lt;br /&gt;
  *zeiger = 1 + *zeiger;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  erhoehe (&amp;amp;zahl);&lt;br /&gt;
  printf (&amp;quot;\nDie erhoehte Zahl lautet: %d\n&amp;quot;, zahl);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Zeiger auf Funktionen==&lt;br /&gt;
&lt;br /&gt;
Stell dir vor, du willst einen Sortieralgorithmus wie Bubble-Sort oder Quick-Sort oder wie sie alle heissen implementieren. Für den Sortieralgorithmus ist eigentlich egal, ''was'' er zu sortieren hat. Ihm ist es egal, ob er Zahlen aufwärts sortieren soll oder Strings in lexikographischer Reihenfolge, ob Objekte nach Größe oder Gewicht, Personen nach Alter oder Adressen nach Postleitzahl. Das einzige, was der Algorithmus wissen muss, ist ''wie'' er zwei Objekte zu vergleichen hat und wann eines davon &amp;quot;kleiner&amp;quot; (im Sinne der Ordnung, nach der sortiert werden soll) ist. &lt;br /&gt;
&lt;br /&gt;
Eine einfache Sortierfunktion, die nur zwei Zahlen sortiert, könnte man also so schreiben: &lt;br /&gt;
 {{comment|Sortiert ein Array von 2 int-Zeigern nach den Inhalten &lt;br /&gt;
  * an den Zeiger-Adressen}}&lt;br /&gt;
 void sort2_a (int * p[])&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Inhalte vergleichen...}}&lt;br /&gt;
    if (*p[0] &amp;gt; *p[1])&lt;br /&gt;
    {&lt;br /&gt;
       {{comment|... und ggf. Dreieckstausch der 2 Zeiger}}&lt;br /&gt;
       int * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Die Funktion bekommt ein Array der Länge&amp;amp;nbsp;2. In diesem Array stehen Zeiger auf die zu sortierenden Zahlen. Ein Array mit Zeigern zu verwenden und nicht ein Array von &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; scheint recht umständlich, und das ist es hier auch. Aber stell dir vor, du willst Strukturen wie &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; sortieren. Das Tauschen zweier Strukturen würde bedeuten, ihre kompletten Inhalte umzukopieren! Das wäre sehr aufwändig. Viel einfacher ist das Kopieren, wenn nur die Adressen zu kopieren sind.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; könnte dann so aussehen:&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void sortiere (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|p[] enthält 2 int-Zeiger: die Adressen von a und b}}&lt;br /&gt;
    int * p[2];&lt;br /&gt;
    p[0] = &amp;amp;a; &lt;br /&gt;
    p[1] = &amp;amp;b; &lt;br /&gt;
 &lt;br /&gt;
    {{comment|Sortiere die Zeiger}} &lt;br /&gt;
    sort2_a (p);&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Sortiert: %d, %d\n&amp;quot;, *p[0], *p[1]);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Für den nächsten Schritt überlegen wir uns, daß das Array in &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; ebensogut void-Pointer enthalten kann. Die einzige Stelle, an der wir auf die endgültigen int-Objekte zugreifen, ist der Vergleich. Diesen Vergleich lagern wir in die Funktion &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; aus:&lt;br /&gt;
 {{comment|Bekommt zwei void-Pointer und vergleicht die Inhalte.&lt;br /&gt;
  * Liefert 0 bei Gleichheit,&lt;br /&gt;
  * -1 wenn der erste Wert kleiner ist als der zweite und&lt;br /&gt;
  * 1  wenn der erste Wert größer ist als der zweite}}&lt;br /&gt;
 int compare_int (void * p0, void * p1)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Um über die Zeiger zugreifen zu können müssen wir diese&lt;br /&gt;
     * erst zu int-Zeigern casten}}&lt;br /&gt;
    int a0 = * (int*) p0;&lt;br /&gt;
    int a1 = * (int*) p1;&lt;br /&gt;
 &lt;br /&gt;
    if (a0 &amp;gt; a1)  return  1;&lt;br /&gt;
    if (a0 &amp;lt; a1)  return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void sort2_b (void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare_int (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Ein Aufruf von &amp;lt;tt&amp;gt;sort2_b&amp;lt;/tt&amp;gt; sieht dann genauso aus wie ein Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt definieren wir uns den neuen Datentyp &amp;lt;tt&amp;gt;comparator_t&amp;lt;/tt&amp;gt;. Dieser ist ein Zeiger auf eine Funktion, die zwei void-Pointer erhält und einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; zurückliefert, also analog arbeitet zu &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; von oben. &lt;br /&gt;
&lt;br /&gt;
Unsere Sortierfunktion bekommt nun neben dem zu sortierenden Zeiger-Array auch eine Vergleichsfunktion &amp;lt;tt&amp;gt;compare&amp;lt;/tt&amp;gt; mitgeliefert, die sie aufruft, wenn sie zwei Objekte vergleichen will&lt;br /&gt;
 {{comment|comparator_t sind Zeiger auf Funktionen, die 2 void-Pointer&lt;br /&gt;
  * erhalten und einen int zurückliefern}}&lt;br /&gt;
 typedef int (*comparator_t) (void*, void*);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Der Sortierer bekommt einen Funktionszeiger auf den Vergleicher.&lt;br /&gt;
  * Der Aufruf vom compare geht so als wäre es eine &amp;quot;normale&amp;quot; Funktion&lt;br /&gt;
  * (ist es im Endeffekt ja auch)}}&lt;br /&gt;
 void sort2_c (comparator_t compare, void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Bei einem Aufruf von &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; muss man dann einen Komparator mit angeben. In einem Beispiel analog zu &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; von oben ist das:&lt;br /&gt;
 sort2_c (compare_int, p);&lt;br /&gt;
Um zwei Strings lexikographisch zu sortieren nehmen wie die Standard-Funktion &amp;lt;tt&amp;gt;strcmp&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void foo()&lt;br /&gt;
 {&lt;br /&gt;
    char * worte[] = { &amp;quot;Wort1&amp;quot;, &amp;quot;Wort2&amp;quot; };&lt;br /&gt;
 &lt;br /&gt;
    sort2_c ((comparator_t) strcmp, (void**) worte);&lt;br /&gt;
 }&lt;br /&gt;
Die Casts sind hier erforderlich. Alternativ könnte man &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; mit reinen void-Pointern versorgen und diese dann dort umcasten.&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
&lt;br /&gt;
Die Syntax zur Definition/Deklaration von Funktionszeigern ist etwas verzwackt. Zur Verdeutlichung ein paar Beispiele. Dabei legt das linke &amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt; jeweils den Return-Typ fest.&lt;br /&gt;
 {{comment|definiert einen neuen Funktionszeiger-Typ}}&lt;br /&gt;
 typedef {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert einen Funktionszeiger}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert ein Array von Funktionszeigern (mit Initializer)}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}[]) ({{type}}, {{type}}, ...) = { wert1, wert2, ... };&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer}}&lt;br /&gt;
 ({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer und ruft die Funktion auf}}&lt;br /&gt;
 (({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}) (arg1, arg2, ...);&lt;br /&gt;
&lt;br /&gt;
=Standard-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==String-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===strcpy===&lt;br /&gt;
Bei vielen Compilern können sie einem String nicht direkt einen Wert (Text) zuweisen. Dazu müssen Sie dann die Prozedur strcpy() benutzen. Diese erwartet als ersten Parameter den Namen einer String-Variablen (ohne eckige Klammern) und als zweiten Parameter den eines (anderen) Strings. Letzterer kann auch ein in doppelten Hochkommas (&amp;quot;) eingeschlossener Text sein. Die Funktion fügt am Ende automatisch ein 0-Zeichen ein. Um diese Funktion nutzen zu können, müssen Sie die Datei string.h includieren! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri1[21], eingabe[21];&lt;br /&gt;
&lt;br /&gt;
  strcpy (stri1, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Der 1. String: %s\n&amp;quot;, stri1);&lt;br /&gt;
  printf (&amp;quot;Bitte geben Sie maximal 20 Zeichen ein: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%s&amp;quot;, eingabe);&lt;br /&gt;
  strcpy (stri1, eingabe);&lt;br /&gt;
  printf (&amp;quot;\n%s = %s&amp;quot;, stri1, eingabe);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis:''' &lt;br /&gt;
Da ein String, wie jedes Feld, eigentlich ein Zeiger ist, dürfen Sie kein &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; bei &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; angeben!&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
Es werden zwei gleich große Strings definiert: &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;eingabe&amp;lt;/tt&amp;gt;, mit je 20 &amp;quot;nutzbaren&amp;quot; Zeichen. &lt;br /&gt;
In &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; wird die Zeichenkette &amp;lt;tt&amp;gt;&amp;quot;hallo&amp;quot;&amp;lt;/tt&amp;gt; hineinkopiert. Das 0-Zeichen am Ende wird automatisch angefügt. &lt;br /&gt;
Der String wird ausgegeben. Als neues &amp;quot;Sonderzeichen&amp;quot; kommt &amp;lt;tt&amp;gt;%s&amp;lt;/tt&amp;gt; ins Spiel. Es hat die gleiche Aufgabe wie &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt;, nur für Strings. &lt;br /&gt;
Sie werden gebeten, eine String einzugeben. &lt;br /&gt;
Dieser String wird danach in die Variable &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; kopiert. &lt;br /&gt;
Beide Strings, die ja nun die gleiche Zeichenkette enthalten, werden ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===strlen===&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;strlen&amp;lt;/tt&amp;gt;, die als Parameter eine String-Variable erwartet, liefert die Länge diese Strings zurück. Sie werden jetzt vermutlich sagen: &amp;quot;Das ist doch klar, wie lang der String ist. Ich habe es ja bei der Deklaratin angegeben&amp;quot;. Das stimmt schon, aber denken Sie noch einmal an die null-terminierten Strings. Das 0-Zeichen steht am Ende des Strings (am Ende der gültigen Zeichenfolge), aber nicht unbedingt am Ende des reservierten Speicherplatzes. Haben Sie eine Variable &amp;quot;char Variable[21];&amp;quot;, und ihr den Wert &amp;quot;hallo&amp;quot; zugewiesen, dann steht das null-Zeichen in Variable[5]. Der &amp;quot;gültige&amp;quot; String ist also 5 Zeichen (0-4) lang. Und genau das (5) würde strlen zurück liefern. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri[21];&lt;br /&gt;
  &lt;br /&gt;
  strcpy (stri, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
  printf (&amp;quot;Der String ist %d Zeichen lang&amp;quot;, strlen (stri));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird vor allem gebraucht, wenn Sie direkt auf den String zugreifen, mittels &amp;lt;tt&amp;gt;stri[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;stri[1]&amp;lt;/tt&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
==Ein- und Ausgabe-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===Bildschirm-Ausgabe===&lt;br /&gt;
Bisher war das Tutorial trotz aller Beispiele reine Theorie. Sie konnten zwar Programme schreiben, aber die Funktion nicht testen. Hier lernen Sie nun, wie Sie etwas am Bildschirm ausgeben.&lt;br /&gt;
&lt;br /&gt;
Die dazu notwendige Funktione heisst &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (das '&amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt;' ist kein Fehler!). Diese Anweisung gibt die ihr übergebenen Parameter auf das Standard-Ausgabegerät aus, in der Regel also auf den Bildschirm. Sie kann beliebig viele Parameter übernehmen. Es müssen jedoch Standard-Datentypen (z.B. &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;...) sein! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
    int zahl1 = 12;&lt;br /&gt;
    char zeichen1 = 'A';&lt;br /&gt;
    &lt;br /&gt;
    printf (&amp;quot;Das ist Text, und er wird als solcher ausgegeben. \n&amp;quot;);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zahl1' ist: %d \n&amp;quot;, zahl1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %c \n&amp;quot;, zeichen1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %d \n&amp;quot;, zeichen1);&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt Text aus. Das Zeichen am Ende (&amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;) bedeutet &amp;quot;New Line&amp;quot;, es bewegt den Cursor an den Anfang der nächsten Zeile. &lt;br /&gt;
&lt;br /&gt;
Der zweite &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt auch Text aus, am Ende befindet sich wieder das &amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;, um einen Zeilenvorschub zu erreichen. Das &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; wird vom Compiler durch den ersten Parameter ersetzt, der nach dem Text angegeben wird. In diesem Fall wird &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; also durch den Wert der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ersetzt. Das &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; im &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; bedeutet &amp;quot;Dezimalzahl&amp;quot;, der Computer gibt also eine ganze Zahl aus. &lt;br /&gt;
&lt;br /&gt;
In der dritten Ausgabe wird ein Zeichen ausgegeben. Diesmal bedeutet &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; &amp;quot;char&amp;quot; (Zeichen). Es wird also &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; durch ein &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt; ersetzt, denn die Variable &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; wird als Character interpretiert. &lt;br /&gt;
&lt;br /&gt;
Die letzte Ausgabe interpretiert den Inhalt von &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; als Zahl, und gibt dager den ASCII-Wert von &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, also 65 aus. Das ist ein typisches Beispiel für das mögliche unterschiedliche Interpretieren einer  Variablen!&lt;br /&gt;
&lt;br /&gt;
===Tastatur-Eingabe===&lt;br /&gt;
&lt;br /&gt;
Um ein &amp;quot;gscheites&amp;quot; Programm schreiben zu können, muß man wissen, wie der Benutzer über die Tastatur Befehle eingeben kann. Die dafür notwendigen Funktionen stelle ich in diesem Kapitel vor.&lt;br /&gt;
Die wichtigste Funktion ist &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt;. Er liest Daten von der Tastatur. Die Syntax entspricht derer von &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int  zahl1;&lt;br /&gt;
char zeichen1;&lt;br /&gt;
&lt;br /&gt;
printf (&amp;quot;Bitte geben Sie eine Zahl ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl1);&lt;br /&gt;
printf (&amp;quot;Geben Sie einen Zeichen ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%c&amp;quot;, &amp;amp;zeichen1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Programm gibt eine Eingabeaufforderung aus. Dann erwartet es vom Benutzer, daß er eine Zahl eingibt, die mit [ENTER] bestätigt wird. Dieser Wert wird in &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; abgespeichert. Danach erfolgt wiederum eine Aufforderung zur Eingabe, diesmal eines einzelnen Zeichens. Dieses kann man nun eingeben und ebenfalls mit [ENTER] bestätigen.&lt;br /&gt;
&lt;br /&gt;
Macht man keine dem Datentyp der erwarteten Variable entsprechende Eingabe, dann bricht das Programm mit einer Fehlermeldung ab (wenn man z.B. &amp;quot;1_T2&amp;quot; eingibt, wenn eine Zahl erwartet wird)!&lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; vor den Parametern ist notwendig. Warum, das erfahren Sie im Kapitel &amp;quot;Unterprogramme&amp;quot;. Für die Profis eine Kurz-Erklärung: Das Unterprogramm &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; bekommt zwar einen Wert übergeben, kann aber keinen zurückliefern (&amp;quot;call by value&amp;quot;). Daher wird kein Wert, sondern ein Zeiger auf eine Variable übergeben. Mit dem &amp;amp; Zeichen bekommen Sie die Adresse einer Variablen (&amp;quot;call by reference&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=Parameter von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;=&lt;br /&gt;
Das Unterprogramm &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; kann, wie jede andere Funktion, Parameter besitzen. Doch keine selbst gewählten, sondern nur bestimmte. Doch warum braucht main Parameter? Denken Sie einmal an alle Betriebssystembefehle:&lt;br /&gt;
&amp;lt;tt&amp;gt;dir *.exe &amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;copy *.* a:&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;ls -la &amp;lt;/tt&amp;gt;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;&amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen!&lt;br /&gt;
&lt;br /&gt;
=Kurzreferenz=&lt;br /&gt;
==Syntax-Bausteine==&lt;br /&gt;
&lt;br /&gt;
Die Erklärung des Aufbaus von C-Befehlen erfolgt neben einfachen Beispielen auch durch ihren prinzipellen Aufbau. In diesen Syntax-Beschreibungen finden sich immer wieder die gleichen Bausteine, die hier näher erklärt werden sollen. Falls die solch ein Syntax-Baustein begegnet, kannst Du ihn anclicken und kommst dann zu seiner Erläuterung. &lt;br /&gt;
&lt;br /&gt;
In den Beispielen selbst gehören auch die spitzen Klammern zu dem Baustein (was daran zu erkennen ist, daß auch die Klammern eingefärbt sind). Die Klammern dürfen in einem konkreten C-Programm daher nicht eingetippt werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bezeichner&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Bezeichner in C dienen dazu, Variablen zu identifizieren und ihnen sprechende Namen zu geben, um die Quelle lesbarer zu machen. Man braucht Bezeichner auch, um selbstdefinierte Datentypen zu benennen und zum Benennen von Struct- und Union-Komponenten sowie als Namen für Funktionen und Sprungmarken (Labels).&lt;br /&gt;
&lt;br /&gt;
Bezeichner dürfen aus den Kleinbuchstaben &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;z&amp;lt;/tt&amp;gt;, den Großbuchstaben &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;Z&amp;lt;/tt&amp;gt;, dem Unterstrich&amp;amp;nbsp;&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt; und den Ziffern &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;9&amp;lt;/tt&amp;gt; aufgebaut werden, wobei an erster Stelle jedoch keine Ziffer stehen darf.&lt;br /&gt;
&lt;br /&gt;
Es wird zwischen Groß- und Kleinschreibung unterschieden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Ausdruck in C ist ein Konstrukt, das einen Wert hat. Ob dieser Wert eine ganze Zahl ist, eine Kommazahl oder ein Zeiger, etc. ist dabei egal. Die einfachsten Ausdrücke sind Konstanten wie&lt;br /&gt;
 2&lt;br /&gt;
oder Variablen wie&lt;br /&gt;
 ein_zahl&lt;br /&gt;
Mehrere Ausdrücke können durch [[#Liste der Operatoren|Operatoren]] zu komplexeren Ausdrücken kombiniert werden, etwa&lt;br /&gt;
 eine_zahl + andere_zahl == 2&lt;br /&gt;
oder &lt;br /&gt;
 eine_zahl = 2&lt;br /&gt;
Letzterer hat den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; und den Nebeneffekt, daß er diesen Wert an &amp;lt;tt&amp;gt;eine_zahl&amp;lt;/tt&amp;gt; zuweist.&lt;br /&gt;
&lt;br /&gt;
Auch der Aufruf einer Funktion, die einen Rückgabewert liefert, ist ein Ausdruck:&lt;br /&gt;
 sin (1.2)&lt;br /&gt;
und kann zum Aufbau komplexerer Ausdrüche verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bedingung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Bedingung ist ein Ausdruck, bei der nur interessiert, ob dieser zu&amp;amp;nbsp;0 (unwahr) auswertet oder zu ungleich&amp;amp;nbsp;0 (wahr). Solche Ausdrücke findet man in if-Anweisungen, in Schleifenbedingungen und bedingten Zuweisungen&lt;br /&gt;
 (ein_wert &amp;lt; 2) || (ein_wert &amp;gt; 40)&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Lvalue ist ein Ausdruck, dem etwas zugewiesen werden kann. Der Name ''Lvalue'' kommt aus dem Englischen. Das ''L'' steht abkürzend für left. Ein Lvalue ist damit ein Ausdruck, der auf der linken Seite eine Zuweisung in C stehen darf. Das &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; in den folgenden Beispiel-Ausdrücken muss ein Lvalue sein:&lt;br /&gt;
 x = y-1&lt;br /&gt;
&lt;br /&gt;
 x++&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Konstante&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Konstante ist ein Ausdruck, dessen Wert dem Compiler bekannt ist. Beispiele für Konstanten sind etwa&lt;br /&gt;
 7&lt;br /&gt;
 'B'&lt;br /&gt;
 -13.98e12&lt;br /&gt;
 1+(2*3)&lt;br /&gt;
und die Werte von [[#Enum|Enum]]s. &lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; aus dem folgenden Codestück definiert jedoch keine Konstante in diesem Sinne&lt;br /&gt;
 const double Pi = 3.14159256;&lt;br /&gt;
denn in einem anderen Quellmodul könnte durch die Deklaration&lt;br /&gt;
 extern const double Pi;&lt;br /&gt;
das Symbol &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; bekannt sein, ohne daß sein Wert bekannt ist!&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Adresse&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Adresse ist ein Ausdruck, der einen Speicherort (physikalisch oder virtuell) halten kann. Adressen erhält man dadurch, daß man einem Bezeichner den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt;voranstellt, Adressen durch Arithmetik berechnet oder Zahlen zu Adressen castet. Folgende Ausdrücke sind Adressen (eine sinnvolle Deklaration der auftretenden Variablen vorausgesetzt)&lt;br /&gt;
 &amp;amp; eine_zahl&lt;br /&gt;
 &amp;amp; ein_array[10]&lt;br /&gt;
 &amp;amp; ein_struct&lt;br /&gt;
 &amp;amp; ein_struct.komponente&lt;br /&gt;
 (int *) 0x1234&lt;br /&gt;
 (int *) eine_zahl&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Deklaration&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Anweisungen sind gewissermassen die Atome (oder Moleküle?), aus denen ein C-Programm besteht. Jedes C-Programm ist eine Abfolge von Deklarationen und Anweisungen. Einfache Anweisungen erhält man, in dem man einen Ausdruck nimmt und einen Strichpunkt dahinter schreibt:&lt;br /&gt;
 {{Ausdruck|}};&lt;br /&gt;
wie in&lt;br /&gt;
 x = x+1;&lt;br /&gt;
&lt;br /&gt;
Andere Anweisungen sind die unten aufgeführten Schleifen und die if- sowie die switch-Anweisung.&lt;br /&gt;
&lt;br /&gt;
Mehrere Deklarationen und Anweisungen können zu einem Block zusammengefasst werden. Dieser Block stellt dann wieder eine einzelne Anweisung dar und kann genau so gehandhabt werden!&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
In diesem Sinne ist auch z.B. die Syntax der if-Anweisung zu verstehen&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
besagt, daß der abhängig ausgeführte Code eine einzelne Anweisung sein darf oder eben ein kompletter Block oder die Verschachtelung mehrerer Blöcke etc.&lt;br /&gt;
&lt;br /&gt;
Eine Anweisung kann auch &amp;quot;leer&amp;quot; sein, also nichts tun. Diese Anweisungen sind der leere Block&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
und der Strichpunkt&lt;br /&gt;
 ;&lt;br /&gt;
die man gelegentlich in Schleifen findet:&lt;br /&gt;
 while (!timeout())&lt;br /&gt;
    {}&lt;br /&gt;
oder hinter Sprungmarken, die sonst direkt vor einer schliessenden Blockklammer stünden:&lt;br /&gt;
 {&lt;br /&gt;
    ...&lt;br /&gt;
    goto ein_label;&lt;br /&gt;
    ...&lt;br /&gt;
    {{Label|ein_label}}:;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Nicht jede Anweisung ist an jeder Stelle eines C-Programms erlaubt, so darf ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; nut innerhalb einer Schleife stehen. Gleiches gilt für &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;, das aber auch innerhalb eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; vorkommen darf.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Dies steht für einen Datentyp. Es kann ein elementarer Typ sein wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;, ein Zeiger darauf wie &amp;lt;tt&amp;gt;char*&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;void*&amp;lt;/tt&amp;gt;, und auch Qualifier enthalten wie das &amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt; im Typ &amp;lt;tt&amp;gt;unsigned long long&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Zu den Typen gehören auch zusammengesetzte Datentypen wie Strukturen und Unions, mit &amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt; selbst definierte Typen und natürlich Zeiger darauf, wie aus dem Abschnitt [[#Datentypen|Datentypen]]:&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person *&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;data32_t&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;&lt;br /&gt;
und Zeiger auf Funktionen.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Parameterliste&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
Die Parameterliste bei einer Funktionsdefinition gibt an, wieviel Übergabeparameter sie bekommt, wie diese heissen und welchen Typs diese sind. Der prinzipielle Aufbau ist&lt;br /&gt;
 {{Type}} {{Bezeichner}}, {{Type}} {{Bezeichner}}, ...&lt;br /&gt;
Falls die Funktion keine Parameter hat, dann ist die Parameterliste leer.&lt;br /&gt;
&lt;br /&gt;
Hier als Beispiel die zweiparametrige Funktion &amp;lt;tt&amp;gt;produkt&amp;lt;/tt&amp;gt;. Der erste Parameter heisst&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und ist ein &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;. Der zweite namens&amp;amp;nbsp;&amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; ist vom Typ &amp;quot;Zeiger auf double&amp;quot;, der Inhalt &amp;lt;tt&amp;gt;*b&amp;lt;/tt&amp;gt; ist also auch ein double.&lt;br /&gt;
&lt;br /&gt;
'''Definition der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b)&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
In älteren C-Quellen findet man noch eine andere Syntax für die Deklaration der Parameter, die aber heute praktisch nicht mehr verwendet wird:&lt;br /&gt;
'''alte Definition der Funktion:'''&lt;br /&gt;
 double produkt (a, b)&lt;br /&gt;
 double a, *b;&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Um die Funktion bekannt zu machen, werdendet man eine Deklaration bzw. den Prototypen, der dem Compiler nur mitteilt, welche Parameter die Funktion bekommt und was sie zurückliefert. Für den Aufruf der Funktion muss der Compiler nur diesen Prototyp kennen, ''was'' die Funktion im Endeffekt macht und wie sie implementiert wurde ist egal, sie wird als BlackBox angesehen.&lt;br /&gt;
&lt;br /&gt;
'''Prototyp der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b);&lt;br /&gt;
Hier dürfen die Bezeichner auch fehlen:&lt;br /&gt;
 double produkt (double, double*);&lt;br /&gt;
&lt;br /&gt;
==if==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==if-else==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==for==&lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Eine for-Schleife entspricht folgendem Konstrukt. Dabei sind die drei Ausdrücke optional. Fehlt die Bedingung, dann wird diese als &amp;quot;wahr&amp;quot; angenommen. Die beiden anderen Ausdrücke wird man als Ausdrücke mit Nebeneffekt wählen wie z.B. &amp;lt;tt&amp;gt;x=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;x=x-2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
 {&lt;br /&gt;
    {{Ausdruck|1}};&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_loop}}:&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
    else&lt;br /&gt;
       goto _break;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_continue}}:&lt;br /&gt;
    {{Ausdruck|2}};&lt;br /&gt;
    goto _loop;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_break}}:;&lt;br /&gt;
 }&lt;br /&gt;
Die Labels &amp;lt;tt&amp;gt;_break&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_continue&amp;lt;/tt&amp;gt; entsprechen den Sprungzielen einer &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Anweisung innerhalb von &amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==do-while==&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while  ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
==while==&lt;br /&gt;
 while  ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==switch==&lt;br /&gt;
 switch  ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    ...&lt;br /&gt;
  &lt;br /&gt;
    default:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#break-Anweisung|&amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Konstanten|&amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#continue-Anweisung|&amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#do-while-Schleife|&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Enum|&amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#for-Schleife|&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#goto-Anweisung|&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#return-Anweisung|&amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Liste der Operatoren|sizeof]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Strukturen|&amp;lt;tt&amp;gt;struct&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Eigene Datentypen|&amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Unions|&amp;lt;tt&amp;gt;union&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#while-Schleife|&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund2}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Arithmetische Operatoren&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Dies sind die &amp;quot;normalen&amp;quot; arithmetischen Operationen, wie man sie aus der Schule kennt. Man kann damit und allen anderen Operatoren auch komplexere Ausdrücke aufbauen. Die Prioritäten sind so, wie man sie kennt, also &amp;quot;Punktrechnung vor Strichrechnung&amp;quot;. Will man dies ändern, dann mit den runden Klammern:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;1+2*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 7&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(1+2)*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 9&amp;lt;br/&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}}&amp;amp;nbsp;+&amp;amp;nbsp;{{Ausdruck|}}&amp;lt;/tt&amp;gt; || Addition&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} - {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Subtraktion&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} * {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Multiplikation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} / {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Division&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} % {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Rest der Division (modulo)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;- {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Vorzeichenumkehr, Zweier-Komplement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Logische Operatoren und Vergleiche&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die logischen und die vergleichenden Operatoren liefern als Ergebnis den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (wahr) oder einen Wert ungleich&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (falsch, um genau zu sein den Wert &amp;lt;tt&amp;gt;!0&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Man kann das Ergebnis zwar einer Variablen zuweisen, in aller Regel wird man solche Ausdrücke jedoch in Bedingungen zu &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder in Abbruch-Bedingungen von Schleifen finden.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;&amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches AND: beides wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124;&amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches OR: mind. eines ist wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;! {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches NOT (0 &amp;amp;harr; ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} == {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} != {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist nicht gleich&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bitweise Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~ {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise NOT (Einser-Komplement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise AND&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise ODER&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} ^ {{Ausdruck|}}&amp;lt;/tt&amp;gt; ||bitweise XOR&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Shift-Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;lt;&amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Bits nach links schieben&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;gt;&amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Schieben nach rechts schieben&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Typen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Ein Cast in C kann dazu verwendet werden, den Typ eines Ausdruckes zu ändern oder den Ausdruck mit einer bestimmten Genauigkeit zu berechnen. Wird z.B. eine Berechnung standardmässig in 16 Bit ausgeführt, dann kann man mit einem Cast &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(long) &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
ausdrücken, daß die Berechnung in 32 Bit erfolgen soll. Des weiteren kann man Zeiger und ganze Zahlen und Gleitkommazahlen ineinander umwandeln.&lt;br /&gt;
&lt;br /&gt;
Casts können ''nicht'' dazu verwendet werden, um z.B. eine Zahl in einen String zu konvertieren, der diese Zahl darstellt! Dafür gibt es spezielle Funktionen wie &amp;lt;tt&amp;gt;itoa&amp;lt;/tt&amp;gt;!&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Type}}) {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Cast, Typwandlung&lt;br /&gt;
|-&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;| &amp;lt;tt&amp;gt;sizeof ({{Type}})&amp;lt;/tt&amp;gt; || Eine Konstante, deren Wert die Größe (in Bytes) des Typs ist. &amp;lt;tt&amp;gt;sizeof&amp;lt;/tt&amp;gt; ist auch auf Objekte anwendbar wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, Arrays bekannter Größe, Strukturen und Unions,  Array-, Struktur- und Union-Komponenten, Pointer, etc. Beispiel:&amp;lt;br/&amp;gt;&lt;br /&gt;
 int i, sum=0, array[] = { 1, -13, 4, 0, sizeof (int*) };&lt;br /&gt;
 &lt;br /&gt;
 for (i=0; i&amp;lt; sizeof (array) / sizeof (array[0]); i++)&lt;br /&gt;
    sum += array[i];&lt;br /&gt;
Alle Elemente des Arrays werden aufaddiert, ohne daß deren Anzahl explizit in der Schleife genannt ist.&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zeiger und Adressen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;* {{Adresse}}&amp;lt;/tt&amp;gt; || der Inhalt an Adresse&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp; {{Lvalue}}&amp;lt;/tt&amp;gt; || Adresse von&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Strukturen, Unions, Arrays&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Struct&amp;gt;}}.{{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Zeiger-auf-Struct&amp;gt;}} -&amp;gt; {{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union, deren Adresse man hat&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Adresse}}&amp;amp;#91;{{Ausdruck|}}&amp;amp;#93;&amp;lt;/tt&amp;gt; || Array-Element&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bedingte Auswertung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Bedingung}}) ? {{Ausdruck|}} : {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Auswahl des Wertes abhängig von der Bedingung&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zuweisung und Operatoren mit Nebeneffekt&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die Unterschiede der post- und pre-Varianten der Increment/Decrement kommen in Konstrukten wie &amp;lt;tt&amp;gt;x = *p++&amp;lt;/tt&amp;gt; zum tragen:&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *p++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; p = p+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *++p;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; p = p+1; x = *p;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = (*p)++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; *p = (*p)+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = ++(*p);&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; *p = (*p)+1; x = *p;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} = {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Zuweisung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++ {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-- {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Decrement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ++&amp;lt;/tt&amp;gt; || Post-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} --&amp;lt;/tt&amp;gt; || Post-Decrement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Kurzschreibweisen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Für ganz Faule gibt es anstatt&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a = a @ b&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
für viele Operatoren (hier dargestellt durch ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;@&amp;lt;/tt&amp;gt;) die abkürzende Schreibweise&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a @= b&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} += {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} -= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} *= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} /= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} %= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ^= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;lt;&amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;gt;&amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Autoren'''&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
* Kernighan und Ritchie - Buch&lt;br /&gt;
* Christian Wirth , C Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://wwwuser.gwdg.de/~kboehm/ebook/inhalt.html C-Programmieren unter Linux]&lt;br /&gt;
* [http://www.gdv.uni-hannover.de/documentation.php Skripte zum Selbststudium: C, C++, Java, etc]&lt;br /&gt;
* [http://info.baeumle.com/ansic.html Einführung in ANSI-C]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Quellcode C|!]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Inrfb2</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10396</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10396"/>
				<updated>2007-03-13T11:36:53Z</updated>
		
		<summary type="html">&lt;p&gt;Inrfb2: /* Reihenfolge der Auswertung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Programmiersprache C wurde 1971 als Gundlage für das Betriebssystem UNIX in den USA entwickelt (UNIX ist zu über 90% in C geschrieben). 1978 wurde von Brian Kernighan und Dennis Ritchie eine eindeutige Sprachdefinition entwickelt. Mittlerweile ist C von ANSI und ISO standardisiert.&lt;br /&gt;
&lt;br /&gt;
Heute sind C und ihr Nachfolger C++ die dominierenden Programmiersprachen. Sehr viele Anwendungen sind in C geschrieben, was inzwischen auch auf eingebettete Systeme zutrifft, die lange in Assembler programmiert werden mussten, da keine ausreichend leistungsfähigen Compiler zur Verfügung standen. &lt;br /&gt;
&lt;br /&gt;
Leider ist C nicht einfach zu lernen &amp;amp;ndash; es wurde weder von noch für Hobby-Programmierer entwickelt &amp;amp;ndash; und eignet sich daher nur bedingt für den Einsteiger. Mit etwas Übung und einem optimierenden Compiler kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
Vom Design her ist C eine Hardware-unabhängig Sprache. Das bedeutet, daß C-Programme mit vertretbarem Aufwand auf ein anderes System portiert werden können. Dazu benötigt man lediglich einen anderen Compiler, und Inline-Assembler-Anweisungen (Assembleranweisungen innerhalb eines C-Programmes) müssen der neuen Hardware (Prozessor) angepasst werden. &lt;br /&gt;
&lt;br /&gt;
==Geschichte==&lt;br /&gt;
;1971: C wird entwickelt&lt;br /&gt;
;1978: Kernighan und Ritchie definieren die Sprache.&lt;br /&gt;
;1983: ANSI und ISO standardisieren C.&lt;br /&gt;
;1992: Bjarne Stroustrup enwickelt die Nachfolgesprache C++.&lt;br /&gt;
&lt;br /&gt;
=Aufbau eines C-Programmes=&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
   C-Programme haben keinen fixen Aufbau wie z.B. Pascal. Es gibt zwar gewisse Regeln, aber sonst sind dem Programmierer alle Freiheiten überlassen. Der folgende &amp;quot;Beispiel-Aufbau&amp;quot; ist daher nicht zwingend und kann durchaus verändert werden.&lt;br /&gt;
&lt;br /&gt;
   Natürlich haben C-Programme einen fixen Aufbau! Ebenso wie Pascal-Programme auch unterliegen sie einer strikten Grammatik! &lt;br /&gt;
Auskommentiert --[[Benutzer:SprinterSB|SprinterSB]] 10:23, 17. Feb 2006 (CET)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Ein einfaches C-Programm könnte folgendermassen aussehen. Das Programm tut eigentlich nichts, aber das Beispiel zeigt den prinzipiellen Aufbau. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 int Zahl1;&lt;br /&gt;
 char Zeichen1;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int zahl2;&lt;br /&gt;
 &lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Beschreibung:'''&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndash; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
 {{comment|void-Definition von main ist nur beim Controller ueblich}}&lt;br /&gt;
 {{comment|spezielle Compilereinstellungen sind noetig, damit bei dieser Definition von main}}&lt;br /&gt;
 {{comment|kein Fehler/Warnung erzeugt wird.}}&lt;br /&gt;
 void main ()&lt;br /&gt;
 {&lt;br /&gt;
     ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
 int main (void)&lt;br /&gt;
 {  {{comment|der Block &amp;quot;main&amp;quot; beginnt}}&lt;br /&gt;
    int zahl;&lt;br /&gt;
    &lt;br /&gt;
    {   {{comment|ein Block beginnt}}&lt;br /&gt;
        {{comment|hier koennen Deklarationen und Anweisungen stehen}}&lt;br /&gt;
    }   {{comment|der Block endet}}&lt;br /&gt;
   &lt;br /&gt;
    return 0;&lt;br /&gt;
 }  {{comment|&amp;quot;main&amp;quot; endet}}&lt;br /&gt;
&lt;br /&gt;
=Datentypen=&lt;br /&gt;
==Elementare Datentypen==&lt;br /&gt;
Der Datentyp einer Variable gibt an, welche Werte eine Variable enthalten kann, welcher Art diese Daten sind und wie sie verarbeitet werden, etwa in arithmetischen Operationen wie einer Addition. So ist es zum Beispiel möglich, in eine Variable vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ganze Zahlen zwischen ca. -32000 und +32000 einzutragen. In einer char-Variable können ASCII-Zeichen gespeichert werden (alles, was Sie mit der Tastatur erzeugen können) oder ganze Zahlen von -128 bis 127.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da C plattformabhängig ist, hängt die Größe eines Datentypes zum Teil von der genutzten Hardware (z.B. 8, 16 oder 32 Bit-Controller) und dem Compiler und dessen Einstellungen ab!&lt;br /&gt;
&lt;br /&gt;
===int, char, short, long (ganze Zahlen)===&lt;br /&gt;
In Variable dieser Typen können Sie ganze Zahlen abspeichern, also z.B. 1, &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;2, 100, 12345. Jeden dieser Typen gibt es in zwei Ausprägungen: als &amp;quot;&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;quot;, also als vorzeichenbehafteten Typ, und als &amp;quot;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&amp;quot;, also ohne Vorzeichen, d.h. das Vorzeichen wird als 0 oder +1 genommen. &lt;br /&gt;
&lt;br /&gt;
Vorzeichenbehaftete Ganzzahl-Typen werden intern im &amp;lt;tt&amp;gt;n-1&amp;lt;/tt&amp;gt;-Komplement dargestellt, das Vorzeichen selbst findet sich also im höchstwertigen Bit. Werden zur Speicherung ''b'' Bits verwendet, dann reicht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;z.B. *zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==Enum==&lt;br /&gt;
&lt;br /&gt;
Über &amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt; können Aufzählungen definiert werden. Die Werte sind &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Werte und beginnen mit&amp;amp;nbsp;0. Der folgende enum hat einen um&amp;amp;nbsp;1 grösseren Wert. Mit einer Zuweisung können auch andere Werte zugeordnet werden. Klarer wird's im Beispiel:&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 enum Farben&lt;br /&gt;
 {&lt;br /&gt;
    ROT,&lt;br /&gt;
    GRUEN,&lt;br /&gt;
    BLAU,&lt;br /&gt;
    BRAUN = 5,&lt;br /&gt;
    SCHWARZ&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
Dies definiert die Konstanten &amp;lt;tt&amp;gt;ROT=0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;GRUEN=1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BLAU=2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BRAUN=5&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;SCHWARZ=6&amp;lt;/tt&amp;gt; und den Typ &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void foo (enum Farben farbe)&lt;br /&gt;
{&lt;br /&gt;
   switch (farbe)&lt;br /&gt;
   {&lt;br /&gt;
      case ROT:&lt;br /&gt;
         ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit kann man anstatt &amp;quot;magischer&amp;quot; Zahlen sprechende Namen im Code verwenden, etwa in Berechnungen und Zuweisungen, Vergleichen oder als Konstante hinter einem &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zusammengesetzte Datentypen==&lt;br /&gt;
===Arrays===&lt;br /&gt;
Oft muß man sehr viele Werte gleichzeitig abspeichern und betrachten, die alle der selben Aufgabe dienen. Man schreibt z.B. ein Programm, das 10 Zahlen einlesen und anschließend wieder ausgeben soll. Man könnte das natürlich mit 10 einzelnen Variablen bewerkstelligen, aber es ist sinnvoller, dabei Arrays &amp;amp;ndash; teilweise auch als ''Felder'' bezeichnet &amp;amp;ndash; zu verwenden.&lt;br /&gt;
&lt;br /&gt;
In einem Array werden mehrere Variablen gleichen Typs zusammengefasst und hintereinander im Speicher abgelegt. So kann man viele tausend Variablen anlegen mit nur einer Zeile Code. Doch es gibt noch größere Vorteile: Sie können das Array mit einer Schleife ganz einfach nach Werten durchsuchen. Stellen Sie sich vor, Sie müssten mit 100 verschiedenen Variablen &amp;lt;tt&amp;gt;Zahl_00&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;Zahl_99&amp;lt;/tt&amp;gt; arbeiten!&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}}&amp;amp;#91;{{Konstante}}&amp;amp;#93;;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 unsigned int werte[100];&lt;br /&gt;
&lt;br /&gt;
Der Name muß natürlich ein gültiger Bezeichner sein, als Datentyp kann jeder Typ genommen werden &amp;amp;ndash; sowohl elementare Datentypen als auch Zeiger, Strukturen, Unions oder selbst definierte Datentypen. In der eckigen Klammer wird die Anzahl der Elemente bekanntgegeben. Ein mit [3] definiertes Array hat Platz für drei Variablen. Da der Index immer bei 0 beginnt, greift man also mit &amp;lt;tt&amp;gt;[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;[1]&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;[2]&amp;lt;/tt&amp;gt; auf den jeweilige Inhalt zu. Um auf eine der im Array enthaltenen Variablen zugreifen zu können, müssen Sie den Variablennamen und in eckigen Klammern den Index (die &amp;quot;Nummer&amp;quot;) der Variablen angeben. Diese Variable verhält sich dann wie eine ganz normale Variable des jeweiligen Datentypes. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #define NZAHLEN 10&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int i;&lt;br /&gt;
    int zahlen[NZAHLEN];  {{comment|zahlen[0] ... zahlen[9]}}&lt;br /&gt;
  &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++)&lt;br /&gt;
    {&lt;br /&gt;
       printf (&amp;quot;Bitte Zahl %d eingeben: &amp;quot;, i);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; zahlen[i]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++) &lt;br /&gt;
       printf (&amp;quot;Zahl %d ist: %d\n&amp;quot;, i, zahlen[i]);&lt;br /&gt;
      &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 10 int-Variablen großes Array angelegt. &lt;br /&gt;
In dieses wird nun der Reihe nach 10 Zahlen eingelesen. &lt;br /&gt;
Anschließend werden alle 10 Zahlen ausgegeben. &lt;br /&gt;
&lt;br /&gt;
Dabei wird die Größe der Arrays und das Schleifenende über das Define &amp;quot;&amp;lt;tt&amp;gt;NZAHLEN&amp;lt;/tt&amp;gt;&amp;quot; angegeben. Dadurch muss nur ''eine Stelle'' im Code geändert werden, wenn die Größe des Arrays einmal einen anderer Wert als 10 haben soll &amp;amp;ndash; dies vermeidet Fehler die dadurch entstehen, wenn man beim Anpassen der Array-Größe eine Codestelle vergisst, zudem wird der Code lesbarer als wenn irgendwo die Zahl &amp;quot;10&amp;quot; auftaucht.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
:Wird ein ungültiger Index angeben (einer, der in der Deklaration nicht enthalten ist) können  undefinierte Dinge passieren, wenn dadurch andere Variableninhalte oder Programmcode überschrieben wird, der hinter oder vor dem Array im Speicher liegt. Schlimmstenfalls kann sogar der Computer/Controller abstürzen. Also darauf achten, daß keine ungültigen Werte als Index auftreten!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Strings (Zeichenketten)===&lt;br /&gt;
Ein String ist nichts anderes als ein Array, das aus einzelnen Zeichen (&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;) gebildet wird. Die Ausgabe auf dem Bildschirm funktioniert am einfachsten mittels Strings.&lt;br /&gt;
&lt;br /&gt;
Die Definition eines Strings erfolgt also genauso wie bei Arrays:&lt;br /&gt;
 char string[21];&lt;br /&gt;
&lt;br /&gt;
Nun haben Sie eine String, in dem Sie 21 Zeichen speichern können. Ganz richtig ist das jedoch nicht. C arbeitet mit &amp;quot;null-terminierten Strings&amp;quot;. Das beudeutet, dass die Länge des Strings nicht abgespeichert wird, sondern das Zeichen mit dem ASCII-Wert 0 das Stringende kennzeichnet. Daher auch die Bezeichnung  &amp;quot;null terminiert&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Das letzte Zeichen eines Strings muß daher immer das ASCII-Zeichen Nr. 0 sein. Ist es das nicht, hat der String kein definiertes Ende, und wenn Sie versuchen, ihn durch eine Standard-Funktion auszugeben zu lassen, könnte es eine Weile dauern, bis sich im Speicher zufällig irgendwo eine 0 befindet. Es stehen ihnen daher bei dem Beispiel nur 20 Zeichen zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
===Mehrdimensionale Arrays===&lt;br /&gt;
Manchmal benötigt man mehr als nur ein eindimensionales Array, wie Sie es bisher kennengelernt haben. Auch dies ist kein Problem. In der Deklaration geben Sie einfach mehrere eckige Klammern hintereinander an. Aber Vorsicht: der Speicherplatz ist begrenzt, ein &amp;quot;&amp;lt;tt&amp;gt;char feld[1024][1024]&amp;lt;/tt&amp;gt;&amp;quot; hat die Speicherplatzgrenzen vermutlich bereits weit überschritten, und der Compiler wird einen (bei gewissen Einstellung auch keinen) Fehler liefern.&lt;br /&gt;
Beim Zugriff auf mehrdimensionale Felder müssen auch mehrere Indizes angeben werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  int x,y;&lt;br /&gt;
  int feld[3][5];&lt;br /&gt;
 &lt;br /&gt;
  for (x=0; x&amp;lt;3; x++) &lt;br /&gt;
  {&lt;br /&gt;
     for (y=0; y&amp;lt;5; y++)&lt;br /&gt;
     {&lt;br /&gt;
       printf (&amp;quot;Feldwert x: %d,  y: %d &amp;quot;, x, y);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; feld[x][y]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  for(x=0; x&amp;lt;3; x++) &lt;br /&gt;
     for (y=0; y&amp;lt;5; y++) &lt;br /&gt;
        printf (&amp;quot;Wert: feld[%d][%d] = %d\n&amp;quot;, x, y, feld[x][y]);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 3 mal 5 &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array angelegt. &lt;br /&gt;
Dann werden die Werte eingegeben: zuerst &amp;lt;tt&amp;gt;feld[0][0]&amp;lt;/tt&amp;gt;, dann &amp;lt;tt&amp;gt;feld[0][1]&amp;lt;/tt&amp;gt;, usw. bis &amp;lt;tt&amp;gt;feld[2][4]&amp;lt;/tt&amp;gt;. &lt;br /&gt;
Zum Schluß werden alle Werte noch einmal ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===Strukturen===&lt;br /&gt;
In C können Sie sogenannte &amp;quot;Strukturen&amp;quot; definieren. Dabei handelt es sich um eine Zusammenfassung mehrerer Datentypen zu einem größeren. Im Unterschied zu Feldern können in Strukturen unterschiedliche Datentypen zusammengestellt und gespeichert werden: &lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 struct {{Bezeichner}}&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur 'Person'}}&lt;br /&gt;
 struct Person &lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;lt;tt&amp;gt;struct Person {&amp;lt;/tt&amp;gt;&amp;quot; leitet die Definition der Struktur mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;Person&amp;lt;/tt&amp;gt;&amp;quot; ein. &lt;br /&gt;
Dann werden in dieser Struktur fünf Komponenten definiert: drei Strings und zwei &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. &lt;br /&gt;
mit &amp;lt;tt&amp;gt;}&amp;lt;/tt&amp;gt; wird die Definition abgeschlossen. Sie haben damit einen Datentyp erstellt. Um eine Variable des Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach an&lt;br /&gt;
 struct Person {{Bezeichner}};&lt;br /&gt;
&lt;br /&gt;
Zum Zugriff auf eine Komponente der Struktur gibt man den Namen der Struktur-Variablen an (im folgenden Beispiel also &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;klaus&amp;lt;/tt&amp;gt;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
 {{comment|Definition zweier Struktur-Variablen}}&lt;br /&gt;
 struct Person hubert, klaus;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Zugriff auf Struktur-Komponenten}}&lt;br /&gt;
 hubert.alter = 32;&lt;br /&gt;
 klaus.alter = hubert.alter + 1;&lt;br /&gt;
&lt;br /&gt;
===Unions===&lt;br /&gt;
Eine Union wird ganz analog zu einer Struktur deklariert und verwendet. Sie unterscheidet sich von einer Struktur jedoch dadurch, daß ihre Elemente nicht nacheinander im Speicher abgelegt werden, sondern sich überlagern. Auf die in einer Union enthaltenen Daten gibt es also verschiedene Sichten: je nachdem, welche Sicht bzw. Interpretation der Daten man gerne hätte, wählt man den gewünschten Zugriff.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
union Daten &lt;br /&gt;
{&lt;br /&gt;
   int id;&lt;br /&gt;
&lt;br /&gt;
   struct Person u_person;&lt;br /&gt;
&lt;br /&gt;
   struct u_double&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      double wert;&lt;br /&gt;
   };&lt;br /&gt;
&lt;br /&gt;
   struct u_pointer&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      union Daten * p1;&lt;br /&gt;
      union Daten * p2;&lt;br /&gt;
   };&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
union Daten data;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies definiert eine Union mit den vier Zugriffsmöglichkeiten &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_double&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Größe der Union richtet sich dabei nach der grössten Komponente. In diesem Beispiel sind alle Komponenten so angelegt worden, daß sie an erster Stelle ein &amp;lt;tt&amp;gt;int id&amp;lt;/tt&amp;gt; enthalten. In &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; könnte man sich also merken, wie die Daten in der Union zu interpretieren sind. Würde &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; nicht dieses &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; enthalten, so würde sich &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; mit &amp;lt;tt&amp;gt;data.u_person.vname&amp;lt;/tt&amp;gt; überlagern. Ein Ändern der ersten Buchstaben von &amp;lt;tt&amp;gt;vname&amp;lt;/tt&amp;gt; hätte also ein Ändern von &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; zur Folge, und man könnte es nicht mehr als Merker verwenden. Mit diesem Feld überlagert das &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; die &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;-Felder der anderen Sichten, z.B. ist &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; der selbe Zugriff wie auf &amp;lt;tt&amp;gt;data.u_person.id&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein anderes Beispiel ist eine Union, die es ermöglicht, auf die einzelnen Bytes eines &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; zuzugreifen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef union&lt;br /&gt;
{&lt;br /&gt;
   unsigned long  as_long;&lt;br /&gt;
   unsignen short as_short[2];&lt;br /&gt;
   unsignen char  as_byte[4];&lt;br /&gt;
} data32_t;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies überlagert einen &amp;lt;tt&amp;gt;unsigned long&amp;lt;/tt&amp;gt; &amp;amp;ndash; also eine 32-Bit-Zahl &amp;amp;ndash; mit vier Bytes bzw. zwei Shorts.&lt;br /&gt;
 data32_t wert;&lt;br /&gt;
 &lt;br /&gt;
 wert.as_long = 0x12345678;&lt;br /&gt;
 wert.as_byte[0] = 0xab;&lt;br /&gt;
 {{comment|nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform)}}&lt;br /&gt;
&lt;br /&gt;
==Eigene Datentypen==&lt;br /&gt;
&lt;br /&gt;
=Variablen=&lt;br /&gt;
Eine Variable ist ein Synonym (=anderer Name) für eine Speicherstelle in einem Computer. Einfacher gesagt, eine Variable bietet Raum, um Daten wie Zahlen oder Zeichen zu speichern und wieder zu lesen.&lt;br /&gt;
&lt;br /&gt;
==Variablennamen==&lt;br /&gt;
Ein Variablenname kann zusammengesetzt werden aus den Buchstaben &amp;lt;tt&amp;gt;'''A'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''Z'''&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;'''a'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''z'''&amp;lt;/tt&amp;gt;, den Ziffern &amp;lt;tt&amp;gt;'''0'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''9'''&amp;lt;/tt&amp;gt;, sowie dem Sonderzeichen &amp;quot;Unterstrich&amp;quot; (underscore) &amp;lt;tt&amp;gt;'''_'''&amp;lt;/tt&amp;gt;. Dabei darf an erster Stelle keine Ziffer stehen. Die Bezeichner &amp;lt;tt&amp;gt;hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALLO&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALL0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;_123&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_HALLO&amp;lt;/tt&amp;gt; sind also alle gültige und unterschiedliche Variablennamen.&lt;br /&gt;
&lt;br /&gt;
==Anlegen von Variablen==&lt;br /&gt;
Um eine Variable verwenden zu können, muss sie zuerst vereinbart (&amp;quot;erzeugt&amp;quot;) werden. Dies wird auch als &amp;quot;''Definition der Variablen''&amp;quot; bezeichnet und geht so: Schreiben Sie zuerst den Datentyp, dann den Namen der Variablen. Zum Schluß kommt noch der Strichpunkt, wie nach jeder C-Anweisung oder Deklaration. Und nicht vergessen: C unterscheidet zwischen  Groß- und Kleinschreibung! &lt;br /&gt;
 int Zahl1, Zahl2;&lt;br /&gt;
 char Zeichen;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    float gleitZahl;&lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:'''&lt;br /&gt;
In einer Zeile können auch mehrere Variablen gleichen Types vereinbart werden, wenn man ein Komma dazwischen setzt. Variablen können in jedem Block vereinbart werden. Siehe [[#Gültigkeitsbereich|Gültigkeitsbereich]].&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen==&lt;br /&gt;
Man kann einer vereinbarten Variable Werte [[#Zuweisungen|zuweisen]]. Dazu schreibt man zuerst den Variablennamen, ein Gleichheitszeichen &amp;quot;&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;&amp;quot; und anschliessend den zuzuweisenden [[#Ausdrücke|Ausdruck]]. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, zahl2 = 12;&lt;br /&gt;
  char zeichen1 = 'A';&lt;br /&gt;
&lt;br /&gt;
  zahl1 = 52;&lt;br /&gt;
  zeichen1 = zeichen1 + 1; &lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Zuerst werden drei Variablen angelegt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;: wird gleich bei der Vereinbarung der Wert 12 zugewiesen. &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl1 = 52&amp;lt;/tt&amp;gt;: Hier wird der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; der Wert 52 zugewiesen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;: wird um 1 erhöht. Da in der Variablen &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; gespeichert ist, gibt sich ihr neuer Wert aus &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt;. Weil &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; dem Wert 65 entspricht, ist &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt; gleich 66, was dem Wert für &amp;lt;tt&amp;gt;'B'&amp;lt;/tt&amp;gt; entspricht.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei float==&lt;br /&gt;
Das funktioniert genau wie bei normale Zuweisungen. Nachkommastellen werden durch einen Punkt abgegrenzt: &lt;br /&gt;
 floatVariable = 3.14;&lt;br /&gt;
Zusätzlich kann eine Zehnerpotenz angegeben werden:&lt;br /&gt;
 floatVariable2 = -1.234E-6;&lt;br /&gt;
Dadurch wird der erst Wert mit 10&amp;lt;sup&amp;gt;&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;6&amp;lt;/sup&amp;gt; multipliziert, der Wert der Variablen ist also &lt;br /&gt;
:&amp;lt;math&amp;gt;-1{,}234\cdot10^{-6} = -0.000001234&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei logischen Variablen==&lt;br /&gt;
Wie bereits erwähnt, besitzt C keinen logischen Datentyp. Es müssen also &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; dafür genutzt werden. Die Zuweisung entpricht der Standard-Zuweisung. Wird der Wert 0 zugewiesen, dann ist die Variable &amp;quot;unwahr&amp;quot;, ansonsten ist sie &amp;quot;wahr&amp;quot;. &lt;br /&gt;
 intVariable = !0;   /* entspricht &amp;quot;wahr&amp;quot;   */&lt;br /&gt;
 intVariable = 0;    /* entspricht &amp;quot;unwahr&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
==Konstanten==&lt;br /&gt;
Konstanten können als Variable angesehen werden, die nicht beschrieben, sondern nur gelesen werden können. Ein typisches Beispiel dafür ist die Zahl &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; (rund 3,141592654). Niemand würde in der realen Welt versuchen, ihr einen anderen Wert zuzuweisen. Würde man &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; jedoch wie eine normale Variable anlegen, wäre dies ohne weiteres möglich. Um dies zu verhindern, gibt es das Schlüsselwort &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in C:&lt;br /&gt;
 const {{Type}} {{Bezeichner}} = {{Konstante}};  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Wichtig dabei ist, dass man Konstanten nur bei der Vereinbarung einen Wert zuweisen kann. &lt;br /&gt;
Da Konstanten gewöhnlich im gesamten Programm, zumindest einer Quelldatei genutzt werden, definiert man diese allerdings gewöhnlich außerhalb des main-Blockes entweder am Anfang eines Programmes, oder in einer sogenannten Header-Datei, die per &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; eingebunden wird.&lt;br /&gt;
 const float PI = 3.141592;  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Es sei jedoch erwähnt, daß auch einer Konstanten nachträglich ein anderer Wert zugewieden werden kann. Im obigen Beispiel könnte mit&lt;br /&gt;
 * ((float*) &amp;amp;PI) = 2;&lt;br /&gt;
der Wert von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; im Nachhinein verändert werden. Es wird die Adresse von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; genommen und diese Adresse durch den Cast in eine ganz normale &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;-Adresse umgewandelt, über welche der Wert geändert wird. Die sei der Vollständigkeit halber erwähnt.&lt;br /&gt;
&lt;br /&gt;
Je nachdem, an welcher Stelle sich das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; bei einer Pointer-Deklaration befindet, markiert es den Pointer als konstant oder das Objekt, auf das dieser Pointer zeigt. Eine häufige Parameterdeklaration in Ausgabe-Funktionen, die einen String erhalten, ist&lt;br /&gt;
 void foo (const char * str, ...);&lt;br /&gt;
Dadurch ist &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; der Zeiger auf eine Zeichenkette, die innerhalt der Funktion nicht verändert wird bzw. verändert werden darf. Eine Zuweisung wie &amp;lt;tt&amp;gt;*str = 'a'&amp;lt;/tt&amp;gt; ergibt also einen Fehler. &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; selbst kann aber sehr wohl verändert werden, etwa mit &amp;lt;tt&amp;gt;str++&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Soll ausgedrückt werden, daß &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; unveränderlich ist, dann so:&lt;br /&gt;
 void foo (char * const str, ...);&lt;br /&gt;
Jetzt wäre eine Änderung des Strings in Ordnung, etwa durch &amp;lt;tt&amp;gt;str[10] = 'a'&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Um sich zu merken, worauf das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; wirkt, trennt man die Deklaration in Gedanken beim&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf: Steht das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; links vom&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, dann gehört es zum &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, steht es rechts davon, dann gehört es zum Pointer. Natürlich ist es auch denkbar, beides &amp;amp;ndash; also den Zeiger und sein Ziel &amp;amp;ndash; als konstant zu markieren.&lt;br /&gt;
&lt;br /&gt;
==Gültigkeitsbereich==&lt;br /&gt;
In C können mehrere Variablen den gleichen Namen haben, solange eindeutig ist, welche in welchen Block gültig ist. Dabei gelten folgende Regeln: &lt;br /&gt;
&lt;br /&gt;
;Lokale Variablen: sind Variablen, die innerhalb eines Blockes definiert werden. Jede Variable ist nur in dem Block gültig, in dem sie vereinbart wurde, sowie in allen darin enthaltenen Blöcken; es sei denn, in einem Unter-Block wird eine Variable gleichen Namens definiert. Dann bezieht sich in diesem Unter-Block der Bezeichner auf die im Unter-Block angelegte Variable.&lt;br /&gt;
;Globale Variablen: werden ausserhalb jedes Blockes definiert und gelten ab der Stelle, an der sie deklariert werden, siehe auch [[#Deklaration und Definition|Deklaration und Definition]]. Wird jedoch in einem Block eine Variable gleichen Namens angelegt, gilt ab hier bis zum Ende des Blocks nicht mehr die globale Variable, sondern die im Block deklarierte. Das Spiel kann man weiterspielen: wird in einem Unter-Block wieder eine namensgleiche Variable angelegt, gilt diese in dem Unterblock.&lt;br /&gt;
&lt;br /&gt;
==Speicherklassen==&lt;br /&gt;
Jede Variable in C gehört zu einer bestimmten Speicherklasse&lt;br /&gt;
;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;: Lokale Variablen sind in aller Regal sogenannte ''automatische Variablen''. Das bedeutet, sie werden automatisch angelegt, wenn ein Block bzw. eine Funktion betreten wird und danach wieder entfernt. Das Schlüsselwort &amp;quot;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;&amp;quot; wird praktisch nie hingeschrieben, denn lokale Variablen ohne die ausdrückliche Angabe einer Speicherklasse, sind automatisch automatische Variablen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;: Eine externes Symbol ist im ganzen Programm bekannt bzw. in dem Block, in der die Deklaration steht. In unterschiedlichen Blöcken stehende Deklarationen beziehen sich auf das gleiche Symbol! Obgleich das Datum global zugreifbar ist, ist der Gültigkeitsbereich auf den deklarierenden Block begrenzt bzw. auf das deklarierende Quell-Modul, sofern das Symbol ausserhalb jedes Blocks des Moduls deklariert wird. Siehe auch [[#Deklaration und Definition|Deklaration und Definition]].&lt;br /&gt;
;&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;: Die Variable ist im Block gültig bzw. im Quell-Modul (also in der C-Datei, in der die angelegt wurde), wenn sie nicht innerhalb eines Blockes angelegt wurde. Statische Variablen werden nicht in Registern oder im Frame der Funktion angelegt, sondern im selben Speicherbereich, in dem auch die globalen Variablen liegen; Konstanten evtl. auch im Flash. Eine lokale Variable, die als &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; angelegt wird, &amp;quot;überlebt&amp;quot; also das Verlassen des Blocks und hat beim neuerlichen Betreten des Blockes ihren bisherigen Wert. In unterschiedlichen Blöcken angelegte lokale statische Variablen beziehen sich auf unterschiedliche Speicherstellen, genau wie bei lokalen Variablen auch.&lt;br /&gt;
;&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;: Durch diese Speicherklasse wird eine Variable &amp;amp;ndash; falls möglich &amp;amp;ndash; als Registervariable angelegt, also in einem Maschinenregister des Computer/Controllers gehalten. Dadurch kann auf solche Variablen besonders schnell zugegriffen werden. Dieses Schlüsselwort ist bei modernen Compilern weitgehend überflüssig, da die entsprechenden Optimierungen selbständig vorgenommen werden, wenn ausreichend Register vorhanden sind. Auch globale Variablen können als Register angelegt werden, davon ist dem Anfänger aber dringend abzuraten, weil leicht schwerauffindbare Fehler und Abstürze auftreten, wenn man nicht genau weiss, welche Implikationen in einer solchen Definition stecken!&lt;br /&gt;
;&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;: (FIXME: volatile ist ein Qualifier und keine Speicherklasse) Dies ist das genaue Gegenteil von &amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt; und bewirkt, dass die Variable auf keinen Fall in einem Register zwischengespeichert werden darf, sondern immer aus dem RAM gelesen und ins RAM geschrieben werden soll. &amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt; müssen alle ''globalen'' Variablen markiert werden, die in [[ISR | Interrupt-Handlern]] verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Ausdrücke=&lt;br /&gt;
Eine Variable oder eine Konstante in C stellen einfache Ausdrücke dar.&lt;br /&gt;
Diese elementaren Ausdrücke können durch Operatoren miteinander verknüpft werden und so zu neuen, komplexeren Ausdrücken zusammen gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Einfache Beispiele für Ausdrücke sind also z.B.:&lt;br /&gt;
 1&lt;br /&gt;
 a&lt;br /&gt;
 'a'&lt;br /&gt;
 1 + a&lt;br /&gt;
 a == 1&lt;br /&gt;
&lt;br /&gt;
Auch Funktionen können einen Wert zurückliefern und in Ausdrücken weiter benutzt werden.&lt;br /&gt;
In den folgenden Abschnitten wird gezeigt, welche Operatoren in C vorhanden sind,&lt;br /&gt;
und wei man damit neue Ausdrücke aufbauen kann.&lt;br /&gt;
&lt;br /&gt;
==Lvalues==&lt;br /&gt;
&lt;br /&gt;
Ein Lvalue in C ist ein Ausdruck, dem ein anderer Ausdruck zugewiesen werden kann, dessen Wert also durch eine Zuweisung verändert werden kann.&lt;br /&gt;
das 'L' leitet sich ab von 'left' bwz. 'links' und das 'value' bedeutet Wert: Ein Lvalue ist ein Ausdruck, der auf der linken Seite einer Zuweisung stehen darf. Ein Lvalue ist also immer auch ein gültiger Ausdruck, aber die Umkehrung gilt in alles Regel nicht.&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für einen Lvalue ist eine &amp;quot;normale&amp;quot; Variable, die nicht mit &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; als Konstante markiert ist:&lt;br /&gt;
 a = 1;&lt;br /&gt;
Hingegen ist der Ausdruck &amp;lt;tt&amp;gt;a+1&amp;lt;/tt&amp;gt; kein Lvalue, denn eine Zuweisung wie&lt;br /&gt;
 a+1 = 2;&lt;br /&gt;
die mathematisch durchaus sinnvoll ist, erzeugt einen Compilerfehler, der etwa lauten könnte &amp;quot;illegal lvalue in assignment&amp;quot;:&lt;br /&gt;
&amp;quot;ungültiger Wert in Zuweisung&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Andere Beipiele für Lvalues sind die Komponenten von (nicht-konstanten) [[#Strukturen|Strukturen]] und [[#Unions|Unions]], [[#Arrays|Array]]-Elemente und die Dereferenzierungen von Pointern: Die Konstante&amp;amp;nbsp;4 wird durch den Cast in eine Adresse umgewandelt. Über die Dereferenzierung&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; wird an die Adresse&amp;amp;nbsp;4 im Speicher eine&amp;amp;nbsp;3 geschrieben. Ob das erlaubt bzw. sinnvoll ist, ist abhängig von der jeweiligen Architektur.&lt;br /&gt;
 * ((unsigned int *) 4) = 3;&lt;br /&gt;
Hier ist der gesamte &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;-Ausdruck ein Lvalue&lt;br /&gt;
&lt;br /&gt;
==Logische (boolsche) Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp;amp;&amp;amp;amp; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr oder &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; || gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; || ungleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;= b&amp;lt;/tt&amp;gt; || kleiner oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt; b&amp;lt;/tt&amp;gt; || kleiner als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt;= b&amp;lt;/tt&amp;gt; || glösser oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt; b&amp;lt;/tt&amp;gt; || grösser als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; nicht wahr und vice versa&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine interessante Eigenschaft der Operatoren &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;amp;amp;&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; ist, dass&lt;br /&gt;
sie die Auswertung abbrechen, sobald das Ergebnis feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet. Ein oft anzutreffendes Codestück sieht so aus, dabei sei &amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
  if (p &amp;amp;&amp;amp; *p == 5)&lt;br /&gt;
  {&lt;br /&gt;
     {{comment|mach was}}&lt;br /&gt;
  }&lt;br /&gt;
Zuerst wird in der Bedinung geprüft, ob Zeiger&amp;amp;nbsp;&amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; einen Wert ungleich Null hat, also ob er überhaupt einen gültigen Wert enthält. Es ist weit verbreitete Konvention in C, daß Zeiger, die keinen gültigen Wert haben, die Adresse&amp;amp;nbsp;0 enthalten. '''Nur dann, wenn ein Zeiger nicht ein Null-Pointer ist, darf überhaupt ein Zugriff über ihn erfolgen!'''&lt;br /&gt;
&lt;br /&gt;
==Vergleich von Variablen==&lt;br /&gt;
Skalare Variablen (also ganze Zahlen, Gleitkommazahlen, Zeiger) können miteinander verglichen werden. Dazu gibt es die folgenden Operatoren in C: &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; || ist nicht gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;=&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;=&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das Ergebnis der Auswertung ist eine ganze Zahl. Ist die Bedingung erfüllt, dann ist der Wert ungleich&amp;amp;nbsp;0. Ist die Bedingung nicht erfüllt, dann ist ihr Wert gleich&amp;amp;nbsp;0.&lt;br /&gt;
Meistens wird man diese Operatoren in &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Konstrukten finden wie zum Beispiel&lt;br /&gt;
 if (x &amp;gt;= 10)&lt;br /&gt;
    x = 10;&lt;br /&gt;
oder in Abbruchbedingungen von Schleifen, wie sie weiter unten erklärt werden.&lt;br /&gt;
&lt;br /&gt;
Es ist auch möglich, das Ergebnis der Auswertung in einer &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Variablen zu speichern:&lt;br /&gt;
 int i;&lt;br /&gt;
 int z1, z2;&lt;br /&gt;
 &lt;br /&gt;
 z1 = 5;&lt;br /&gt;
 z2 = 100;&lt;br /&gt;
 i = z1 &amp;lt;= z2;  {{comment|Ein Vergleich. i wird &amp;quot;wahr&amp;quot;, da z1 kleinergleich z2 ist}}&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich&amp;amp;nbsp;0 (&amp;quot;wahr&amp;quot;), wenn &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; kleiner oder gleich &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt; ist. Ist &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; jedoch größer als &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt;, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich&amp;amp;nbsp;0 (&amp;quot;unwahr&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
==Arithmetische Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a + b&amp;lt;/tt&amp;gt; || Summe (Addition)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a - b&amp;lt;/tt&amp;gt; || Differenz (Subtraktion)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a * b&amp;lt;/tt&amp;gt; || Produkt (Multiplikation)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a / b&amp;lt;/tt&amp;gt; || Quotient (Division, evtl. mit Rest)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a % b&amp;lt;/tt&amp;gt; || Rest bei Division (Modulo)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;-a&amp;lt;/tt&amp;gt; || Vorzeichenumkehr (Zweierkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Bit-Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp; b&amp;lt;/tt&amp;gt; || bitweise und (and)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || bitweise oder (or)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a ^ b&amp;lt;/tt&amp;gt; || bitweise exclusiv-oder (xor, exor)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;~a&amp;lt;/tt&amp;gt; || jedes Bit in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; invertieren (not, Einerkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Index-Operator bei Arrays==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a[b]&amp;lt;/tt&amp;gt; || das (b+1)ste Element des Feldes a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Folgendes gilt es bei der Verwendung des Indexoperators zu beachten:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; muss ein [[C-Tutorial#Felder | Feld]] oder [[C-Tutorial#Zeiger | Zeiger]] sein&lt;br /&gt;
# &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; muss ein Integer sein oder ein Datentyp, der sich in einen int umwandeln läßt (z.B. char)&lt;br /&gt;
# Es wird nicht geprüft, ob der Index &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; im Feld &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gültig ist!&lt;br /&gt;
# Der erste Index eines Feldes ist immer 0. Daher ''(b+1)stes Element'' in der Beschreibung&lt;br /&gt;
&lt;br /&gt;
==Komponenten-Auswahl bei Structs und Unions==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a.b&amp;lt;/tt&amp;gt; || Element b der [[C-Tutorial#Strukturen | Struktur]] oder des Unions a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adress-Operator und Dereferenzierung==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&amp;amp;amp;a&amp;lt;/tt&amp;gt; || Speicheradresse der Variablen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;*a&amp;lt;/tt&amp;gt; || Wert, der an der Adresse &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a-&amp;amp;gt;b&amp;lt;/tt&amp;gt; || Wert des Elements &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; der Struktur, deren Adresse in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Adressoperator &amp;amp; kann auf Variablen angewendet werden und&lt;br /&gt;
gibt die Startadresse der Variablen im Speicher zurück.&lt;br /&gt;
&lt;br /&gt;
Handelt es sich bei einer Variable um einen [[C-Tutorial#Zeiger | Zeiger]], so enthält&lt;br /&gt;
sie eine Speicheradresse. Um an den '''Wert''' zu gelangen, der&lt;br /&gt;
an dieser Adresse steht, wird der Operator * vorangestellt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
&lt;br /&gt;
 {{comment|x ist eine Integervariable und hat den Wert 5}}&lt;br /&gt;
 int x = 5;&lt;br /&gt;
     &lt;br /&gt;
 {{comment|z ist ein Zeiger auf eine Integer-Variable und enthaelt somit}}&lt;br /&gt;
 {{comment|die Speicheradresse einer Integer-Variablen}}&lt;br /&gt;
 int *z;       &lt;br /&gt;
  &lt;br /&gt;
 {{comment|Verwendung des Adress-Operators: weist an z die Adresse von x zu}}&lt;br /&gt;
 z = &amp;amp;x;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Verwendung der Dereferenzierung}}&lt;br /&gt;
 {{comment|erhoehe den Wert, der bei Adresse z steht, um eins}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|da z auf x zeigt, hat x jetzt den Wert 6}}&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff auf Struktir- und Union-Elemente eine abkürzende Schreibweise möglich:&lt;br /&gt;
&lt;br /&gt;
Statt &lt;br /&gt;
  (*strukturZeiger).element&lt;br /&gt;
kann geschrieben werden&lt;br /&gt;
  strukturZeiger-&amp;gt;element&lt;br /&gt;
Beide Schreibweisen sind absolut gleichbedeutend, die Klammern bei der ersteren sind notwendig.&lt;br /&gt;
&lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
:Bei der Dereferenzierung durch &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; findet keine Prüfung statt, ob der Zeiger auch auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu einer Änderung '''irgendeiner''' Speicherstelle!&lt;br /&gt;
&lt;br /&gt;
 int *z; {{comment|z ist ein Zeiger auf einen int}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.}}&lt;br /&gt;
 {{comment|z enthaelt irgendeine ungueltige Adresse!!}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|&amp;quot;Erhoehe einen Integer _irgendwo_ im Speicher um 1&amp;quot; -&amp;gt; CRASH !!!}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
&lt;br /&gt;
==Cast-Operator==&lt;br /&gt;
&lt;br /&gt;
Der Cast Operator dient dazu, den Datentyp eines Wertes zu ändern. Dafür wird einfach der neue Datentyp in Klammern vor den Wert geschrieben.&lt;br /&gt;
&lt;br /&gt;
Um zum Beispiel aus einem Float ein Integer zu machen:&lt;br /&gt;
 var  = (int) 5.60;&lt;br /&gt;
Dabei wird der Wert aber auch gerundet, und es findet somit ein Informationsverlust statt.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Umwandeln einer ganzen Zahl in eine Adresse:&lt;br /&gt;
 int * addr;&lt;br /&gt;
 addr = (int*) 0x1234;&lt;br /&gt;
Damit ist &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; an Adresse 0x1234.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
Der Cast-Operator selbst führt ''keine Konvertierung'' von Darstellungen durch, etwa die Umwandlung der ganzen Zahl 123 ein den String &amp;lt;tt&amp;gt;&amp;quot;123&amp;quot;&amp;lt;/tt&amp;gt;, der diese Zahl darstellt! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
  int main(int argc, char ** argv)&lt;br /&gt;
  {&lt;br /&gt;
        char text[] = &amp;quot;5.6&amp;quot;;&lt;br /&gt;
        int zahl = (int) text;&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, zahl);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Anfangsadresse des Strings &amp;lt;tt&amp;gt;&amp;quot;5.6&amp;quot;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Komma-Operator==&lt;br /&gt;
Mit einem &amp;lt;tt&amp;gt;,&amp;lt;/tt&amp;gt; können mehrere Ausdrücke nacheinander ausgewertet werden.&lt;br /&gt;
Die Auswertung erfolgt von links nach rechts.&lt;br /&gt;
&lt;br /&gt;
Solche Konstrukte sieht man manchmal in Abfragen wie&lt;br /&gt;
 FILE  *file;&lt;br /&gt;
 if (file = fopen (&amp;quot;foo.exe&amp;quot;, &amp;quot;r&amp;quot;), file != NULL)&lt;br /&gt;
was erst an &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; einen Wert zuweist und den &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Block nur betritt,&lt;br /&gt;
wenn &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; nicht der Nullpointer ist.&lt;br /&gt;
&lt;br /&gt;
Bequem kann das auch in einer [[#for-Schleife|for-Schleife]] sein, wenn man zwei (oder mehr) Laufvariablen hat oder so:&lt;br /&gt;
 for (i=0, j=0; i &amp;lt; 10; i++, j += 2)&lt;br /&gt;
    &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Zuweisung===&lt;br /&gt;
=== ++ und -- ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; stellen einfachere Schreibweisen dar zum Addieren bzw. Subtrahieren von&amp;amp;nbsp;1.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; (Inkrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo++; &lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo + 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; 3}}&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; (Dekrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo--;&lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo - 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; -1}}&lt;br /&gt;
&lt;br /&gt;
Die beiden Operatoren können sowohl in der Präfix-Schreibweise (vor der Variablen) als auch als Postfix-Schreibweise (hinter der Variablen) notiert werden. &lt;br /&gt;
Der Unterschied liegt darin, dass beim Präfix der Wert zuerst neu berechnet wird und die Variable dann verwendet wird. Beim Postfix wird die Variable zuerst verwendet und erst nach Auswertung des Ausdrucks, in dem sie enthalten ist, neu berechnet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 int ausgabe1, ausgabe2, var1 = 10, var2 = 10;&lt;br /&gt;
 ausgabe1 = 3 * ++var1; {{comment|ausgabe1 &amp;amp;#61; 33; var1 &amp;amp;#61; 11;}}&lt;br /&gt;
 ausgabe2 = 3 * var2++; {{comment|ausgabe2 &amp;amp;#61; 30; var2 &amp;amp;#61; 11;}}&lt;br /&gt;
&lt;br /&gt;
Für Zeiger arbeiten diese Operatoren etwas anders, siehe dazu [[#Zeiger-Arithmetik|Zeiger-Arithmetik]].&lt;br /&gt;
&lt;br /&gt;
===Bedingter Ausdruck===&lt;br /&gt;
 ({{Bedingung}}) ? {{Ausdruck|1}} : {{Ausdruck|2}}&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; erfüllt ist, dann wertet dieser Ausdruck aus zu &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt;. Ist er nicht erfüllt, dann wertet er aus zu &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 x = (x &amp;gt;= 3) ? 0 : x+1;&lt;br /&gt;
Startet man &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; mit dem Wert 0, dann nimmt es bei mehrfacher Anwendung dieser Zeile (z.B. in einer Schleife) nacheinander die folgende Werte an:&lt;br /&gt;
:&amp;lt;tt&amp;gt;1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, ...&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&lt;br /&gt;
Wie auch in der Mathematik gibt es auch in C genaue Regeln über die Abarbeitungsreihenfolge (precedence)&lt;br /&gt;
der Operatoren. Dass sich alle C-Compiler genau an diesen ANSI-Vorschlag halten, ist leider nicht sicher.&lt;br /&gt;
Neben hat auch nicht jeder Programmierer diese Regel jederzeit im Kopf. &lt;br /&gt;
Daher ist es sinnvoll, Ausdrücke durch runde Klammern eindeutig zu kennzeichnen. &lt;br /&gt;
Nebenbei stören sich Compiler nicht an überflüssigen Klammerpaaren.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Priorität ||Operator||Assoziativität&lt;br /&gt;
|-&lt;br /&gt;
  &lt;br /&gt;
|&amp;lt;tt&amp;gt;15&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ( ) [ ] -&amp;gt; . &amp;lt;/tt&amp;gt;                      ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;14&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;! ~ ++ -- + - (TYP) * &amp;amp; sizeof &amp;lt;/tt&amp;gt;    ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;13&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; * / % (Rechenoperationen) &amp;lt;/tt&amp;gt;         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;12&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; + - (binär) &amp;lt;/tt&amp;gt;                       ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;11&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;&amp;lt; &amp;gt;&amp;gt; &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;10&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt; &amp;lt;= &amp;gt; &amp;gt;= &amp;lt;/tt&amp;gt;                         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 9&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; == != &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 8&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp; (bit-AND-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 7&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ^ (bit-XOR-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 6&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; (bit-OR-Operator)&amp;lt;/tt&amp;gt;   ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 5&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp;&amp;amp; &amp;lt;/tt&amp;gt;                                ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 4&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; &amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 3&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;? : &amp;lt;/tt&amp;gt;                               ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 2&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; = += -= /= *= %= &amp;gt;&amp;gt;= &amp;lt;&amp;lt;= &amp;amp;= &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;= ^= &amp;lt;/tt&amp;gt; ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 1&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; , (Sequenz-Operator) &amp;lt;/tt&amp;gt;              ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
&lt;br /&gt;
Peter Baeumle-Courth, ANSI-C im Überblick &amp;lt;p&amp;gt;&lt;br /&gt;
W. Alex, Einführung in C/C++&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
Eine Kontrollanweisung ist eine Anweisung, die Einfluss auf den Programmfluss hat. Normalerweise werden Anweisungen so ausgeführt, wie sie in der Quelldatei stehen: Von links nach rechts (falls mehrere Anweisungen in einer Zeile stehen sollten, wovon i.A. abzuraten ist) und von oben nach unten. Mit einer Kontrollanweisung kann dieser lineare Programmfluss durchbrochen werden: Die Codeausführung kann kann abhängig von einer Bedingung gemacht werden (&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;), kann wiederholt werden (Schleife) oder an einer anderen Stelle der Funktion fortgesetzt werden (&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==if-Anweisung==&lt;br /&gt;
Mit Hilfe des if-Befehls kann man Codeteile abhängig davon einer Bedingung ausführen lassen:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
oder mit else-Teil&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 if (x &amp;gt; 100)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;gt; 100 ist: Fehlerausgabe}}&lt;br /&gt;
    printf (&amp;quot;x = %d ist zu gross fuer die Berechnung!\n&amp;quot;, x);&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;lt;&amp;amp;#61; 100 ist: Berechne Summe der Zahlen 1...x}}&lt;br /&gt;
    {{comment|Die lokale Variable x2 lebt nur innerhalb dieses alse-Blocks}}&lt;br /&gt;
    int x2 = x;&lt;br /&gt;
 &lt;br /&gt;
    for (x = 0; x2 &amp;gt; 0; x2--)&lt;br /&gt;
       x += x2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Wenn die Bedingung wahr ist (&amp;lt;tt&amp;gt;x &amp;gt; 100&amp;lt;/tt&amp;gt;), dann wird eine Meldung ausgegeben; danach ist die if-Anweisung beendet. Der else-Block wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung nicht erfüllt (&amp;lt;tt&amp;gt;x &amp;amp;le; 100&amp;lt;/tt&amp;gt;), dann wird gleich zum else-Teil gesprungen, und nach dessen Ausführung der if-Befehl beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Ein häufiger Fehler ist es, statt &amp;lt;tt&amp;gt;if (a &amp;amp;#61;&amp;amp;#61; 23)&amp;lt;/tt&amp;gt; etwas wie &amp;lt;tt&amp;gt;if (a &amp;amp;#61; 23)&amp;lt;/tt&amp;gt; zu schreiben. &lt;br /&gt;
Dann wird allerdings nicht geprüft, ob die Variable&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gleich 23 ist, sondern der Variablen&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wird der Wert 23 zugewiesen. Der Ausdruck &amp;lt;tt&amp;gt;a &amp;amp;#61; 23&amp;lt;/tt&amp;gt; hat den Wert&amp;amp;nbsp;23 und ist damit immer &amp;quot;wahr&amp;quot;! Daher ist diese if-Bedingung immer erfüllt!&lt;br /&gt;
&lt;br /&gt;
Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken sondern bestenfalls eine Warnung. Damit ist dieser Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise &amp;lt;tt&amp;gt;if (23 &amp;amp;#61;&amp;amp;#61; a)&amp;lt;/tt&amp;gt;. Wenn man dort anstatt des Vergleichsoperators '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;amp;#61;&amp;lt;/tt&amp;gt;' den Zuweisungsoperator '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;lt;/tt&amp;gt;' verwendet, spuckt der Compiler sehr wohl einen Fehler aus! Ist die Zuweisung jedoch erwünscht und eine Compiler-Warnung lästig, dann wählt man eine Schreibweise wie &amp;lt;tt&amp;gt;if ((a &amp;amp;#61; b))&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;if (a &amp;amp;#61; b, a)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist zu schreiben &amp;lt;tt&amp;gt;if (Bedingung);&amp;lt;/tt&amp;gt; Richtig muss es heissen &amp;quot;&amp;lt;tt&amp;gt;if(Bedingung)&amp;lt;/tt&amp;gt;&amp;quot; Das Semikolon im ersten Fall ist eine leere Anweisung, die im if-Falle ausgeführt wird &amp;amp;ndash; sie bleibt also ohne Resultet. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt; ein auf das Semikolon folgende Anweisung die eigentlich zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören soll wird immer ausgeführt, die sie nicht mehr zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; dazu gehört.&lt;br /&gt;
}}&lt;br /&gt;
Bei verschachtelten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Konstrukten gehört ein &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zu letzten &amp;quot;freien&amp;quot; &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;. Soll in einer &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Folge das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zum ersten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören, dann ist das so zu hinzuschreiben:&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Ohne die geschweiften Klammern um das zweite &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehörte das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; dort hinzu.&lt;br /&gt;
&lt;br /&gt;
==switch-Anweisung==&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
&lt;br /&gt;
 switch ({{Ausdruck|}}) &lt;br /&gt;
 {&lt;br /&gt;
     case konstante1:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
    &lt;br /&gt;
     case konstante2:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 &lt;br /&gt;
     {{comment|weitere case-Marken}}&lt;br /&gt;
 &lt;br /&gt;
     default:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 } {{comment|Ende von switch}} &lt;br /&gt;
&lt;br /&gt;
Der Ausdruck muss ein skalarer Typ sein, er wird in die nächste ganze Zahl gewandelt und mit den Werten hinter den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Marken verglichen. Bei einer Übereinstimmung werden alle Befehle ab dem zutreffenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; ausgeführt. Stimmt der Ausdruck mit keinem der Werte überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt falls vorhanden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der nachfolgenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;- und des &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitts werden ausgeführt, wenn die Anweisungen des &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitts nicht mit dem Befehl &amp;lt;tt&amp;gt;break;&amp;lt;/tt&amp;gt; beendet werden!&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es dürfen beliebig viele &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitte angegeben werden, pro Vergleichswert jedoch nur einer.&lt;br /&gt;
Der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ist optional. Die Reihenfolge, in der &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt; angegeben werden, ist unerheblich.&lt;br /&gt;
&lt;br /&gt;
==Schleifen==&lt;br /&gt;
Um Anweisungen mehrmals hintereinander auszuführen, benötigt man Schleifen. Diese führen Anweisungen aus, bis oder solange Bedingungen erfüllt sind.&amp;lt;br&amp;gt; &lt;br /&gt;
Wichtig ist also, ob die Bedingung '''vor''' oder '''nach''' den Schleifen-Anweisungen geprüft wird. &lt;br /&gt;
&lt;br /&gt;
===while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 while ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Die while-Schleife wird solange durchlaufen, wie die Bedingung erfüllt ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Die Anweisung kann natürlich auch ein Block sein, der aus mehreren Deklarationen und Anweisungen besteht. &lt;br /&gt;
&lt;br /&gt;
 int zahl1 = 0;&lt;br /&gt;
 int zahl2 = 1;&lt;br /&gt;
 &lt;br /&gt;
 while (zahl1 &amp;lt; 3)&lt;br /&gt;
 {&lt;br /&gt;
    zahl1 = zahl1 + 1;&lt;br /&gt;
    zahl2 = zahl2 * 2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife drei mal durchlaufen. Zu Beginn des vierten Durchlaufs ist die Bedingung nicht mehr erfüllt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
&lt;br /&gt;
===do-while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
Die do-while-Schleife wird auf jeden Fall einmal durchlaufen und dann solange wiederholt, wie die Bedingung erfüllt ist.&lt;br /&gt;
 int i = 2;&lt;br /&gt;
 &lt;br /&gt;
 do &lt;br /&gt;
 {&lt;br /&gt;
     i = i*i;   {{comment|i quadrieren}}&lt;br /&gt;
     printf (&amp;quot;i = %d\n&amp;quot;, i);&lt;br /&gt;
 }&lt;br /&gt;
 while (i &amp;lt; 20);&lt;br /&gt;
&lt;br /&gt;
Die Schleife wird durchlaufen und wiederholt, solange &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; kleiner als 20 ist. Es werden also nacheinander die Werte 2, 4 und 16 ausgegeben. Nach der Schleife hat&amp;amp;nbsp;&amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; den Wert 256.&lt;br /&gt;
&lt;br /&gt;
===for-Schleife===&lt;br /&gt;
'''Syntax:''' &lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Bei den Ausdrücken wird es sich um einen Ausdrücke mit Nebeneffekt handeln wie etwa &amp;lt;tt&amp;gt;i=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;i=i+2&amp;lt;/tt&amp;gt;. Es werden folgende Aktionen ausgeführt:&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# falls die Bedingung wahr ist, dann führe &amp;lt;tt&amp;gt;Anweisung&amp;lt;/tt&amp;gt; aus.&lt;br /&gt;
# falls die Bedingung unwahr ist, dann sprinte zu 7 (Ende).&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# gehe zu 2&lt;br /&gt;
# nächste Anweisung nach der for-Schleife&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int lauf, summe;&lt;br /&gt;
 &lt;br /&gt;
 for (lauf=1, summe=0; lauf &amp;lt;= 10; lauf += 2) &lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel ist &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; ein [[#Komma-Operator|Komma-Ausdruck]], der zwei Anweisungen kombiniert und daher sogar zwei Nebeneffente hat: er setzt &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;1 und &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;0.&lt;br /&gt;
&lt;br /&gt;
Das Äquivalent als while-Schleife:&lt;br /&gt;
&lt;br /&gt;
 int lauf  = 1;                 {{comment|Anfangswerte}}&lt;br /&gt;
 int summe = 0;&lt;br /&gt;
 &lt;br /&gt;
 while (lauf &amp;lt;= 10)             {{comment|Bedingung}}&lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
    lauf  += 2;                 {{comment|Inkrement}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; in jedem Schleifendurchlauf um die Laufvariable &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; erhöht. Da &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nacheinander die ungeraden Werte von&amp;amp;nbsp;1 bis&amp;amp;nbsp;10 annimmt, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von&amp;amp;nbsp;1 bis kleinergleich 10 gespeichert, also der Wert&amp;amp;nbsp;25. &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; hat nach der Schleife den Wert&amp;amp;nbsp;11.&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf = 1&amp;lt;/tt&amp;gt; bedeutet, dass der Variablen &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; vor dem ersten Schleifendurchlauf der Wert&amp;amp;nbsp;1 zugewiesen wird. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf &amp;lt;= 10&amp;lt;/tt&amp;gt; ist die Schleifenbedingung; ist sie nicht erfüllt, wird die Schleife beendet. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf += 2&amp;lt;/tt&amp;gt; bedeutet, dass &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nach jedem Durchlauf um&amp;amp;nbsp;2 erhöht wird.&lt;br /&gt;
&lt;br /&gt;
===continue-Anweisung===&lt;br /&gt;
Innerhalb einer Schleife darf die &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die nachfolgenden Anweisungen übersprungen werden und mit dem nächsten Schleifendurchlauf fortgesetzt wird &amp;amp;ndash; vorausgesetzt die Schleifenbedingung ist noch erfüllt. Ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; etc. stehen, wenn dieses innerhalb einer Schleife steht.&lt;br /&gt;
&lt;br /&gt;
==break-Anweisung==&lt;br /&gt;
Innerhalb einer Schleife oder eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; darf die &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die Schleifen-/Switch-Anweisung sofort verlassen wird und das Programm dahinter weiter macht. Bei mehrfach geschachtelten Schleifen wird nur die innere verlassen. Ein &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; stehen, wenn dieses innerhalb einer Schleife/Switch-Anweisung steht.&lt;br /&gt;
&lt;br /&gt;
==goto-Anweisung==&lt;br /&gt;
&lt;br /&gt;
Innerhalb ein und derselben Funktion kann mit &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; an eine andere Stelle gesprungen werden. Dazu gibt man hinter dem &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einen Bezeichner an, der dadurch als Label fungiert:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 goto {{Bezeichner}};&lt;br /&gt;
Die Bezeichner selbst steht irgendwo in der Funktion und wird dadurch zur Sprungmarke (Label), daß er von einem Doppelpunkt (und mindestens einer C-Anweisung, die auch leer sein darf) gefolgt wird.&lt;br /&gt;
&lt;br /&gt;
Das Beispiel durchsucht das 2-dimensionale &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array &amp;lt;tt&amp;gt;feld&amp;lt;/tt&amp;gt; mit den &amp;lt;tt&amp;gt;SIZE_X &amp;amp;times; SIZE_Y&amp;lt;/tt&amp;gt; Werten nach dem Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;. Wird er gefunden, dann wird die 2-fach geschachtelte Suchschleife verlassen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int x, y;&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y; y++)&lt;br /&gt;
       if (feld[x][y] == 0)&lt;br /&gt;
          goto done;&lt;br /&gt;
 {{Label|done:}};&lt;br /&gt;
&lt;br /&gt;
Der folgende Code hat die gleiche Funktion, arbeitet jedoch ohne &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int x, y;&lt;br /&gt;
 int found = 0; {{comment|FALSE}}&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X &amp;amp;&amp;amp; !found; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y &amp;amp;&amp;amp; !found; y++)&lt;br /&gt;
       found = (0 == feld[x][y]);&lt;br /&gt;
Der Nachteil der &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-losen Variante ist, daß man eine Variable, die merkt, ob das Suchziel gefunden wurde, mitschleppen und in ''jedem'' Schleifendurchlauf abtesten muss. Dies bedeutet einen höheren Programmier- und Laufzeitaufwand und ist nicht so klar formuliert wie das &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-Beispiel.&lt;br /&gt;
&lt;br /&gt;
Gleichwohl sei angemerkt, daß die Verwendung von &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einem gewissen Dogmatismus unterliegt, der sich wie folgt subsummieren liesse:&lt;br /&gt;
:''goto ist böse und sollte keinesfalls verwendet werden! Wer es dennoch tut, offenbart dadurch seinen schlechten Geschmach sowie mangelhafte C-Kenntnis.'' &amp;lt;div align=&amp;quot;right&amp;quot;&amp;gt;http://www.roboternetz.de/phpBB2/images/smiles/icon_wink.gif&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Funktionen=&lt;br /&gt;
Stellen Dir vor, Du hast eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben &amp;amp;ndash; was Dich Zeit beim Erstellen des Programms und Speicherplatz im ausführbaren Programm kostet &amp;amp;ndash; kannst Du den Code-Abschnitt in eine Funktion schreiben und diese von jeder Stelle des Programms aus verwenden. Die Hauptgründe, um Funktionen zu verwenden, sind:&lt;br /&gt;
;Wiederverwendung von Code: Mehrfach verwendete Codestücke müssen nicht mehrfach implementiert werden. Oft unterscheiden sich die Codesequenzen nur in Kleinigkeiten, die man der Funktion über Parameter mitteilen kann.&lt;br /&gt;
;Übersichtlichkeit: Ein gut gegliedertes C-Programm implementiert klar umrissene Aufgaben in einer Funktion, auch wenn diese Funktion nur einmal im Code aufgerufen wird! Dadurch bleibt der Code um die Aufrufstelle besser verständlich, und man kann auf verschiedenen &amp;quot;Ebenen&amp;quot; denken. Eine Funktion wie &amp;quot;Datei öffnen&amp;quot; kann recht komplex sein. Auf höherer Ebene interessieren die Innereien nicht mehr, man möchte sich um andere Dinge kümmern und will den Code an der Stelle garnicht sehen...&lt;br /&gt;
;Rekursive Funktionen: Eine Funktion kann sich auch selbst aufrufen. In dem Falle nennt man die Funktion ''rekursiv''. Zwar lässt sich das, was eine rekursive Funktion tut, auch mit anderen Mitteln formulieren, die keine rekursiven Funktionen brauchen, aber oft ist der rekursive Weg knackiger und klarer formulierbar als eine nicht-rekursiven Ansatz, auch wenn es etwas mehr Resourcen verbraucht.&lt;br /&gt;
;Modulare Programmierung: Funktionen können anhand ihres Aufgabenbereichs auf verschiedene C-Quellen &amp;amp;ndash; sogenannte ''Module'' &amp;amp;ndash; verteilt werden. Funktionen, die etwas mit dem USB-Bus anstellen, werden in einem anderen Modul sein als mathematische Funktionen. Dies erhöht die Übersichtlichkeit und vereinfacht die Entwicklung im Team.&lt;br /&gt;
;Bibliotheken: Standard-Funktionen wie das hier oft auftauchende &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; sind in Bibliotheken gespeichert. Wenn das eigene Programm übersetzt wird, dann müssen nicht mehr alle Standard-Funktionen übersetzt werden, sondern werden nur noch aus der Bibliothek gelesen und ihr Code zum Programm dazugelinkt. Die Bibliotheks-Funktionen wurden schon zu einem früheren Zeitpunkt compiliert und liegen in dieser compilerten Form in der Bibliothek. Das spart mächtig Entwicklungszeit. Man kann auch selbst solche Bibliotheken erstellen und in diversen Projekten wiederverwenden.&lt;br /&gt;
;Generische Programmierung: In C ist es möglich, einer Funktion eine andere Funktion zu übergeben. (Damit ist nicht gemeint, ihr deren ''Rückgabewert'' zu übergeben (was auch ginge), sondern ''die Funktion selbst'' wird als Parameter übergeben und kann aufgerufen werden.) Ein typisches Beispiel dafür sind Sortieralgorithmen. Einem Sortieralgorithmus kann es egal sein, ''was'' er sortiert. Er muss lediglich wissen, ''wie'' er das Zeug zu sortieren hat: aufsteigend, absteigend, als Zahl, in lexikographischer Ordnung, nach der Quersumme, Körper nach Oberfläche, Durchmesser, Gewicht oder Volumen... Diese Vergleichsfunktion, die für zwei Objekte entscheidet, welches davon &amp;quot;kleiner&amp;quot; ist, kann man dem Sortierer übergeben. Will er zwei Werte vergleichen, dann muss er nur die Vergleichsfunktion aufrufen, ohne zu wissen, was diese tut. Damit kann der Sortieralgorithmus unanhängig von den Objekten gehalten werden, mit denen er hantieren soll.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Definition==&lt;br /&gt;
&lt;br /&gt;
In der ''Definition'' der Funktion wird gesagt, welche Werte sie liefern kann, wie sie heisst (Bezeichner) und wieviele und welche Parameter sie hat. Danach folgt ihre Implementierung:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}} ({{Parameterliste}})&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 &lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
Für Funktionen, die keinen Wert zurückliefern, gibt es den speziellen Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der besagt, daß die Funktion nichts zurückgibt. Die einfachste denkbare Funktion ist eine solch void-Funktion. Sie bekommt keine Parameter, gibt nicht zurück und ihr Body ist leer:&lt;br /&gt;
 void dummy()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==return-Anweisung==&lt;br /&gt;
An jeder Stelle des Programmflusses einer Funktion kann diese mit &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; beendet werden.&lt;br /&gt;
&lt;br /&gt;
'''bei void-Funktionen:'''&lt;br /&gt;
 return;&lt;br /&gt;
'''Funktionen mit Rückgabe-Wert:'''&lt;br /&gt;
 return {{Ausdruck|}};&lt;br /&gt;
Die zweite Variante gibt an, welcher Wert zurückgegeben wird.&lt;br /&gt;
 int main (int argc, char * argv[])&lt;br /&gt;
 {&lt;br /&gt;
    if (argc &amp;lt; 2)&lt;br /&gt;
       return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
Falls die letzte Anweisung einer void-Funktion ein &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; ist, kann es auch weggelassen werden wie oben bei der Funktion &amp;lt;tt&amp;gt;dummy&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Aufruf==&lt;br /&gt;
Um die Funktion aufzurufen gibt man ihren Namen an, gefolgt von den durch Komma getrennten Argumenten in runden Klammern wie im Beispiel unten das&lt;br /&gt;
 quadrat (5) &lt;br /&gt;
Da &amp;lt;tt&amp;gt;quadrat&amp;lt;/tt&amp;gt; einen Wert liefert, kann man damit weiter rechnen wie mit einem normalen Ausdruck:&lt;br /&gt;
 if (quadrat (a) + quadrat (b) == quadrat (c))&lt;br /&gt;
    c = quadrat (quadrat (a)); {{comment|c &amp;amp;#61; a hoch 4}}&lt;br /&gt;
&lt;br /&gt;
==Rekursive Funktionen==&lt;br /&gt;
Eine Funktion die sich selbst &amp;amp;ndash; möglicheweise auch über andere Zwischenfunktionen &amp;amp;ndash; wieder selbst aufruft, wird als ''rekursive Funktion'' bezeichnet. In der Definition ist nichts besonderes zu beachten. Ist die Verschachtelungstiefe im laufenden Programm zu tief, dann gibt das natürlich Probleme, aber das gilt bei tief verschachtelten 'normalen' Funktionen abenso...&lt;br /&gt;
&lt;br /&gt;
Das Beispiel berechnet den Größten Gemeinsamen Teiler zweier Zahlen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int ggT (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
     if (0 == a)&lt;br /&gt;
        return b;&lt;br /&gt;
 &lt;br /&gt;
    return ggT (b % a, a);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Ein komplettes kleines Programm:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int quadrat (int param1)&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  zahl = param1 * param1;&lt;br /&gt;
  return zahl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl, ergebnis;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Bitte Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = quadrat (zahl);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, zahl, ergebnis);&lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, 5, quadrat (5));&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur ausserhalb von Blöcken. Geschachtelte Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen beim Aufruf die Klammern angeben werden:&lt;br /&gt;
 dummy();&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Prototypen==&lt;br /&gt;
Wie oben erwähnt, kann ein Unterprogramm an jeder beliebigen Stelle im Programm stehen. Damit ist jedoch eine Bedingung verknüpft: Das Unterprogramm muß in der Datei oberhalb des ersten Aufrufes definiert worden sein. Wenn Sie ein Unterprogramm in Zeile 10 zum ersten mal aufrufen, müssen Sie die Deklaration davor erledigt haben. Verstanden?&lt;br /&gt;
Um dies zu erreichen, gibt es zwei Möglichkeiten: &lt;br /&gt;
&lt;br /&gt;
Entweder Sie schreiben alle Unterprogramme vor &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; in die Datei. Dies muß jedoch wiederum so geschehen, dass Funktionen zum Zeitpunkt ihres Aufrufes bereits bekannt sind! &lt;br /&gt;
Wo dies nicht möglich ist (z.B. sich gegenseitig aufrufende Unterprogramme), oder wenn Sie das stört, müssen Sie Prototypen verwenden. &lt;br /&gt;
Wie definiert man nun Prototypen? Sie kopieren einfach die erste Zeile des Unterprogrammes (z.B. &amp;quot;&amp;lt;tt&amp;gt;void ausgeben (int zahl)&amp;lt;/tt&amp;gt;&amp;quot;), fügen einen Strichpunkt&amp;amp;nbsp;&amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;an und fügen es an einer geeigneten Stelle ein (so, dass alle Aufrufe später in der Datei kommen). &lt;br /&gt;
Solche Definitionen stehen gewöhnlich am Anfang der Quelldatei oder in einer Header-Datei, die eingebunden wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl);  /* Der Prototyp */&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
   ausgeben (12);&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl)   /* Die eigentliche Prozedur */&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Ausgabe: %d\n&amp;quot;, zahl);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Parameterübergabe==&lt;br /&gt;
&lt;br /&gt;
Alle Werte, die an Prozeduren und Funktionen übergeben werden, werden grundsätzlich '''kopiert'''.&lt;br /&gt;
Das hat folgende Auswirkungen:&lt;br /&gt;
&lt;br /&gt;
# Änderungen an einem Parameter in einer Funktion erscheinen ''nicht'' beim Aufrufer!&lt;br /&gt;
# Möchte man, dass eine Funktion einen Wert trotzdem dauerhaft ändern soll, so muss die Adresse des Wertes via [[#Zeiger|Zeiger]] übergeben werden.&lt;br /&gt;
# Werden [[#Strukturen|Strukturen]] übergeben, so wird von ihnen eine Kopie erstellt, was bei großen Strukturen viel Zeit und Arbeitsspeicher kostet. Deshalb wird häufig nur die Adresse von Strukturen übergeben, da die Adresse viel schneller und platzsparender als die Struktur selbst kopiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele:'''&lt;br /&gt;
 void erhoehe (int x)&lt;br /&gt;
 {&lt;br /&gt;
    x = x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe(a);&lt;br /&gt;
    {{comment|a ist immer noch 0}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Beim Aufruf von &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; wird eine Kopie des Wertes von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; (im Beispiel also 0) erstellt und der Prozedur als Parameter &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; übergeben. Weil dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat dies keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|erhoehe den Wert an der Adresse x um eins}}&lt;br /&gt;
    *x = *x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe (&amp;amp;a);&lt;br /&gt;
    {{comment|a ist jetzt 1}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Jetzt wird im Hauptprogramm mittels [[#Adress-Operator und Dereferenzierung|Adress-Operator]] &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; die Speicheradresse von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; bestimmt. Dann wird eine ''Kopie der Adresse'' an das Unterprogramm &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; übergeben. Jetzt kennt das Unterprogramm die&lt;br /&gt;
Adresse des Originals &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und kann direkt mit dem Inhalts-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&lt;br /&gt;
'''Besonderheit bei Feldern'''&lt;br /&gt;
&lt;br /&gt;
Bei der Übergabe von [[#Felder|Feldern]] gibt es eine Besonderheit. Schreibt man nämlich den Namen eines Feldes, so ist das nichts anderes als die '''Speicheradresse des ersten Elements'''.&lt;br /&gt;
Bei der Übergabe eines Feldes wird also eine Kopie der Startadresse übergeben. Somit kann das Unterprogramm auf den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 void erhoehe (int x[])&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
   int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
   erhoehe (a);&lt;br /&gt;
   {{comment|a hat jetzt folgenden Inhalte: 11, 23, 35}}&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Dass die Übergabe einer Adresse erfolgt, sieht man an folgendem Beispiel, das von der Funktionsweise '''absolut identisch''' mit dem vorhergehenden ist:&lt;br /&gt;
&lt;br /&gt;
 {{comment|Bei Parametern gibt es keinen Unterschied zwischen Zeiger und Feld}}&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
    int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
    erhoehe (a);&lt;br /&gt;
 &lt;br /&gt;
    {{comment|a hat jetzt folgenden Inhalt: 11, 23, 35}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
Die Länge des Feldes wird nicht automatisch übergeben. Dafür ist ggf. ein zusätzlicher Parameter notwendig.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Variable Argumentanzahl==&lt;br /&gt;
== Funktionen indirekt aufrufen ==&lt;br /&gt;
Siehe [[#Zeiger auf Funktionen|Zeiger auf Funktionen]]&lt;br /&gt;
&lt;br /&gt;
=Zeiger II=&lt;br /&gt;
&lt;br /&gt;
Zeiger haben wir bereits weiter oben kennen gelernt. Zeiger sind ein zentrales Konzept in C und sollen hier etwas eingehender behandelt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger-Arithmetik==&lt;br /&gt;
In C kann man den Wert eines Zeigers verändern. Betrachten wir dazu die Funktion &amp;lt;tt&amp;gt;suche_0&amp;lt;/tt&amp;gt;, die einen Zeiger auf einen &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; erhält. Die Funktion soll ab der gegebenen Adresse nach dem ersten long-Wert suchen, der 0 ist, und dessen Adresse zurückgeben:&lt;br /&gt;
 long * suche_0 (long * addr)&lt;br /&gt;
 {&lt;br /&gt;
    while (*addr != 0)&lt;br /&gt;
       addr = addr + 1;&lt;br /&gt;
 &lt;br /&gt;
    return addr;&lt;br /&gt;
 }&lt;br /&gt;
In der Bedingung der while-Schleife wird der Inhalt an der Speicherstelle &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf 0 getestet. Ist der Wert 0, dann wird die Schleife beendet und die Adresse zurückgeliefert. Ist der Wert ungleich 0, dann wird &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf den nächste long gesetzt, &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; also um 4 Bytes weitergezählt. &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ist ja ein Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, und ein &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; ist 4 Bytes lang.&lt;br /&gt;
&lt;br /&gt;
Die Bedeutung von&lt;br /&gt;
 address + n&lt;br /&gt;
ist also, die Adresse um das &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;-fache der Größe des Typs, auf den &amp;lt;tt&amp;gt;address&amp;lt;/tt&amp;gt; zeigt, zu erhöhen. Dabei ist &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; eine ganze Zahl und darf auch negativ sein.&lt;br /&gt;
&lt;br /&gt;
Hier noch ein Beispiel einer Funktion, die nach einer Person mit einer bestimmten ID sucht (für die Definition von &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; siehe [[#Strukturen|Strukturen]]). Der Parameter &amp;lt;tt&amp;gt;person&amp;lt;/tt&amp;gt; ist dabei ein Array von Strukturen. Eine Person mit der gesuchten ID muss existieren, ansonsten hat die Suchfunktion kein definiertes Verhalten.&lt;br /&gt;
 {{comment|Sucht nach einer Person mit der ID person_id}}&lt;br /&gt;
 struct Person * &lt;br /&gt;
 suche_person_id (struct Person * person, int person_id)&lt;br /&gt;
 {&lt;br /&gt;
    while (person-&amp;gt;id != person_id)&lt;br /&gt;
       person++;&lt;br /&gt;
 &lt;br /&gt;
    return person;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:1em; padding:1em; border:solid 2px #FF0040;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- Vorlage:FarbigerRahmen funzt hier net --&amp;gt;&lt;br /&gt;
Beachte, daß es nicht sinnvoll ist, zwei Zeiger zu addieren oder zu multiplizieren. Ausserdem ist das &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt; der Zeiger-Arithmetik nicht kommutativ. Eine Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, der an Adresse 1 im Speicher zeigt, wird man schreiben als&lt;br /&gt;
 (long *) 1&lt;br /&gt;
Addiert man darauf eine ganze Zahl, dann haben die entstehenden Ausdrücke unterschiedliche Werte:&lt;br /&gt;
 (long *) 1 + 2    {{comment|zeigt zu Adresse 9}}&lt;br /&gt;
 (long *) 2 + 1    {{comment|zeigt zu Adresse 6}}&lt;br /&gt;
 (long *) (1 + 2)  {{comment|zeigt zu Adresse 3}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==void-Pointer==&lt;br /&gt;
Eine besondere Art von Zeiger ist der void-Pointer&lt;br /&gt;
 void * addr;&lt;br /&gt;
Ein void-Pointer ist ein &amp;quot;Zeiger auf irgendwas&amp;quot;, dementsprechend kann er nicht dereferenziert werden, Anwenden von &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf einen solchen Zeiger gibt also einen Fehler. Ausserdem ist es nicht möglich, mit einem void-Pointer Zeigerarithmetik zu machen, weil er nicht auf eine definierte Art von Objekt zeigt. Der Vorteil eines void-Pointers ist, daß er jede Art von Zeiger aufnehmen kann.&lt;br /&gt;
&lt;br /&gt;
Dazu betrachten wir die Funktion &amp;lt;tt&amp;gt;send_buf&amp;lt;/tt&amp;gt;, die eine Adresse erhält und ab dieser Adresse &amp;lt;tt&amp;gt;num&amp;lt;/tt&amp;gt; Bytes versenden soll. Wir könnten die Funktion so schreiben:&lt;br /&gt;
 void send_buf (unsigned char * buf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   ...&lt;br /&gt;
Das ist jedoch hässlich, wenn wir damit etwas anderes verschicken wollen als &amp;lt;tt&amp;gt; unsigned char&amp;lt;/tt&amp;gt;, etwa eine Struktur wie &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; (vom Typ &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;):&lt;br /&gt;
 send_buf ((unsigned char*) &amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
Ohne den Cast der Adresse von &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; zu einem Zeiger auf &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt; bekommt man eine Warnung oder gar einen Compilerfehler.&lt;br /&gt;
Dieses Zeiger gecaste ist mühsam und hässlich, es muss bei jedem Aufruf der Funktion explizit hingeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Besser ist es, den ersten Parameter der Funktion als void-Pointer zu definieren und den Cast in der Funktion zu machen:&lt;br /&gt;
 void send_buf (void * vbuf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   unsigned char *buf = (unsigned char*) vbuf;&lt;br /&gt;
   ...&lt;br /&gt;
Durch den Cast in der Funktion kann auf den Inhalt des Zeigers zugegriffen werden. Man muss nur festlegen, ''wie'' man zugreifen will, nämlich als &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Der Aufruf kann jetzt ohne Pointer-Cast erfolgen: &lt;br /&gt;
 send_buf (&amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
&lt;br /&gt;
==Null-Pointer==&lt;br /&gt;
==Zeiger als Parameter==&lt;br /&gt;
Wenn Sie ein Unterprogramm aufrufen, können Sie diesem Parameter übergeben, aber keine Werte zurückgekommen (außer den Funktionswert bei Funktionen). Dies hat einen guten Grund: beim Aufruf werden nicht die aufgerufenen Parameter benutzt, sondern es werden deren Werte in neue Variablen kopiert. Diese Variablen werden am Ende des Unterprogrammes &amp;quot;zerstört&amp;quot;, ohne ihre Werte an die aufrufenden Parameter zu übergeben. Jede Veränderung eines Parameters hat daher keine Auswirkung auf den Parameter.&lt;br /&gt;
&lt;br /&gt;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der C-Compiler legt dann immer noch Kopien an. In dieser Kopie steht aber kein Wert, sondern die Adresse einer Varaiblen. Und auf diese können Sie dann zugreifen. Denken Sie nur an &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; &amp;amp;ndash; da übergeben Sie ja auch die Adresse einer Variablen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void erhoehe (int *zeiger)&lt;br /&gt;
{&lt;br /&gt;
  *zeiger = 1 + *zeiger;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  erhoehe (&amp;amp;zahl);&lt;br /&gt;
  printf (&amp;quot;\nDie erhoehte Zahl lautet: %d\n&amp;quot;, zahl);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Zeiger auf Funktionen==&lt;br /&gt;
&lt;br /&gt;
Stell dir vor, du willst einen Sortieralgorithmus wie Bubble-Sort oder Quick-Sort oder wie sie alle heissen implementieren. Für den Sortieralgorithmus ist eigentlich egal, ''was'' er zu sortieren hat. Ihm ist es egal, ob er Zahlen aufwärts sortieren soll oder Strings in lexikographischer Reihenfolge, ob Objekte nach Größe oder Gewicht, Personen nach Alter oder Adressen nach Postleitzahl. Das einzige, was der Algorithmus wissen muss, ist ''wie'' er zwei Objekte zu vergleichen hat und wann eines davon &amp;quot;kleiner&amp;quot; (im Sinne der Ordnung, nach der sortiert werden soll) ist. &lt;br /&gt;
&lt;br /&gt;
Eine einfache Sortierfunktion, die nur zwei Zahlen sortiert, könnte man also so schreiben: &lt;br /&gt;
 {{comment|Sortiert ein Array von 2 int-Zeigern nach den Inhalten &lt;br /&gt;
  * an den Zeiger-Adressen}}&lt;br /&gt;
 void sort2_a (int * p[])&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Inhalte vergleichen...}}&lt;br /&gt;
    if (*p[0] &amp;gt; *p[1])&lt;br /&gt;
    {&lt;br /&gt;
       {{comment|... und ggf. Dreieckstausch der 2 Zeiger}}&lt;br /&gt;
       int * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Die Funktion bekommt ein Array der Länge&amp;amp;nbsp;2. In diesem Array stehen Zeiger auf die zu sortierenden Zahlen. Ein Array mit Zeigern zu verwenden und nicht ein Array von &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; scheint recht umständlich, und das ist es hier auch. Aber stell dir vor, du willst Strukturen wie &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; sortieren. Das Tauschen zweier Strukturen würde bedeuten, ihre kompletten Inhalte umzukopieren! Das wäre sehr aufwändig. Viel einfacher ist das Kopieren, wenn nur die Adressen zu kopieren sind.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; könnte dann so aussehen:&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void sortiere (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|p[] enthält 2 int-Zeiger: die Adressen von a und b}}&lt;br /&gt;
    int * p[2];&lt;br /&gt;
    p[0] = &amp;amp;a; &lt;br /&gt;
    p[1] = &amp;amp;b; &lt;br /&gt;
 &lt;br /&gt;
    {{comment|Sortiere die Zeiger}} &lt;br /&gt;
    sort2_a (p);&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Sortiert: %d, %d\n&amp;quot;, *p[0], *p[1]);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Für den nächsten Schritt überlegen wir uns, daß das Array in &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; ebensogut void-Pointer enthalten kann. Die einzige Stelle, an der wir auf die endgültigen int-Objekte zugreifen, ist der Vergleich. Diesen Vergleich lagern wir in die Funktion &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; aus:&lt;br /&gt;
 {{comment|Bekommt zwei void-Pointer und vergleicht die Inhalte.&lt;br /&gt;
  * Liefert 0 bei Gleichheit,&lt;br /&gt;
  * -1 wenn der erste Wert kleiner ist als der zweite und&lt;br /&gt;
  * 1  wenn der erste Wert größer ist als der zweite}}&lt;br /&gt;
 int compare_int (void * p0, void * p1)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Um über die Zeiger zugreifen zu können müssen wir diese&lt;br /&gt;
     * erst zu int-Zeigern casten}}&lt;br /&gt;
    int a0 = * (int*) p0;&lt;br /&gt;
    int a1 = * (int*) p1;&lt;br /&gt;
 &lt;br /&gt;
    if (a0 &amp;gt; a1)  return  1;&lt;br /&gt;
    if (a0 &amp;lt; a1)  return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void sort2_b (void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare_int (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Ein Aufruf von &amp;lt;tt&amp;gt;sort2_b&amp;lt;/tt&amp;gt; sieht dann genauso aus wie ein Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt definieren wir uns den neuen Datentyp &amp;lt;tt&amp;gt;comparator_t&amp;lt;/tt&amp;gt;. Dieser ist ein Zeiger auf eine Funktion, die zwei void-Pointer erhält und einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; zurückliefert, also analog arbeitet zu &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; von oben. &lt;br /&gt;
&lt;br /&gt;
Unsere Sortierfunktion bekommt nun neben dem zu sortierenden Zeiger-Array auch eine Vergleichsfunktion &amp;lt;tt&amp;gt;compare&amp;lt;/tt&amp;gt; mitgeliefert, die sie aufruft, wenn sie zwei Objekte vergleichen will&lt;br /&gt;
 {{comment|comparator_t sind Zeiger auf Funktionen, die 2 void-Pointer&lt;br /&gt;
  * erhalten und einen int zurückliefern}}&lt;br /&gt;
 typedef int (*comparator_t) (void*, void*);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Der Sortierer bekommt einen Funktionszeiger auf den Vergleicher.&lt;br /&gt;
  * Der Aufruf vom compare geht so als wäre es eine &amp;quot;normale&amp;quot; Funktion&lt;br /&gt;
  * (ist es im Endeffekt ja auch)}}&lt;br /&gt;
 void sort2_c (comparator_t compare, void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Bei einem Aufruf von &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; muss man dann einen Komparator mit angeben. In einem Beispiel analog zu &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; von oben ist das:&lt;br /&gt;
 sort2_c (compare_int, p);&lt;br /&gt;
Um zwei Strings lexikographisch zu sortieren nehmen wie die Standard-Funktion &amp;lt;tt&amp;gt;strcmp&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void foo()&lt;br /&gt;
 {&lt;br /&gt;
    char * worte[] = { &amp;quot;Wort1&amp;quot;, &amp;quot;Wort2&amp;quot; };&lt;br /&gt;
 &lt;br /&gt;
    sort2_c ((comparator_t) strcmp, (void**) worte);&lt;br /&gt;
 }&lt;br /&gt;
Die Casts sind hier erforderlich. Alternativ könnte man &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; mit reinen void-Pointern versorgen und diese dann dort umcasten.&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
&lt;br /&gt;
Die Syntax zur Definition/Deklaration von Funktionszeigern ist etwas verzwackt. Zur Verdeutlichung ein paar Beispiele. Dabei legt das linke &amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt; jeweils den Return-Typ fest.&lt;br /&gt;
 {{comment|definiert einen neuen Funktionszeiger-Typ}}&lt;br /&gt;
 typedef {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert einen Funktionszeiger}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert ein Array von Funktionszeigern (mit Initializer)}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}[]) ({{type}}, {{type}}, ...) = { wert1, wert2, ... };&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer}}&lt;br /&gt;
 ({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer und ruft die Funktion auf}}&lt;br /&gt;
 (({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}) (arg1, arg2, ...);&lt;br /&gt;
&lt;br /&gt;
=Standard-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==String-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===strcpy===&lt;br /&gt;
Bei vielen Compilern können sie einem String nicht direkt einen Wert (Text) zuweisen. Dazu müssen Sie dann die Prozedur strcpy() benutzen. Diese erwartet als ersten Parameter den Namen einer String-Variablen (ohne eckige Klammern) und als zweiten Parameter den eines (anderen) Strings. Letzterer kann auch ein in doppelten Hochkommas (&amp;quot;) eingeschlossener Text sein. Die Funktion fügt am Ende automatisch ein 0-Zeichen ein. Um diese Funktion nutzen zu können, müssen Sie die Datei string.h includieren! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri1[21], eingabe[21];&lt;br /&gt;
&lt;br /&gt;
  strcpy (stri1, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Der 1. String: %s\n&amp;quot;, stri1);&lt;br /&gt;
  printf (&amp;quot;Bitte geben Sie maximal 20 Zeichen ein: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%s&amp;quot;, eingabe);&lt;br /&gt;
  strcpy (stri1, eingabe);&lt;br /&gt;
  printf (&amp;quot;\n%s = %s&amp;quot;, stri1, eingabe);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis:''' &lt;br /&gt;
Da ein String, wie jedes Feld, eigentlich ein Zeiger ist, dürfen Sie kein &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; bei &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; angeben!&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
Es werden zwei gleich große Strings definiert: &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;eingabe&amp;lt;/tt&amp;gt;, mit je 20 &amp;quot;nutzbaren&amp;quot; Zeichen. &lt;br /&gt;
In &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; wird die Zeichenkette &amp;lt;tt&amp;gt;&amp;quot;hallo&amp;quot;&amp;lt;/tt&amp;gt; hineinkopiert. Das 0-Zeichen am Ende wird automatisch angefügt. &lt;br /&gt;
Der String wird ausgegeben. Als neues &amp;quot;Sonderzeichen&amp;quot; kommt &amp;lt;tt&amp;gt;%s&amp;lt;/tt&amp;gt; ins Spiel. Es hat die gleiche Aufgabe wie &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt;, nur für Strings. &lt;br /&gt;
Sie werden gebeten, eine String einzugeben. &lt;br /&gt;
Dieser String wird danach in die Variable &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; kopiert. &lt;br /&gt;
Beide Strings, die ja nun die gleiche Zeichenkette enthalten, werden ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===strlen===&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;strlen&amp;lt;/tt&amp;gt;, die als Parameter eine String-Variable erwartet, liefert die Länge diese Strings zurück. Sie werden jetzt vermutlich sagen: &amp;quot;Das ist doch klar, wie lang der String ist. Ich habe es ja bei der Deklaratin angegeben&amp;quot;. Das stimmt schon, aber denken Sie noch einmal an die null-terminierten Strings. Das 0-Zeichen steht am Ende des Strings (am Ende der gültigen Zeichenfolge), aber nicht unbedingt am Ende des reservierten Speicherplatzes. Haben Sie eine Variable &amp;quot;char Variable[21];&amp;quot;, und ihr den Wert &amp;quot;hallo&amp;quot; zugewiesen, dann steht das null-Zeichen in Variable[5]. Der &amp;quot;gültige&amp;quot; String ist also 5 Zeichen (0-4) lang. Und genau das (5) würde strlen zurück liefern. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri[21];&lt;br /&gt;
  &lt;br /&gt;
  strcpy (stri, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
  printf (&amp;quot;Der String ist %d Zeichen lang&amp;quot;, strlen (stri));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird vor allem gebraucht, wenn Sie direkt auf den String zugreifen, mittels &amp;lt;tt&amp;gt;stri[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;stri[1]&amp;lt;/tt&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
==Ein- und Ausgabe-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===Bildschirm-Ausgabe===&lt;br /&gt;
Bisher war das Tutorial trotz aller Beispiele reine Theorie. Sie konnten zwar Programme schreiben, aber die Funktion nicht testen. Hier lernen Sie nun, wie Sie etwas am Bildschirm ausgeben.&lt;br /&gt;
&lt;br /&gt;
Die dazu notwendige Funktione heisst &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (das '&amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt;' ist kein Fehler!). Diese Anweisung gibt die ihr übergebenen Parameter auf das Standard-Ausgabegerät aus, in der Regel also auf den Bildschirm. Sie kann beliebig viele Parameter übernehmen. Es müssen jedoch Standard-Datentypen (z.B. &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;...) sein! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
    int zahl1 = 12;&lt;br /&gt;
    char zeichen1 = 'A';&lt;br /&gt;
    &lt;br /&gt;
    printf (&amp;quot;Das ist Text, und er wird als solcher ausgegeben. \n&amp;quot;);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zahl1' ist: %d \n&amp;quot;, zahl1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %c \n&amp;quot;, zeichen1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %d \n&amp;quot;, zeichen1);&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt Text aus. Das Zeichen am Ende (&amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;) bedeutet &amp;quot;New Line&amp;quot;, es bewegt den Cursor an den Anfang der nächsten Zeile. &lt;br /&gt;
&lt;br /&gt;
Der zweite &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt auch Text aus, am Ende befindet sich wieder das &amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;, um einen Zeilenvorschub zu erreichen. Das &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; wird vom Compiler durch den ersten Parameter ersetzt, der nach dem Text angegeben wird. In diesem Fall wird &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; also durch den Wert der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ersetzt. Das &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; im &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; bedeutet &amp;quot;Dezimalzahl&amp;quot;, der Computer gibt also eine ganze Zahl aus. &lt;br /&gt;
&lt;br /&gt;
In der dritten Ausgabe wird ein Zeichen ausgegeben. Diesmal bedeutet &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; &amp;quot;char&amp;quot; (Zeichen). Es wird also &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; durch ein &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt; ersetzt, denn die Variable &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; wird als Character interpretiert. &lt;br /&gt;
&lt;br /&gt;
Die letzte Ausgabe interpretiert den Inhalt von &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; als Zahl, und gibt dager den ASCII-Wert von &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, also 65 aus. Das ist ein typisches Beispiel für das mögliche unterschiedliche Interpretieren einer  Variablen!&lt;br /&gt;
&lt;br /&gt;
===Tastatur-Eingabe===&lt;br /&gt;
&lt;br /&gt;
Um ein &amp;quot;gscheites&amp;quot; Programm schreiben zu können, muß man wissen, wie der Benutzer über die Tastatur Befehle eingeben kann. Die dafür notwendigen Funktionen stelle ich in diesem Kapitel vor.&lt;br /&gt;
Die wichtigste Funktion ist &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt;. Er liest Daten von der Tastatur. Die Syntax entspricht derer von &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int  zahl1;&lt;br /&gt;
char zeichen1;&lt;br /&gt;
&lt;br /&gt;
printf (&amp;quot;Bitte geben Sie eine Zahl ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl1);&lt;br /&gt;
printf (&amp;quot;Geben Sie einen Zeichen ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%c&amp;quot;, &amp;amp;zeichen1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Programm gibt eine Eingabeaufforderung aus. Dann erwartet es vom Benutzer, daß er eine Zahl eingibt, die mit [ENTER] bestätigt wird. Dieser Wert wird in &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; abgespeichert. Danach erfolgt wiederum eine Aufforderung zur Eingabe, diesmal eines einzelnen Zeichens. Dieses kann man nun eingeben und ebenfalls mit [ENTER] bestätigen.&lt;br /&gt;
&lt;br /&gt;
Macht man keine dem Datentyp der erwarteten Variable entsprechende Eingabe, dann bricht das Programm mit einer Fehlermeldung ab (wenn man z.B. &amp;quot;1_T2&amp;quot; eingibt, wenn eine Zahl erwartet wird)!&lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; vor den Parametern ist notwendig. Warum, das erfahren Sie im Kapitel &amp;quot;Unterprogramme&amp;quot;. Für die Profis eine Kurz-Erklärung: Das Unterprogramm &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; bekommt zwar einen Wert übergeben, kann aber keinen zurückliefern (&amp;quot;call by value&amp;quot;). Daher wird kein Wert, sondern ein Zeiger auf eine Variable übergeben. Mit dem &amp;amp; Zeichen bekommen Sie die Adresse einer Variablen (&amp;quot;call by reference&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=Parameter von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;=&lt;br /&gt;
Das Unterprogramm &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; kann, wie jede andere Funktion, Parameter besitzen. Doch keine selbst gewählten, sondern nur bestimmte. Doch warum braucht main Parameter? Denken Sie einmal an alle Betriebssystembefehle:&lt;br /&gt;
&amp;lt;tt&amp;gt;dir *.exe &amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;copy *.* a:&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;ls -la &amp;lt;/tt&amp;gt;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;&amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen!&lt;br /&gt;
&lt;br /&gt;
=Kurzreferenz=&lt;br /&gt;
==Syntax-Bausteine==&lt;br /&gt;
&lt;br /&gt;
Die Erklärung des Aufbaus von C-Befehlen erfolgt neben einfachen Beispielen auch durch ihren prinzipellen Aufbau. In diesen Syntax-Beschreibungen finden sich immer wieder die gleichen Bausteine, die hier näher erklärt werden sollen. Falls die solch ein Syntax-Baustein begegnet, kannst Du ihn anclicken und kommst dann zu seiner Erläuterung. &lt;br /&gt;
&lt;br /&gt;
In den Beispielen selbst gehören auch die spitzen Klammern zu dem Baustein (was daran zu erkennen ist, daß auch die Klammern eingefärbt sind). Die Klammern dürfen in einem konkreten C-Programm daher nicht eingetippt werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bezeichner&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Bezeichner in C dienen dazu, Variablen zu identifizieren und ihnen sprechende Namen zu geben, um die Quelle lesbarer zu machen. Man braucht Bezeichner auch, um selbstdefinierte Datentypen zu benennen und zum Benennen von Struct- und Union-Komponenten sowie als Namen für Funktionen und Sprungmarken (Labels).&lt;br /&gt;
&lt;br /&gt;
Bezeichner dürfen aus den Kleinbuchstaben &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;z&amp;lt;/tt&amp;gt;, den Großbuchstaben &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;Z&amp;lt;/tt&amp;gt;, dem Unterstrich&amp;amp;nbsp;&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt; und den Ziffern &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;9&amp;lt;/tt&amp;gt; aufgebaut werden, wobei an erster Stelle jedoch keine Ziffer stehen darf.&lt;br /&gt;
&lt;br /&gt;
Es wird zwischen Groß- und Kleinschreibung unterschieden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Ausdruck in C ist ein Konstrukt, das einen Wert hat. Ob dieser Wert eine ganze Zahl ist, eine Kommazahl oder ein Zeiger, etc. ist dabei egal. Die einfachsten Ausdrücke sind Konstanten wie&lt;br /&gt;
 2&lt;br /&gt;
oder Variablen wie&lt;br /&gt;
 ein_zahl&lt;br /&gt;
Mehrere Ausdrücke können durch [[#Liste der Operatoren|Operatoren]] zu komplexeren Ausdrücken kombiniert werden, etwa&lt;br /&gt;
 eine_zahl + andere_zahl == 2&lt;br /&gt;
oder &lt;br /&gt;
 eine_zahl = 2&lt;br /&gt;
Letzterer hat den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; und den Nebeneffekt, daß er diesen Wert an &amp;lt;tt&amp;gt;eine_zahl&amp;lt;/tt&amp;gt; zuweist.&lt;br /&gt;
&lt;br /&gt;
Auch der Aufruf einer Funktion, die einen Rückgabewert liefert, ist ein Ausdruck:&lt;br /&gt;
 sin (1.2)&lt;br /&gt;
und kann zum Aufbau komplexerer Ausdrüche verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bedingung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Bedingung ist ein Ausdruck, bei der nur interessiert, ob dieser zu&amp;amp;nbsp;0 (unwahr) auswertet oder zu ungleich&amp;amp;nbsp;0 (wahr). Solche Ausdrücke findet man in if-Anweisungen, in Schleifenbedingungen und bedingten Zuweisungen&lt;br /&gt;
 (ein_wert &amp;lt; 2) || (ein_wert &amp;gt; 40)&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Lvalue ist ein Ausdruck, dem etwas zugewiesen werden kann. Der Name ''Lvalue'' kommt aus dem Englischen. Das ''L'' steht abkürzend für left. Ein Lvalue ist damit ein Ausdruck, der auf der linken Seite eine Zuweisung in C stehen darf. Das &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; in den folgenden Beispiel-Ausdrücken muss ein Lvalue sein:&lt;br /&gt;
 x = y-1&lt;br /&gt;
&lt;br /&gt;
 x++&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Konstante&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Konstante ist ein Ausdruck, dessen Wert dem Compiler bekannt ist. Beispiele für Konstanten sind etwa&lt;br /&gt;
 7&lt;br /&gt;
 'B'&lt;br /&gt;
 -13.98e12&lt;br /&gt;
 1+(2*3)&lt;br /&gt;
und die Werte von [[#Enum|Enum]]s. &lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; aus dem folgenden Codestück definiert jedoch keine Konstante in diesem Sinne&lt;br /&gt;
 const double Pi = 3.14159256;&lt;br /&gt;
denn in einem anderen Quellmodul könnte durch die Deklaration&lt;br /&gt;
 extern const double Pi;&lt;br /&gt;
das Symbol &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; bekannt sein, ohne daß sein Wert bekannt ist!&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Adresse&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Adresse ist ein Ausdruck, der einen Speicherort (physikalisch oder virtuell) halten kann. Adressen erhält man dadurch, daß man einem Bezeichner den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt;voranstellt, Adressen durch Arithmetik berechnet oder Zahlen zu Adressen castet. Folgende Ausdrücke sind Adressen (eine sinnvolle Deklaration der auftretenden Variablen vorausgesetzt)&lt;br /&gt;
 &amp;amp; eine_zahl&lt;br /&gt;
 &amp;amp; ein_array[10]&lt;br /&gt;
 &amp;amp; ein_struct&lt;br /&gt;
 &amp;amp; ein_struct.komponente&lt;br /&gt;
 (int *) 0x1234&lt;br /&gt;
 (int *) eine_zahl&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Deklaration&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Anweisungen sind gewissermassen die Atome (oder Moleküle?), aus denen ein C-Programm besteht. Jedes C-Programm ist eine Abfolge von Deklarationen und Anweisungen. Einfache Anweisungen erhält man, in dem man einen Ausdruck nimmt und einen Strichpunkt dahinter schreibt:&lt;br /&gt;
 {{Ausdruck|}};&lt;br /&gt;
wie in&lt;br /&gt;
 x = x+1;&lt;br /&gt;
&lt;br /&gt;
Andere Anweisungen sind die unten aufgeführten Schleifen und die if- sowie die switch-Anweisung.&lt;br /&gt;
&lt;br /&gt;
Mehrere Deklarationen und Anweisungen können zu einem Block zusammengefasst werden. Dieser Block stellt dann wieder eine einzelne Anweisung dar und kann genau so gehandhabt werden!&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
In diesem Sinne ist auch z.B. die Syntax der if-Anweisung zu verstehen&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
besagt, daß der abhängig ausgeführte Code eine einzelne Anweisung sein darf oder eben ein kompletter Block oder die Verschachtelung mehrerer Blöcke etc.&lt;br /&gt;
&lt;br /&gt;
Eine Anweisung kann auch &amp;quot;leer&amp;quot; sein, also nichts tun. Diese Anweisungen sind der leere Block&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
und der Strichpunkt&lt;br /&gt;
 ;&lt;br /&gt;
die man gelegentlich in Schleifen findet:&lt;br /&gt;
 while (!timeout())&lt;br /&gt;
    {}&lt;br /&gt;
oder hinter Sprungmarken, die sonst direkt vor einer schliessenden Blockklammer stünden:&lt;br /&gt;
 {&lt;br /&gt;
    ...&lt;br /&gt;
    goto ein_label;&lt;br /&gt;
    ...&lt;br /&gt;
    {{Label|ein_label}}:;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Nicht jede Anweisung ist an jeder Stelle eines C-Programms erlaubt, so darf ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; nut innerhalb einer Schleife stehen. Gleiches gilt für &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;, das aber auch innerhalb eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; vorkommen darf.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Dies steht für einen Datentyp. Es kann ein elementarer Typ sein wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;, ein Zeiger darauf wie &amp;lt;tt&amp;gt;char*&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;void*&amp;lt;/tt&amp;gt;, und auch Qualifier enthalten wie das &amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt; im Typ &amp;lt;tt&amp;gt;unsigned long long&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Zu den Typen gehören auch zusammengesetzte Datentypen wie Strukturen und Unions, mit &amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt; selbst definierte Typen und natürlich Zeiger darauf, wie aus dem Abschnitt [[#Datentypen|Datentypen]]:&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person *&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;data32_t&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;&lt;br /&gt;
und Zeiger auf Funktionen.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Parameterliste&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
Die Parameterliste bei einer Funktionsdefinition gibt an, wieviel Übergabeparameter sie bekommt, wie diese heissen und welchen Typs diese sind. Der prinzipielle Aufbau ist&lt;br /&gt;
 {{Type}} {{Bezeichner}}, {{Type}} {{Bezeichner}}, ...&lt;br /&gt;
Falls die Funktion keine Parameter hat, dann ist die Parameterliste leer.&lt;br /&gt;
&lt;br /&gt;
Hier als Beispiel die zweiparametrige Funktion &amp;lt;tt&amp;gt;produkt&amp;lt;/tt&amp;gt;. Der erste Parameter heisst&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und ist ein &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;. Der zweite namens&amp;amp;nbsp;&amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; ist vom Typ &amp;quot;Zeiger auf double&amp;quot;, der Inhalt &amp;lt;tt&amp;gt;*b&amp;lt;/tt&amp;gt; ist also auch ein double.&lt;br /&gt;
&lt;br /&gt;
'''Definition der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b)&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
In älteren C-Quellen findet man noch eine andere Syntax für die Deklaration der Parameter, die aber heute praktisch nicht mehr verwendet wird:&lt;br /&gt;
'''alte Definition der Funktion:'''&lt;br /&gt;
 double produkt (a, b)&lt;br /&gt;
 double a, *b;&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Um die Funktion bekannt zu machen, werdendet man eine Deklaration bzw. den Prototypen, der dem Compiler nur mitteilt, welche Parameter die Funktion bekommt und was sie zurückliefert. Für den Aufruf der Funktion muss der Compiler nur diesen Prototyp kennen, ''was'' die Funktion im Endeffekt macht und wie sie implementiert wurde ist egal, sie wird als BlackBox angesehen.&lt;br /&gt;
&lt;br /&gt;
'''Prototyp der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b);&lt;br /&gt;
Hier dürfen die Bezeichner auch fehlen:&lt;br /&gt;
 double produkt (double, double*);&lt;br /&gt;
&lt;br /&gt;
==if==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==if-else==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==for==&lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Eine for-Schleife entspricht folgendem Konstrukt. Dabei sind die drei Ausdrücke optional. Fehlt die Bedingung, dann wird diese als &amp;quot;wahr&amp;quot; angenommen. Die beiden anderen Ausdrücke wird man als Ausdrücke mit Nebeneffekt wählen wie z.B. &amp;lt;tt&amp;gt;x=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;x=x-2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
 {&lt;br /&gt;
    {{Ausdruck|1}};&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_loop}}:&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
    else&lt;br /&gt;
       goto _break;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_continue}}:&lt;br /&gt;
    {{Ausdruck|2}};&lt;br /&gt;
    goto _loop;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_break}}:;&lt;br /&gt;
 }&lt;br /&gt;
Die Labels &amp;lt;tt&amp;gt;_break&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_continue&amp;lt;/tt&amp;gt; entsprechen den Sprungzielen einer &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Anweisung innerhalb von &amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==do-while==&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while  ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
==while==&lt;br /&gt;
 while  ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==switch==&lt;br /&gt;
 switch  ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    ...&lt;br /&gt;
  &lt;br /&gt;
    default:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#break-Anweisung|&amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Konstanten|&amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#continue-Anweisung|&amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#do-while-Schleife|&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Enum|&amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#for-Schleife|&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#goto-Anweisung|&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#return-Anweisung|&amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Liste der Operatoren|sizeof]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Strukturen|&amp;lt;tt&amp;gt;struct&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Eigene Datentypen|&amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Unions|&amp;lt;tt&amp;gt;union&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#while-Schleife|&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund2}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Arithmetische Operatoren&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Dies sind die &amp;quot;normalen&amp;quot; arithmetischen Operationen, wie man sie aus der Schule kennt. Man kann damit und allen anderen Operatoren auch komplexere Ausdrücke aufbauen. Die Prioritäten sind so, wie man sie kennt, also &amp;quot;Punktrechnung vor Strichrechnung&amp;quot;. Will man dies ändern, dann mit den runden Klammern:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;1+2*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 7&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(1+2)*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 9&amp;lt;br/&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}}&amp;amp;nbsp;+&amp;amp;nbsp;{{Ausdruck|}}&amp;lt;/tt&amp;gt; || Addition&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} - {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Subtraktion&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} * {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Multiplikation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} / {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Division&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} % {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Rest der Division (modulo)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;- {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Vorzeichenumkehr, Zweier-Komplement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Logische Operatoren und Vergleiche&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die logischen und die vergleichenden Operatoren liefern als Ergebnis den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (wahr) oder einen Wert ungleich&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (falsch, um genau zu sein den Wert &amp;lt;tt&amp;gt;!0&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Man kann das Ergebnis zwar einer Variablen zuweisen, in aller Regel wird man solche Ausdrücke jedoch in Bedingungen zu &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder in Abbruch-Bedingungen von Schleifen finden.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;&amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches AND: beides wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124;&amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches OR: mind. eines ist wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;! {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches NOT (0 &amp;amp;harr; ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} == {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} != {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist nicht gleich&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bitweise Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~ {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise NOT (Einser-Komplement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise AND&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise ODER&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} ^ {{Ausdruck|}}&amp;lt;/tt&amp;gt; ||bitweise XOR&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Shift-Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;lt;&amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Bits nach links schieben&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;gt;&amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Schieben nach rechts schieben&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Typen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Ein Cast in C kann dazu verwendet werden, den Typ eines Ausdruckes zu ändern oder den Ausdruck mit einer bestimmten Genauigkeit zu berechnen. Wird z.B. eine Berechnung standardmässig in 16 Bit ausgeführt, dann kann man mit einem Cast &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(long) &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
ausdrücken, daß die Berechnung in 32 Bit erfolgen soll. Des weiteren kann man Zeiger und ganze Zahlen und Gleitkommazahlen ineinander umwandeln.&lt;br /&gt;
&lt;br /&gt;
Casts können ''nicht'' dazu verwendet werden, um z.B. eine Zahl in einen String zu konvertieren, der diese Zahl darstellt! Dafür gibt es spezielle Funktionen wie &amp;lt;tt&amp;gt;itoa&amp;lt;/tt&amp;gt;!&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Type}}) {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Cast, Typwandlung&lt;br /&gt;
|-&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;| &amp;lt;tt&amp;gt;sizeof ({{Type}})&amp;lt;/tt&amp;gt; || Eine Konstante, deren Wert die Größe (in Bytes) des Typs ist. &amp;lt;tt&amp;gt;sizeof&amp;lt;/tt&amp;gt; ist auch auf Objekte anwendbar wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, Arrays bekannter Größe, Strukturen und Unions,  Array-, Struktur- und Union-Komponenten, Pointer, etc. Beispiel:&amp;lt;br/&amp;gt;&lt;br /&gt;
 int i, sum=0, array[] = { 1, -13, 4, 0, sizeof (int*) };&lt;br /&gt;
 &lt;br /&gt;
 for (i=0; i&amp;lt; sizeof (array) / sizeof (array[0]); i++)&lt;br /&gt;
    sum += array[i];&lt;br /&gt;
Alle Elemente des Arrays werden aufaddiert, ohne daß deren Anzahl explizit in der Schleife genannt ist.&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zeiger und Adressen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;* {{Adresse}}&amp;lt;/tt&amp;gt; || der Inhalt an Adresse&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp; {{Lvalue}}&amp;lt;/tt&amp;gt; || Adresse von&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Strukturen, Unions, Arrays&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Struct&amp;gt;}}.{{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Zeiger-auf-Struct&amp;gt;}} -&amp;gt; {{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union, deren Adresse man hat&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Adresse}}&amp;amp;#91;{{Ausdruck|}}&amp;amp;#93;&amp;lt;/tt&amp;gt; || Array-Element&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bedingte Auswertung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Bedingung}}) ? {{Ausdruck|}} : {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Auswahl des Wertes abhängig von der Bedingung&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zuweisung und Operatoren mit Nebeneffekt&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die Unterschiede der post- und pre-Varianten der Increment/Decrement kommen in Konstrukten wie &amp;lt;tt&amp;gt;x = *p++&amp;lt;/tt&amp;gt; zum tragen:&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *p++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; p = p+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *++p;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; p = p+1; x = *p;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = (*p)++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; *p = (*p)+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = ++(*p);&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; *p = (*p)+1; x = *p;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} = {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Zuweisung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++ {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-- {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Decrement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ++&amp;lt;/tt&amp;gt; || Post-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} --&amp;lt;/tt&amp;gt; || Post-Decrement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Kurzschreibweisen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Für ganz Faule gibt es anstatt&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a = a @ b&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
für viele Operatoren (hier dargestellt durch ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;@&amp;lt;/tt&amp;gt;) die abkürzende Schreibweise&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a @= b&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} += {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} -= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} *= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} /= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} %= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ^= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;lt;&amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;gt;&amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Autoren'''&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
* Kernighan und Ritchie - Buch&lt;br /&gt;
* Christian Wirth , C Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://wwwuser.gwdg.de/~kboehm/ebook/inhalt.html C-Programmieren unter Linux]&lt;br /&gt;
* [http://www.gdv.uni-hannover.de/documentation.php Skripte zum Selbststudium: C, C++, Java, etc]&lt;br /&gt;
* [http://info.baeumle.com/ansic.html Einführung in ANSI-C]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Quellcode C|!]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Inrfb2</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10395</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10395"/>
				<updated>2007-03-13T11:26:45Z</updated>
		
		<summary type="html">&lt;p&gt;Inrfb2: /* Reihenfolge der Auswertung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Programmiersprache C wurde 1971 als Gundlage für das Betriebssystem UNIX in den USA entwickelt (UNIX ist zu über 90% in C geschrieben). 1978 wurde von Brian Kernighan und Dennis Ritchie eine eindeutige Sprachdefinition entwickelt. Mittlerweile ist C von ANSI und ISO standardisiert.&lt;br /&gt;
&lt;br /&gt;
Heute sind C und ihr Nachfolger C++ die dominierenden Programmiersprachen. Sehr viele Anwendungen sind in C geschrieben, was inzwischen auch auf eingebettete Systeme zutrifft, die lange in Assembler programmiert werden mussten, da keine ausreichend leistungsfähigen Compiler zur Verfügung standen. &lt;br /&gt;
&lt;br /&gt;
Leider ist C nicht einfach zu lernen &amp;amp;ndash; es wurde weder von noch für Hobby-Programmierer entwickelt &amp;amp;ndash; und eignet sich daher nur bedingt für den Einsteiger. Mit etwas Übung und einem optimierenden Compiler kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
Vom Design her ist C eine Hardware-unabhängig Sprache. Das bedeutet, daß C-Programme mit vertretbarem Aufwand auf ein anderes System portiert werden können. Dazu benötigt man lediglich einen anderen Compiler, und Inline-Assembler-Anweisungen (Assembleranweisungen innerhalb eines C-Programmes) müssen der neuen Hardware (Prozessor) angepasst werden. &lt;br /&gt;
&lt;br /&gt;
==Geschichte==&lt;br /&gt;
;1971: C wird entwickelt&lt;br /&gt;
;1978: Kernighan und Ritchie definieren die Sprache.&lt;br /&gt;
;1983: ANSI und ISO standardisieren C.&lt;br /&gt;
;1992: Bjarne Stroustrup enwickelt die Nachfolgesprache C++.&lt;br /&gt;
&lt;br /&gt;
=Aufbau eines C-Programmes=&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
   C-Programme haben keinen fixen Aufbau wie z.B. Pascal. Es gibt zwar gewisse Regeln, aber sonst sind dem Programmierer alle Freiheiten überlassen. Der folgende &amp;quot;Beispiel-Aufbau&amp;quot; ist daher nicht zwingend und kann durchaus verändert werden.&lt;br /&gt;
&lt;br /&gt;
   Natürlich haben C-Programme einen fixen Aufbau! Ebenso wie Pascal-Programme auch unterliegen sie einer strikten Grammatik! &lt;br /&gt;
Auskommentiert --[[Benutzer:SprinterSB|SprinterSB]] 10:23, 17. Feb 2006 (CET)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Ein einfaches C-Programm könnte folgendermassen aussehen. Das Programm tut eigentlich nichts, aber das Beispiel zeigt den prinzipiellen Aufbau. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 int Zahl1;&lt;br /&gt;
 char Zeichen1;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int zahl2;&lt;br /&gt;
 &lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Beschreibung:'''&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndash; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
 {{comment|void-Definition von main ist nur beim Controller ueblich}}&lt;br /&gt;
 {{comment|spezielle Compilereinstellungen sind noetig, damit bei dieser Definition von main}}&lt;br /&gt;
 {{comment|kein Fehler/Warnung erzeugt wird.}}&lt;br /&gt;
 void main ()&lt;br /&gt;
 {&lt;br /&gt;
     ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
 int main (void)&lt;br /&gt;
 {  {{comment|der Block &amp;quot;main&amp;quot; beginnt}}&lt;br /&gt;
    int zahl;&lt;br /&gt;
    &lt;br /&gt;
    {   {{comment|ein Block beginnt}}&lt;br /&gt;
        {{comment|hier koennen Deklarationen und Anweisungen stehen}}&lt;br /&gt;
    }   {{comment|der Block endet}}&lt;br /&gt;
   &lt;br /&gt;
    return 0;&lt;br /&gt;
 }  {{comment|&amp;quot;main&amp;quot; endet}}&lt;br /&gt;
&lt;br /&gt;
=Datentypen=&lt;br /&gt;
==Elementare Datentypen==&lt;br /&gt;
Der Datentyp einer Variable gibt an, welche Werte eine Variable enthalten kann, welcher Art diese Daten sind und wie sie verarbeitet werden, etwa in arithmetischen Operationen wie einer Addition. So ist es zum Beispiel möglich, in eine Variable vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ganze Zahlen zwischen ca. -32000 und +32000 einzutragen. In einer char-Variable können ASCII-Zeichen gespeichert werden (alles, was Sie mit der Tastatur erzeugen können) oder ganze Zahlen von -128 bis 127.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da C plattformabhängig ist, hängt die Größe eines Datentypes zum Teil von der genutzten Hardware (z.B. 8, 16 oder 32 Bit-Controller) und dem Compiler und dessen Einstellungen ab!&lt;br /&gt;
&lt;br /&gt;
===int, char, short, long (ganze Zahlen)===&lt;br /&gt;
In Variable dieser Typen können Sie ganze Zahlen abspeichern, also z.B. 1, &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;2, 100, 12345. Jeden dieser Typen gibt es in zwei Ausprägungen: als &amp;quot;&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;quot;, also als vorzeichenbehafteten Typ, und als &amp;quot;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&amp;quot;, also ohne Vorzeichen, d.h. das Vorzeichen wird als 0 oder +1 genommen. &lt;br /&gt;
&lt;br /&gt;
Vorzeichenbehaftete Ganzzahl-Typen werden intern im &amp;lt;tt&amp;gt;n-1&amp;lt;/tt&amp;gt;-Komplement dargestellt, das Vorzeichen selbst findet sich also im höchstwertigen Bit. Werden zur Speicherung ''b'' Bits verwendet, dann reicht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;z.B. *zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==Enum==&lt;br /&gt;
&lt;br /&gt;
Über &amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt; können Aufzählungen definiert werden. Die Werte sind &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Werte und beginnen mit&amp;amp;nbsp;0. Der folgende enum hat einen um&amp;amp;nbsp;1 grösseren Wert. Mit einer Zuweisung können auch andere Werte zugeordnet werden. Klarer wird's im Beispiel:&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 enum Farben&lt;br /&gt;
 {&lt;br /&gt;
    ROT,&lt;br /&gt;
    GRUEN,&lt;br /&gt;
    BLAU,&lt;br /&gt;
    BRAUN = 5,&lt;br /&gt;
    SCHWARZ&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
Dies definiert die Konstanten &amp;lt;tt&amp;gt;ROT=0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;GRUEN=1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BLAU=2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BRAUN=5&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;SCHWARZ=6&amp;lt;/tt&amp;gt; und den Typ &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void foo (enum Farben farbe)&lt;br /&gt;
{&lt;br /&gt;
   switch (farbe)&lt;br /&gt;
   {&lt;br /&gt;
      case ROT:&lt;br /&gt;
         ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit kann man anstatt &amp;quot;magischer&amp;quot; Zahlen sprechende Namen im Code verwenden, etwa in Berechnungen und Zuweisungen, Vergleichen oder als Konstante hinter einem &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zusammengesetzte Datentypen==&lt;br /&gt;
===Arrays===&lt;br /&gt;
Oft muß man sehr viele Werte gleichzeitig abspeichern und betrachten, die alle der selben Aufgabe dienen. Man schreibt z.B. ein Programm, das 10 Zahlen einlesen und anschließend wieder ausgeben soll. Man könnte das natürlich mit 10 einzelnen Variablen bewerkstelligen, aber es ist sinnvoller, dabei Arrays &amp;amp;ndash; teilweise auch als ''Felder'' bezeichnet &amp;amp;ndash; zu verwenden.&lt;br /&gt;
&lt;br /&gt;
In einem Array werden mehrere Variablen gleichen Typs zusammengefasst und hintereinander im Speicher abgelegt. So kann man viele tausend Variablen anlegen mit nur einer Zeile Code. Doch es gibt noch größere Vorteile: Sie können das Array mit einer Schleife ganz einfach nach Werten durchsuchen. Stellen Sie sich vor, Sie müssten mit 100 verschiedenen Variablen &amp;lt;tt&amp;gt;Zahl_00&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;Zahl_99&amp;lt;/tt&amp;gt; arbeiten!&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}}&amp;amp;#91;{{Konstante}}&amp;amp;#93;;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 unsigned int werte[100];&lt;br /&gt;
&lt;br /&gt;
Der Name muß natürlich ein gültiger Bezeichner sein, als Datentyp kann jeder Typ genommen werden &amp;amp;ndash; sowohl elementare Datentypen als auch Zeiger, Strukturen, Unions oder selbst definierte Datentypen. In der eckigen Klammer wird die Anzahl der Elemente bekanntgegeben. Ein mit [3] definiertes Array hat Platz für drei Variablen. Da der Index immer bei 0 beginnt, greift man also mit &amp;lt;tt&amp;gt;[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;[1]&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;[2]&amp;lt;/tt&amp;gt; auf den jeweilige Inhalt zu. Um auf eine der im Array enthaltenen Variablen zugreifen zu können, müssen Sie den Variablennamen und in eckigen Klammern den Index (die &amp;quot;Nummer&amp;quot;) der Variablen angeben. Diese Variable verhält sich dann wie eine ganz normale Variable des jeweiligen Datentypes. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #define NZAHLEN 10&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int i;&lt;br /&gt;
    int zahlen[NZAHLEN];  {{comment|zahlen[0] ... zahlen[9]}}&lt;br /&gt;
  &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++)&lt;br /&gt;
    {&lt;br /&gt;
       printf (&amp;quot;Bitte Zahl %d eingeben: &amp;quot;, i);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; zahlen[i]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++) &lt;br /&gt;
       printf (&amp;quot;Zahl %d ist: %d\n&amp;quot;, i, zahlen[i]);&lt;br /&gt;
      &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 10 int-Variablen großes Array angelegt. &lt;br /&gt;
In dieses wird nun der Reihe nach 10 Zahlen eingelesen. &lt;br /&gt;
Anschließend werden alle 10 Zahlen ausgegeben. &lt;br /&gt;
&lt;br /&gt;
Dabei wird die Größe der Arrays und das Schleifenende über das Define &amp;quot;&amp;lt;tt&amp;gt;NZAHLEN&amp;lt;/tt&amp;gt;&amp;quot; angegeben. Dadurch muss nur ''eine Stelle'' im Code geändert werden, wenn die Größe des Arrays einmal einen anderer Wert als 10 haben soll &amp;amp;ndash; dies vermeidet Fehler die dadurch entstehen, wenn man beim Anpassen der Array-Größe eine Codestelle vergisst, zudem wird der Code lesbarer als wenn irgendwo die Zahl &amp;quot;10&amp;quot; auftaucht.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
:Wird ein ungültiger Index angeben (einer, der in der Deklaration nicht enthalten ist) können  undefinierte Dinge passieren, wenn dadurch andere Variableninhalte oder Programmcode überschrieben wird, der hinter oder vor dem Array im Speicher liegt. Schlimmstenfalls kann sogar der Computer/Controller abstürzen. Also darauf achten, daß keine ungültigen Werte als Index auftreten!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Strings (Zeichenketten)===&lt;br /&gt;
Ein String ist nichts anderes als ein Array, das aus einzelnen Zeichen (&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;) gebildet wird. Die Ausgabe auf dem Bildschirm funktioniert am einfachsten mittels Strings.&lt;br /&gt;
&lt;br /&gt;
Die Definition eines Strings erfolgt also genauso wie bei Arrays:&lt;br /&gt;
 char string[21];&lt;br /&gt;
&lt;br /&gt;
Nun haben Sie eine String, in dem Sie 21 Zeichen speichern können. Ganz richtig ist das jedoch nicht. C arbeitet mit &amp;quot;null-terminierten Strings&amp;quot;. Das beudeutet, dass die Länge des Strings nicht abgespeichert wird, sondern das Zeichen mit dem ASCII-Wert 0 das Stringende kennzeichnet. Daher auch die Bezeichnung  &amp;quot;null terminiert&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Das letzte Zeichen eines Strings muß daher immer das ASCII-Zeichen Nr. 0 sein. Ist es das nicht, hat der String kein definiertes Ende, und wenn Sie versuchen, ihn durch eine Standard-Funktion auszugeben zu lassen, könnte es eine Weile dauern, bis sich im Speicher zufällig irgendwo eine 0 befindet. Es stehen ihnen daher bei dem Beispiel nur 20 Zeichen zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
===Mehrdimensionale Arrays===&lt;br /&gt;
Manchmal benötigt man mehr als nur ein eindimensionales Array, wie Sie es bisher kennengelernt haben. Auch dies ist kein Problem. In der Deklaration geben Sie einfach mehrere eckige Klammern hintereinander an. Aber Vorsicht: der Speicherplatz ist begrenzt, ein &amp;quot;&amp;lt;tt&amp;gt;char feld[1024][1024]&amp;lt;/tt&amp;gt;&amp;quot; hat die Speicherplatzgrenzen vermutlich bereits weit überschritten, und der Compiler wird einen (bei gewissen Einstellung auch keinen) Fehler liefern.&lt;br /&gt;
Beim Zugriff auf mehrdimensionale Felder müssen auch mehrere Indizes angeben werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  int x,y;&lt;br /&gt;
  int feld[3][5];&lt;br /&gt;
 &lt;br /&gt;
  for (x=0; x&amp;lt;3; x++) &lt;br /&gt;
  {&lt;br /&gt;
     for (y=0; y&amp;lt;5; y++)&lt;br /&gt;
     {&lt;br /&gt;
       printf (&amp;quot;Feldwert x: %d,  y: %d &amp;quot;, x, y);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; feld[x][y]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  for(x=0; x&amp;lt;3; x++) &lt;br /&gt;
     for (y=0; y&amp;lt;5; y++) &lt;br /&gt;
        printf (&amp;quot;Wert: feld[%d][%d] = %d\n&amp;quot;, x, y, feld[x][y]);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 3 mal 5 &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array angelegt. &lt;br /&gt;
Dann werden die Werte eingegeben: zuerst &amp;lt;tt&amp;gt;feld[0][0]&amp;lt;/tt&amp;gt;, dann &amp;lt;tt&amp;gt;feld[0][1]&amp;lt;/tt&amp;gt;, usw. bis &amp;lt;tt&amp;gt;feld[2][4]&amp;lt;/tt&amp;gt;. &lt;br /&gt;
Zum Schluß werden alle Werte noch einmal ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===Strukturen===&lt;br /&gt;
In C können Sie sogenannte &amp;quot;Strukturen&amp;quot; definieren. Dabei handelt es sich um eine Zusammenfassung mehrerer Datentypen zu einem größeren. Im Unterschied zu Feldern können in Strukturen unterschiedliche Datentypen zusammengestellt und gespeichert werden: &lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 struct {{Bezeichner}}&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur 'Person'}}&lt;br /&gt;
 struct Person &lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;lt;tt&amp;gt;struct Person {&amp;lt;/tt&amp;gt;&amp;quot; leitet die Definition der Struktur mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;Person&amp;lt;/tt&amp;gt;&amp;quot; ein. &lt;br /&gt;
Dann werden in dieser Struktur fünf Komponenten definiert: drei Strings und zwei &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. &lt;br /&gt;
mit &amp;lt;tt&amp;gt;}&amp;lt;/tt&amp;gt; wird die Definition abgeschlossen. Sie haben damit einen Datentyp erstellt. Um eine Variable des Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach an&lt;br /&gt;
 struct Person {{Bezeichner}};&lt;br /&gt;
&lt;br /&gt;
Zum Zugriff auf eine Komponente der Struktur gibt man den Namen der Struktur-Variablen an (im folgenden Beispiel also &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;klaus&amp;lt;/tt&amp;gt;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
 {{comment|Definition zweier Struktur-Variablen}}&lt;br /&gt;
 struct Person hubert, klaus;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Zugriff auf Struktur-Komponenten}}&lt;br /&gt;
 hubert.alter = 32;&lt;br /&gt;
 klaus.alter = hubert.alter + 1;&lt;br /&gt;
&lt;br /&gt;
===Unions===&lt;br /&gt;
Eine Union wird ganz analog zu einer Struktur deklariert und verwendet. Sie unterscheidet sich von einer Struktur jedoch dadurch, daß ihre Elemente nicht nacheinander im Speicher abgelegt werden, sondern sich überlagern. Auf die in einer Union enthaltenen Daten gibt es also verschiedene Sichten: je nachdem, welche Sicht bzw. Interpretation der Daten man gerne hätte, wählt man den gewünschten Zugriff.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
union Daten &lt;br /&gt;
{&lt;br /&gt;
   int id;&lt;br /&gt;
&lt;br /&gt;
   struct Person u_person;&lt;br /&gt;
&lt;br /&gt;
   struct u_double&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      double wert;&lt;br /&gt;
   };&lt;br /&gt;
&lt;br /&gt;
   struct u_pointer&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      union Daten * p1;&lt;br /&gt;
      union Daten * p2;&lt;br /&gt;
   };&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
union Daten data;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies definiert eine Union mit den vier Zugriffsmöglichkeiten &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_double&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Größe der Union richtet sich dabei nach der grössten Komponente. In diesem Beispiel sind alle Komponenten so angelegt worden, daß sie an erster Stelle ein &amp;lt;tt&amp;gt;int id&amp;lt;/tt&amp;gt; enthalten. In &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; könnte man sich also merken, wie die Daten in der Union zu interpretieren sind. Würde &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; nicht dieses &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; enthalten, so würde sich &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; mit &amp;lt;tt&amp;gt;data.u_person.vname&amp;lt;/tt&amp;gt; überlagern. Ein Ändern der ersten Buchstaben von &amp;lt;tt&amp;gt;vname&amp;lt;/tt&amp;gt; hätte also ein Ändern von &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; zur Folge, und man könnte es nicht mehr als Merker verwenden. Mit diesem Feld überlagert das &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; die &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;-Felder der anderen Sichten, z.B. ist &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; der selbe Zugriff wie auf &amp;lt;tt&amp;gt;data.u_person.id&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein anderes Beispiel ist eine Union, die es ermöglicht, auf die einzelnen Bytes eines &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; zuzugreifen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef union&lt;br /&gt;
{&lt;br /&gt;
   unsigned long  as_long;&lt;br /&gt;
   unsignen short as_short[2];&lt;br /&gt;
   unsignen char  as_byte[4];&lt;br /&gt;
} data32_t;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies überlagert einen &amp;lt;tt&amp;gt;unsigned long&amp;lt;/tt&amp;gt; &amp;amp;ndash; also eine 32-Bit-Zahl &amp;amp;ndash; mit vier Bytes bzw. zwei Shorts.&lt;br /&gt;
 data32_t wert;&lt;br /&gt;
 &lt;br /&gt;
 wert.as_long = 0x12345678;&lt;br /&gt;
 wert.as_byte[0] = 0xab;&lt;br /&gt;
 {{comment|nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform)}}&lt;br /&gt;
&lt;br /&gt;
==Eigene Datentypen==&lt;br /&gt;
&lt;br /&gt;
=Variablen=&lt;br /&gt;
Eine Variable ist ein Synonym (=anderer Name) für eine Speicherstelle in einem Computer. Einfacher gesagt, eine Variable bietet Raum, um Daten wie Zahlen oder Zeichen zu speichern und wieder zu lesen.&lt;br /&gt;
&lt;br /&gt;
==Variablennamen==&lt;br /&gt;
Ein Variablenname kann zusammengesetzt werden aus den Buchstaben &amp;lt;tt&amp;gt;'''A'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''Z'''&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;'''a'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''z'''&amp;lt;/tt&amp;gt;, den Ziffern &amp;lt;tt&amp;gt;'''0'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''9'''&amp;lt;/tt&amp;gt;, sowie dem Sonderzeichen &amp;quot;Unterstrich&amp;quot; (underscore) &amp;lt;tt&amp;gt;'''_'''&amp;lt;/tt&amp;gt;. Dabei darf an erster Stelle keine Ziffer stehen. Die Bezeichner &amp;lt;tt&amp;gt;hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALLO&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALL0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;_123&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_HALLO&amp;lt;/tt&amp;gt; sind also alle gültige und unterschiedliche Variablennamen.&lt;br /&gt;
&lt;br /&gt;
==Anlegen von Variablen==&lt;br /&gt;
Um eine Variable verwenden zu können, muss sie zuerst vereinbart (&amp;quot;erzeugt&amp;quot;) werden. Dies wird auch als &amp;quot;''Definition der Variablen''&amp;quot; bezeichnet und geht so: Schreiben Sie zuerst den Datentyp, dann den Namen der Variablen. Zum Schluß kommt noch der Strichpunkt, wie nach jeder C-Anweisung oder Deklaration. Und nicht vergessen: C unterscheidet zwischen  Groß- und Kleinschreibung! &lt;br /&gt;
 int Zahl1, Zahl2;&lt;br /&gt;
 char Zeichen;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    float gleitZahl;&lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:'''&lt;br /&gt;
In einer Zeile können auch mehrere Variablen gleichen Types vereinbart werden, wenn man ein Komma dazwischen setzt. Variablen können in jedem Block vereinbart werden. Siehe [[#Gültigkeitsbereich|Gültigkeitsbereich]].&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen==&lt;br /&gt;
Man kann einer vereinbarten Variable Werte [[#Zuweisungen|zuweisen]]. Dazu schreibt man zuerst den Variablennamen, ein Gleichheitszeichen &amp;quot;&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;&amp;quot; und anschliessend den zuzuweisenden [[#Ausdrücke|Ausdruck]]. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, zahl2 = 12;&lt;br /&gt;
  char zeichen1 = 'A';&lt;br /&gt;
&lt;br /&gt;
  zahl1 = 52;&lt;br /&gt;
  zeichen1 = zeichen1 + 1; &lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Zuerst werden drei Variablen angelegt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;: wird gleich bei der Vereinbarung der Wert 12 zugewiesen. &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl1 = 52&amp;lt;/tt&amp;gt;: Hier wird der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; der Wert 52 zugewiesen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;: wird um 1 erhöht. Da in der Variablen &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; gespeichert ist, gibt sich ihr neuer Wert aus &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt;. Weil &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; dem Wert 65 entspricht, ist &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt; gleich 66, was dem Wert für &amp;lt;tt&amp;gt;'B'&amp;lt;/tt&amp;gt; entspricht.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei float==&lt;br /&gt;
Das funktioniert genau wie bei normale Zuweisungen. Nachkommastellen werden durch einen Punkt abgegrenzt: &lt;br /&gt;
 floatVariable = 3.14;&lt;br /&gt;
Zusätzlich kann eine Zehnerpotenz angegeben werden:&lt;br /&gt;
 floatVariable2 = -1.234E-6;&lt;br /&gt;
Dadurch wird der erst Wert mit 10&amp;lt;sup&amp;gt;&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;6&amp;lt;/sup&amp;gt; multipliziert, der Wert der Variablen ist also &lt;br /&gt;
:&amp;lt;math&amp;gt;-1{,}234\cdot10^{-6} = -0.000001234&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei logischen Variablen==&lt;br /&gt;
Wie bereits erwähnt, besitzt C keinen logischen Datentyp. Es müssen also &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; dafür genutzt werden. Die Zuweisung entpricht der Standard-Zuweisung. Wird der Wert 0 zugewiesen, dann ist die Variable &amp;quot;unwahr&amp;quot;, ansonsten ist sie &amp;quot;wahr&amp;quot;. &lt;br /&gt;
 intVariable = !0;   /* entspricht &amp;quot;wahr&amp;quot;   */&lt;br /&gt;
 intVariable = 0;    /* entspricht &amp;quot;unwahr&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
==Konstanten==&lt;br /&gt;
Konstanten können als Variable angesehen werden, die nicht beschrieben, sondern nur gelesen werden können. Ein typisches Beispiel dafür ist die Zahl &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; (rund 3,141592654). Niemand würde in der realen Welt versuchen, ihr einen anderen Wert zuzuweisen. Würde man &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; jedoch wie eine normale Variable anlegen, wäre dies ohne weiteres möglich. Um dies zu verhindern, gibt es das Schlüsselwort &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in C:&lt;br /&gt;
 const {{Type}} {{Bezeichner}} = {{Konstante}};  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Wichtig dabei ist, dass man Konstanten nur bei der Vereinbarung einen Wert zuweisen kann. &lt;br /&gt;
Da Konstanten gewöhnlich im gesamten Programm, zumindest einer Quelldatei genutzt werden, definiert man diese allerdings gewöhnlich außerhalb des main-Blockes entweder am Anfang eines Programmes, oder in einer sogenannten Header-Datei, die per &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; eingebunden wird.&lt;br /&gt;
 const float PI = 3.141592;  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Es sei jedoch erwähnt, daß auch einer Konstanten nachträglich ein anderer Wert zugewieden werden kann. Im obigen Beispiel könnte mit&lt;br /&gt;
 * ((float*) &amp;amp;PI) = 2;&lt;br /&gt;
der Wert von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; im Nachhinein verändert werden. Es wird die Adresse von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; genommen und diese Adresse durch den Cast in eine ganz normale &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;-Adresse umgewandelt, über welche der Wert geändert wird. Die sei der Vollständigkeit halber erwähnt.&lt;br /&gt;
&lt;br /&gt;
Je nachdem, an welcher Stelle sich das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; bei einer Pointer-Deklaration befindet, markiert es den Pointer als konstant oder das Objekt, auf das dieser Pointer zeigt. Eine häufige Parameterdeklaration in Ausgabe-Funktionen, die einen String erhalten, ist&lt;br /&gt;
 void foo (const char * str, ...);&lt;br /&gt;
Dadurch ist &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; der Zeiger auf eine Zeichenkette, die innerhalt der Funktion nicht verändert wird bzw. verändert werden darf. Eine Zuweisung wie &amp;lt;tt&amp;gt;*str = 'a'&amp;lt;/tt&amp;gt; ergibt also einen Fehler. &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; selbst kann aber sehr wohl verändert werden, etwa mit &amp;lt;tt&amp;gt;str++&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Soll ausgedrückt werden, daß &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; unveränderlich ist, dann so:&lt;br /&gt;
 void foo (char * const str, ...);&lt;br /&gt;
Jetzt wäre eine Änderung des Strings in Ordnung, etwa durch &amp;lt;tt&amp;gt;str[10] = 'a'&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Um sich zu merken, worauf das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; wirkt, trennt man die Deklaration in Gedanken beim&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf: Steht das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; links vom&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, dann gehört es zum &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, steht es rechts davon, dann gehört es zum Pointer. Natürlich ist es auch denkbar, beides &amp;amp;ndash; also den Zeiger und sein Ziel &amp;amp;ndash; als konstant zu markieren.&lt;br /&gt;
&lt;br /&gt;
==Gültigkeitsbereich==&lt;br /&gt;
In C können mehrere Variablen den gleichen Namen haben, solange eindeutig ist, welche in welchen Block gültig ist. Dabei gelten folgende Regeln: &lt;br /&gt;
&lt;br /&gt;
;Lokale Variablen: sind Variablen, die innerhalb eines Blockes definiert werden. Jede Variable ist nur in dem Block gültig, in dem sie vereinbart wurde, sowie in allen darin enthaltenen Blöcken; es sei denn, in einem Unter-Block wird eine Variable gleichen Namens definiert. Dann bezieht sich in diesem Unter-Block der Bezeichner auf die im Unter-Block angelegte Variable.&lt;br /&gt;
;Globale Variablen: werden ausserhalb jedes Blockes definiert und gelten ab der Stelle, an der sie deklariert werden, siehe auch [[#Deklaration und Definition|Deklaration und Definition]]. Wird jedoch in einem Block eine Variable gleichen Namens angelegt, gilt ab hier bis zum Ende des Blocks nicht mehr die globale Variable, sondern die im Block deklarierte. Das Spiel kann man weiterspielen: wird in einem Unter-Block wieder eine namensgleiche Variable angelegt, gilt diese in dem Unterblock.&lt;br /&gt;
&lt;br /&gt;
==Speicherklassen==&lt;br /&gt;
Jede Variable in C gehört zu einer bestimmten Speicherklasse&lt;br /&gt;
;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;: Lokale Variablen sind in aller Regal sogenannte ''automatische Variablen''. Das bedeutet, sie werden automatisch angelegt, wenn ein Block bzw. eine Funktion betreten wird und danach wieder entfernt. Das Schlüsselwort &amp;quot;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;&amp;quot; wird praktisch nie hingeschrieben, denn lokale Variablen ohne die ausdrückliche Angabe einer Speicherklasse, sind automatisch automatische Variablen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;: Eine externes Symbol ist im ganzen Programm bekannt bzw. in dem Block, in der die Deklaration steht. In unterschiedlichen Blöcken stehende Deklarationen beziehen sich auf das gleiche Symbol! Obgleich das Datum global zugreifbar ist, ist der Gültigkeitsbereich auf den deklarierenden Block begrenzt bzw. auf das deklarierende Quell-Modul, sofern das Symbol ausserhalb jedes Blocks des Moduls deklariert wird. Siehe auch [[#Deklaration und Definition|Deklaration und Definition]].&lt;br /&gt;
;&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;: Die Variable ist im Block gültig bzw. im Quell-Modul (also in der C-Datei, in der die angelegt wurde), wenn sie nicht innerhalb eines Blockes angelegt wurde. Statische Variablen werden nicht in Registern oder im Frame der Funktion angelegt, sondern im selben Speicherbereich, in dem auch die globalen Variablen liegen; Konstanten evtl. auch im Flash. Eine lokale Variable, die als &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; angelegt wird, &amp;quot;überlebt&amp;quot; also das Verlassen des Blocks und hat beim neuerlichen Betreten des Blockes ihren bisherigen Wert. In unterschiedlichen Blöcken angelegte lokale statische Variablen beziehen sich auf unterschiedliche Speicherstellen, genau wie bei lokalen Variablen auch.&lt;br /&gt;
;&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;: Durch diese Speicherklasse wird eine Variable &amp;amp;ndash; falls möglich &amp;amp;ndash; als Registervariable angelegt, also in einem Maschinenregister des Computer/Controllers gehalten. Dadurch kann auf solche Variablen besonders schnell zugegriffen werden. Dieses Schlüsselwort ist bei modernen Compilern weitgehend überflüssig, da die entsprechenden Optimierungen selbständig vorgenommen werden, wenn ausreichend Register vorhanden sind. Auch globale Variablen können als Register angelegt werden, davon ist dem Anfänger aber dringend abzuraten, weil leicht schwerauffindbare Fehler und Abstürze auftreten, wenn man nicht genau weiss, welche Implikationen in einer solchen Definition stecken!&lt;br /&gt;
;&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;: (FIXME: volatile ist ein Qualifier und keine Speicherklasse) Dies ist das genaue Gegenteil von &amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt; und bewirkt, dass die Variable auf keinen Fall in einem Register zwischengespeichert werden darf, sondern immer aus dem RAM gelesen und ins RAM geschrieben werden soll. &amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt; müssen alle ''globalen'' Variablen markiert werden, die in [[ISR | Interrupt-Handlern]] verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Ausdrücke=&lt;br /&gt;
Eine Variable oder eine Konstante in C stellen einfache Ausdrücke dar.&lt;br /&gt;
Diese elementaren Ausdrücke können durch Operatoren miteinander verknüpft werden und so zu neuen, komplexeren Ausdrücken zusammen gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Einfache Beispiele für Ausdrücke sind also z.B.:&lt;br /&gt;
 1&lt;br /&gt;
 a&lt;br /&gt;
 'a'&lt;br /&gt;
 1 + a&lt;br /&gt;
 a == 1&lt;br /&gt;
&lt;br /&gt;
Auch Funktionen können einen Wert zurückliefern und in Ausdrücken weiter benutzt werden.&lt;br /&gt;
In den folgenden Abschnitten wird gezeigt, welche Operatoren in C vorhanden sind,&lt;br /&gt;
und wei man damit neue Ausdrücke aufbauen kann.&lt;br /&gt;
&lt;br /&gt;
==Lvalues==&lt;br /&gt;
&lt;br /&gt;
Ein Lvalue in C ist ein Ausdruck, dem ein anderer Ausdruck zugewiesen werden kann, dessen Wert also durch eine Zuweisung verändert werden kann.&lt;br /&gt;
das 'L' leitet sich ab von 'left' bwz. 'links' und das 'value' bedeutet Wert: Ein Lvalue ist ein Ausdruck, der auf der linken Seite einer Zuweisung stehen darf. Ein Lvalue ist also immer auch ein gültiger Ausdruck, aber die Umkehrung gilt in alles Regel nicht.&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für einen Lvalue ist eine &amp;quot;normale&amp;quot; Variable, die nicht mit &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; als Konstante markiert ist:&lt;br /&gt;
 a = 1;&lt;br /&gt;
Hingegen ist der Ausdruck &amp;lt;tt&amp;gt;a+1&amp;lt;/tt&amp;gt; kein Lvalue, denn eine Zuweisung wie&lt;br /&gt;
 a+1 = 2;&lt;br /&gt;
die mathematisch durchaus sinnvoll ist, erzeugt einen Compilerfehler, der etwa lauten könnte &amp;quot;illegal lvalue in assignment&amp;quot;:&lt;br /&gt;
&amp;quot;ungültiger Wert in Zuweisung&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Andere Beipiele für Lvalues sind die Komponenten von (nicht-konstanten) [[#Strukturen|Strukturen]] und [[#Unions|Unions]], [[#Arrays|Array]]-Elemente und die Dereferenzierungen von Pointern: Die Konstante&amp;amp;nbsp;4 wird durch den Cast in eine Adresse umgewandelt. Über die Dereferenzierung&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; wird an die Adresse&amp;amp;nbsp;4 im Speicher eine&amp;amp;nbsp;3 geschrieben. Ob das erlaubt bzw. sinnvoll ist, ist abhängig von der jeweiligen Architektur.&lt;br /&gt;
 * ((unsigned int *) 4) = 3;&lt;br /&gt;
Hier ist der gesamte &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;-Ausdruck ein Lvalue&lt;br /&gt;
&lt;br /&gt;
==Logische (boolsche) Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp;amp;&amp;amp;amp; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr oder &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; || gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; || ungleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;= b&amp;lt;/tt&amp;gt; || kleiner oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt; b&amp;lt;/tt&amp;gt; || kleiner als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt;= b&amp;lt;/tt&amp;gt; || glösser oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt; b&amp;lt;/tt&amp;gt; || grösser als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; nicht wahr und vice versa&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine interessante Eigenschaft der Operatoren &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;amp;amp;&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; ist, dass&lt;br /&gt;
sie die Auswertung abbrechen, sobald das Ergebnis feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet. Ein oft anzutreffendes Codestück sieht so aus, dabei sei &amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
  if (p &amp;amp;&amp;amp; *p == 5)&lt;br /&gt;
  {&lt;br /&gt;
     {{comment|mach was}}&lt;br /&gt;
  }&lt;br /&gt;
Zuerst wird in der Bedinung geprüft, ob Zeiger&amp;amp;nbsp;&amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; einen Wert ungleich Null hat, also ob er überhaupt einen gültigen Wert enthält. Es ist weit verbreitete Konvention in C, daß Zeiger, die keinen gültigen Wert haben, die Adresse&amp;amp;nbsp;0 enthalten. '''Nur dann, wenn ein Zeiger nicht ein Null-Pointer ist, darf überhaupt ein Zugriff über ihn erfolgen!'''&lt;br /&gt;
&lt;br /&gt;
==Vergleich von Variablen==&lt;br /&gt;
Skalare Variablen (also ganze Zahlen, Gleitkommazahlen, Zeiger) können miteinander verglichen werden. Dazu gibt es die folgenden Operatoren in C: &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; || ist nicht gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;=&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;=&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das Ergebnis der Auswertung ist eine ganze Zahl. Ist die Bedingung erfüllt, dann ist der Wert ungleich&amp;amp;nbsp;0. Ist die Bedingung nicht erfüllt, dann ist ihr Wert gleich&amp;amp;nbsp;0.&lt;br /&gt;
Meistens wird man diese Operatoren in &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Konstrukten finden wie zum Beispiel&lt;br /&gt;
 if (x &amp;gt;= 10)&lt;br /&gt;
    x = 10;&lt;br /&gt;
oder in Abbruchbedingungen von Schleifen, wie sie weiter unten erklärt werden.&lt;br /&gt;
&lt;br /&gt;
Es ist auch möglich, das Ergebnis der Auswertung in einer &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Variablen zu speichern:&lt;br /&gt;
 int i;&lt;br /&gt;
 int z1, z2;&lt;br /&gt;
 &lt;br /&gt;
 z1 = 5;&lt;br /&gt;
 z2 = 100;&lt;br /&gt;
 i = z1 &amp;lt;= z2;  {{comment|Ein Vergleich. i wird &amp;quot;wahr&amp;quot;, da z1 kleinergleich z2 ist}}&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich&amp;amp;nbsp;0 (&amp;quot;wahr&amp;quot;), wenn &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; kleiner oder gleich &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt; ist. Ist &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; jedoch größer als &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt;, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich&amp;amp;nbsp;0 (&amp;quot;unwahr&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
==Arithmetische Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a + b&amp;lt;/tt&amp;gt; || Summe (Addition)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a - b&amp;lt;/tt&amp;gt; || Differenz (Subtraktion)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a * b&amp;lt;/tt&amp;gt; || Produkt (Multiplikation)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a / b&amp;lt;/tt&amp;gt; || Quotient (Division, evtl. mit Rest)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a % b&amp;lt;/tt&amp;gt; || Rest bei Division (Modulo)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;-a&amp;lt;/tt&amp;gt; || Vorzeichenumkehr (Zweierkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Bit-Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp; b&amp;lt;/tt&amp;gt; || bitweise und (and)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || bitweise oder (or)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a ^ b&amp;lt;/tt&amp;gt; || bitweise exclusiv-oder (xor, exor)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;~a&amp;lt;/tt&amp;gt; || jedes Bit in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; invertieren (not, Einerkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Index-Operator bei Arrays==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a[b]&amp;lt;/tt&amp;gt; || das (b+1)ste Element des Feldes a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Folgendes gilt es bei der Verwendung des Indexoperators zu beachten:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; muss ein [[C-Tutorial#Felder | Feld]] oder [[C-Tutorial#Zeiger | Zeiger]] sein&lt;br /&gt;
# &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; muss ein Integer sein oder ein Datentyp, der sich in einen int umwandeln läßt (z.B. char)&lt;br /&gt;
# Es wird nicht geprüft, ob der Index &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; im Feld &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gültig ist!&lt;br /&gt;
# Der erste Index eines Feldes ist immer 0. Daher ''(b+1)stes Element'' in der Beschreibung&lt;br /&gt;
&lt;br /&gt;
==Komponenten-Auswahl bei Structs und Unions==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a.b&amp;lt;/tt&amp;gt; || Element b der [[C-Tutorial#Strukturen | Struktur]] oder des Unions a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adress-Operator und Dereferenzierung==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&amp;amp;amp;a&amp;lt;/tt&amp;gt; || Speicheradresse der Variablen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;*a&amp;lt;/tt&amp;gt; || Wert, der an der Adresse &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a-&amp;amp;gt;b&amp;lt;/tt&amp;gt; || Wert des Elements &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; der Struktur, deren Adresse in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Adressoperator &amp;amp; kann auf Variablen angewendet werden und&lt;br /&gt;
gibt die Startadresse der Variablen im Speicher zurück.&lt;br /&gt;
&lt;br /&gt;
Handelt es sich bei einer Variable um einen [[C-Tutorial#Zeiger | Zeiger]], so enthält&lt;br /&gt;
sie eine Speicheradresse. Um an den '''Wert''' zu gelangen, der&lt;br /&gt;
an dieser Adresse steht, wird der Operator * vorangestellt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
&lt;br /&gt;
 {{comment|x ist eine Integervariable und hat den Wert 5}}&lt;br /&gt;
 int x = 5;&lt;br /&gt;
     &lt;br /&gt;
 {{comment|z ist ein Zeiger auf eine Integer-Variable und enthaelt somit}}&lt;br /&gt;
 {{comment|die Speicheradresse einer Integer-Variablen}}&lt;br /&gt;
 int *z;       &lt;br /&gt;
  &lt;br /&gt;
 {{comment|Verwendung des Adress-Operators: weist an z die Adresse von x zu}}&lt;br /&gt;
 z = &amp;amp;x;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Verwendung der Dereferenzierung}}&lt;br /&gt;
 {{comment|erhoehe den Wert, der bei Adresse z steht, um eins}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|da z auf x zeigt, hat x jetzt den Wert 6}}&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff auf Struktir- und Union-Elemente eine abkürzende Schreibweise möglich:&lt;br /&gt;
&lt;br /&gt;
Statt &lt;br /&gt;
  (*strukturZeiger).element&lt;br /&gt;
kann geschrieben werden&lt;br /&gt;
  strukturZeiger-&amp;gt;element&lt;br /&gt;
Beide Schreibweisen sind absolut gleichbedeutend, die Klammern bei der ersteren sind notwendig.&lt;br /&gt;
&lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
:Bei der Dereferenzierung durch &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; findet keine Prüfung statt, ob der Zeiger auch auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu einer Änderung '''irgendeiner''' Speicherstelle!&lt;br /&gt;
&lt;br /&gt;
 int *z; {{comment|z ist ein Zeiger auf einen int}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.}}&lt;br /&gt;
 {{comment|z enthaelt irgendeine ungueltige Adresse!!}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|&amp;quot;Erhoehe einen Integer _irgendwo_ im Speicher um 1&amp;quot; -&amp;gt; CRASH !!!}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
&lt;br /&gt;
==Cast-Operator==&lt;br /&gt;
&lt;br /&gt;
Der Cast Operator dient dazu, den Datentyp eines Wertes zu ändern. Dafür wird einfach der neue Datentyp in Klammern vor den Wert geschrieben.&lt;br /&gt;
&lt;br /&gt;
Um zum Beispiel aus einem Float ein Integer zu machen:&lt;br /&gt;
 var  = (int) 5.60;&lt;br /&gt;
Dabei wird der Wert aber auch gerundet, und es findet somit ein Informationsverlust statt.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Umwandeln einer ganzen Zahl in eine Adresse:&lt;br /&gt;
 int * addr;&lt;br /&gt;
 addr = (int*) 0x1234;&lt;br /&gt;
Damit ist &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; an Adresse 0x1234.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
Der Cast-Operator selbst führt ''keine Konvertierung'' von Darstellungen durch, etwa die Umwandlung der ganzen Zahl 123 ein den String &amp;lt;tt&amp;gt;&amp;quot;123&amp;quot;&amp;lt;/tt&amp;gt;, der diese Zahl darstellt! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
  int main(int argc, char ** argv)&lt;br /&gt;
  {&lt;br /&gt;
        char text[] = &amp;quot;5.6&amp;quot;;&lt;br /&gt;
        int zahl = (int) text;&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, zahl);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Anfangsadresse des Strings &amp;lt;tt&amp;gt;&amp;quot;5.6&amp;quot;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Komma-Operator==&lt;br /&gt;
Mit einem &amp;lt;tt&amp;gt;,&amp;lt;/tt&amp;gt; können mehrere Ausdrücke nacheinander ausgewertet werden.&lt;br /&gt;
Die Auswertung erfolgt von links nach rechts.&lt;br /&gt;
&lt;br /&gt;
Solche Konstrukte sieht man manchmal in Abfragen wie&lt;br /&gt;
 FILE  *file;&lt;br /&gt;
 if (file = fopen (&amp;quot;foo.exe&amp;quot;, &amp;quot;r&amp;quot;), file != NULL)&lt;br /&gt;
was erst an &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; einen Wert zuweist und den &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Block nur betritt,&lt;br /&gt;
wenn &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; nicht der Nullpointer ist.&lt;br /&gt;
&lt;br /&gt;
Bequem kann das auch in einer [[#for-Schleife|for-Schleife]] sein, wenn man zwei (oder mehr) Laufvariablen hat oder so:&lt;br /&gt;
 for (i=0, j=0; i &amp;lt; 10; i++, j += 2)&lt;br /&gt;
    &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Zuweisung===&lt;br /&gt;
=== ++ und -- ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; stellen einfachere Schreibweisen dar zum Addieren bzw. Subtrahieren von&amp;amp;nbsp;1.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; (Inkrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo++; &lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo + 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; 3}}&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; (Dekrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo--;&lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo - 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; -1}}&lt;br /&gt;
&lt;br /&gt;
Die beiden Operatoren können sowohl in der Präfix-Schreibweise (vor der Variablen) als auch als Postfix-Schreibweise (hinter der Variablen) notiert werden. &lt;br /&gt;
Der Unterschied liegt darin, dass beim Präfix der Wert zuerst neu berechnet wird und die Variable dann verwendet wird. Beim Postfix wird die Variable zuerst verwendet und erst nach Auswertung des Ausdrucks, in dem sie enthalten ist, neu berechnet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 int ausgabe1, ausgabe2, var1 = 10, var2 = 10;&lt;br /&gt;
 ausgabe1 = 3 * ++var1; {{comment|ausgabe1 &amp;amp;#61; 33; var1 &amp;amp;#61; 11;}}&lt;br /&gt;
 ausgabe2 = 3 * var2++; {{comment|ausgabe2 &amp;amp;#61; 30; var2 &amp;amp;#61; 11;}}&lt;br /&gt;
&lt;br /&gt;
Für Zeiger arbeiten diese Operatoren etwas anders, siehe dazu [[#Zeiger-Arithmetik|Zeiger-Arithmetik]].&lt;br /&gt;
&lt;br /&gt;
===Bedingter Ausdruck===&lt;br /&gt;
 ({{Bedingung}}) ? {{Ausdruck|1}} : {{Ausdruck|2}}&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; erfüllt ist, dann wertet dieser Ausdruck aus zu &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt;. Ist er nicht erfüllt, dann wertet er aus zu &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 x = (x &amp;gt;= 3) ? 0 : x+1;&lt;br /&gt;
Startet man &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; mit dem Wert 0, dann nimmt es bei mehrfacher Anwendung dieser Zeile (z.B. in einer Schleife) nacheinander die folgende Werte an:&lt;br /&gt;
:&amp;lt;tt&amp;gt;1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, ...&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&lt;br /&gt;
Wie auch in der Mathematik gibt es auch in C genaue Regeln über die Abarbeitungsreihenfolge (precedence)&lt;br /&gt;
der Operatoren. Dass sich alle C-Compiler genau an diesen ANSI-Vorschlag halten, ist leider nicht sicher.&lt;br /&gt;
Neben hat auch nicht jeder Programmierer diese Regel jederzeit im Kopf. &lt;br /&gt;
Daher ist es sinnvoll, Ausdrücke durch runde Klammern eindeutig zu kennzeichnen. &lt;br /&gt;
Nebenbei stören sich Compiler nicht an überflüssigen Klammerpaaren.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Priorität ||Operator||Assoziativität&lt;br /&gt;
|-&lt;br /&gt;
  &lt;br /&gt;
|&amp;lt;tt&amp;gt;15&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ( ) [ ] -&amp;gt; . &amp;lt;/tt&amp;gt;                      ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;14&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;! ~ ++ -- + - (TYP) * &amp;amp; sizeof &amp;lt;/tt&amp;gt;    ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;13&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; * / % (Rechenoperationen) &amp;lt;/tt&amp;gt;         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;12&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; + - (binär) &amp;lt;/tt&amp;gt;                       ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;11&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;&amp;lt; &amp;gt;&amp;gt; &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;10&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt; &amp;lt;= &amp;gt; &amp;gt;= &amp;lt;/tt&amp;gt;                         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 9&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; == != &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 8&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp; (bit-AND-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 7&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ^ (bit-XOR-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 6&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; (bit-OR-Operator)&amp;lt;/tt&amp;gt;   ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 5&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp;&amp;amp; &amp;lt;/tt&amp;gt;                                ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 4&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; &amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 3&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;? : &amp;lt;/tt&amp;gt;                               ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 2&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; = += -= /= *= %= &amp;gt;&amp;gt;= &amp;lt;&amp;lt;= &amp;amp;= &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;= ^= &amp;lt;/tt&amp;gt; ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 1&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; , (Sequenz-Operator) &amp;lt;/tt&amp;gt;              ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
Eine Kontrollanweisung ist eine Anweisung, die Einfluss auf den Programmfluss hat. Normalerweise werden Anweisungen so ausgeführt, wie sie in der Quelldatei stehen: Von links nach rechts (falls mehrere Anweisungen in einer Zeile stehen sollten, wovon i.A. abzuraten ist) und von oben nach unten. Mit einer Kontrollanweisung kann dieser lineare Programmfluss durchbrochen werden: Die Codeausführung kann kann abhängig von einer Bedingung gemacht werden (&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;), kann wiederholt werden (Schleife) oder an einer anderen Stelle der Funktion fortgesetzt werden (&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==if-Anweisung==&lt;br /&gt;
Mit Hilfe des if-Befehls kann man Codeteile abhängig davon einer Bedingung ausführen lassen:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
oder mit else-Teil&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 if (x &amp;gt; 100)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;gt; 100 ist: Fehlerausgabe}}&lt;br /&gt;
    printf (&amp;quot;x = %d ist zu gross fuer die Berechnung!\n&amp;quot;, x);&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;lt;&amp;amp;#61; 100 ist: Berechne Summe der Zahlen 1...x}}&lt;br /&gt;
    {{comment|Die lokale Variable x2 lebt nur innerhalb dieses alse-Blocks}}&lt;br /&gt;
    int x2 = x;&lt;br /&gt;
 &lt;br /&gt;
    for (x = 0; x2 &amp;gt; 0; x2--)&lt;br /&gt;
       x += x2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Wenn die Bedingung wahr ist (&amp;lt;tt&amp;gt;x &amp;gt; 100&amp;lt;/tt&amp;gt;), dann wird eine Meldung ausgegeben; danach ist die if-Anweisung beendet. Der else-Block wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung nicht erfüllt (&amp;lt;tt&amp;gt;x &amp;amp;le; 100&amp;lt;/tt&amp;gt;), dann wird gleich zum else-Teil gesprungen, und nach dessen Ausführung der if-Befehl beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Ein häufiger Fehler ist es, statt &amp;lt;tt&amp;gt;if (a &amp;amp;#61;&amp;amp;#61; 23)&amp;lt;/tt&amp;gt; etwas wie &amp;lt;tt&amp;gt;if (a &amp;amp;#61; 23)&amp;lt;/tt&amp;gt; zu schreiben. &lt;br /&gt;
Dann wird allerdings nicht geprüft, ob die Variable&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gleich 23 ist, sondern der Variablen&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wird der Wert 23 zugewiesen. Der Ausdruck &amp;lt;tt&amp;gt;a &amp;amp;#61; 23&amp;lt;/tt&amp;gt; hat den Wert&amp;amp;nbsp;23 und ist damit immer &amp;quot;wahr&amp;quot;! Daher ist diese if-Bedingung immer erfüllt!&lt;br /&gt;
&lt;br /&gt;
Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken sondern bestenfalls eine Warnung. Damit ist dieser Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise &amp;lt;tt&amp;gt;if (23 &amp;amp;#61;&amp;amp;#61; a)&amp;lt;/tt&amp;gt;. Wenn man dort anstatt des Vergleichsoperators '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;amp;#61;&amp;lt;/tt&amp;gt;' den Zuweisungsoperator '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;lt;/tt&amp;gt;' verwendet, spuckt der Compiler sehr wohl einen Fehler aus! Ist die Zuweisung jedoch erwünscht und eine Compiler-Warnung lästig, dann wählt man eine Schreibweise wie &amp;lt;tt&amp;gt;if ((a &amp;amp;#61; b))&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;if (a &amp;amp;#61; b, a)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist zu schreiben &amp;lt;tt&amp;gt;if (Bedingung);&amp;lt;/tt&amp;gt; Richtig muss es heissen &amp;quot;&amp;lt;tt&amp;gt;if(Bedingung)&amp;lt;/tt&amp;gt;&amp;quot; Das Semikolon im ersten Fall ist eine leere Anweisung, die im if-Falle ausgeführt wird &amp;amp;ndash; sie bleibt also ohne Resultet. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt; ein auf das Semikolon folgende Anweisung die eigentlich zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören soll wird immer ausgeführt, die sie nicht mehr zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; dazu gehört.&lt;br /&gt;
}}&lt;br /&gt;
Bei verschachtelten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Konstrukten gehört ein &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zu letzten &amp;quot;freien&amp;quot; &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;. Soll in einer &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Folge das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zum ersten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören, dann ist das so zu hinzuschreiben:&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Ohne die geschweiften Klammern um das zweite &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehörte das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; dort hinzu.&lt;br /&gt;
&lt;br /&gt;
==switch-Anweisung==&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
&lt;br /&gt;
 switch ({{Ausdruck|}}) &lt;br /&gt;
 {&lt;br /&gt;
     case konstante1:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
    &lt;br /&gt;
     case konstante2:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 &lt;br /&gt;
     {{comment|weitere case-Marken}}&lt;br /&gt;
 &lt;br /&gt;
     default:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 } {{comment|Ende von switch}} &lt;br /&gt;
&lt;br /&gt;
Der Ausdruck muss ein skalarer Typ sein, er wird in die nächste ganze Zahl gewandelt und mit den Werten hinter den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Marken verglichen. Bei einer Übereinstimmung werden alle Befehle ab dem zutreffenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; ausgeführt. Stimmt der Ausdruck mit keinem der Werte überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt falls vorhanden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der nachfolgenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;- und des &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitts werden ausgeführt, wenn die Anweisungen des &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitts nicht mit dem Befehl &amp;lt;tt&amp;gt;break;&amp;lt;/tt&amp;gt; beendet werden!&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es dürfen beliebig viele &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitte angegeben werden, pro Vergleichswert jedoch nur einer.&lt;br /&gt;
Der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ist optional. Die Reihenfolge, in der &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt; angegeben werden, ist unerheblich.&lt;br /&gt;
&lt;br /&gt;
==Schleifen==&lt;br /&gt;
Um Anweisungen mehrmals hintereinander auszuführen, benötigt man Schleifen. Diese führen Anweisungen aus, bis oder solange Bedingungen erfüllt sind.&amp;lt;br&amp;gt; &lt;br /&gt;
Wichtig ist also, ob die Bedingung '''vor''' oder '''nach''' den Schleifen-Anweisungen geprüft wird. &lt;br /&gt;
&lt;br /&gt;
===while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 while ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Die while-Schleife wird solange durchlaufen, wie die Bedingung erfüllt ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Die Anweisung kann natürlich auch ein Block sein, der aus mehreren Deklarationen und Anweisungen besteht. &lt;br /&gt;
&lt;br /&gt;
 int zahl1 = 0;&lt;br /&gt;
 int zahl2 = 1;&lt;br /&gt;
 &lt;br /&gt;
 while (zahl1 &amp;lt; 3)&lt;br /&gt;
 {&lt;br /&gt;
    zahl1 = zahl1 + 1;&lt;br /&gt;
    zahl2 = zahl2 * 2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife drei mal durchlaufen. Zu Beginn des vierten Durchlaufs ist die Bedingung nicht mehr erfüllt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
&lt;br /&gt;
===do-while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
Die do-while-Schleife wird auf jeden Fall einmal durchlaufen und dann solange wiederholt, wie die Bedingung erfüllt ist.&lt;br /&gt;
 int i = 2;&lt;br /&gt;
 &lt;br /&gt;
 do &lt;br /&gt;
 {&lt;br /&gt;
     i = i*i;   {{comment|i quadrieren}}&lt;br /&gt;
     printf (&amp;quot;i = %d\n&amp;quot;, i);&lt;br /&gt;
 }&lt;br /&gt;
 while (i &amp;lt; 20);&lt;br /&gt;
&lt;br /&gt;
Die Schleife wird durchlaufen und wiederholt, solange &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; kleiner als 20 ist. Es werden also nacheinander die Werte 2, 4 und 16 ausgegeben. Nach der Schleife hat&amp;amp;nbsp;&amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; den Wert 256.&lt;br /&gt;
&lt;br /&gt;
===for-Schleife===&lt;br /&gt;
'''Syntax:''' &lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Bei den Ausdrücken wird es sich um einen Ausdrücke mit Nebeneffekt handeln wie etwa &amp;lt;tt&amp;gt;i=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;i=i+2&amp;lt;/tt&amp;gt;. Es werden folgende Aktionen ausgeführt:&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# falls die Bedingung wahr ist, dann führe &amp;lt;tt&amp;gt;Anweisung&amp;lt;/tt&amp;gt; aus.&lt;br /&gt;
# falls die Bedingung unwahr ist, dann sprinte zu 7 (Ende).&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# gehe zu 2&lt;br /&gt;
# nächste Anweisung nach der for-Schleife&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int lauf, summe;&lt;br /&gt;
 &lt;br /&gt;
 for (lauf=1, summe=0; lauf &amp;lt;= 10; lauf += 2) &lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel ist &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; ein [[#Komma-Operator|Komma-Ausdruck]], der zwei Anweisungen kombiniert und daher sogar zwei Nebeneffente hat: er setzt &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;1 und &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;0.&lt;br /&gt;
&lt;br /&gt;
Das Äquivalent als while-Schleife:&lt;br /&gt;
&lt;br /&gt;
 int lauf  = 1;                 {{comment|Anfangswerte}}&lt;br /&gt;
 int summe = 0;&lt;br /&gt;
 &lt;br /&gt;
 while (lauf &amp;lt;= 10)             {{comment|Bedingung}}&lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
    lauf  += 2;                 {{comment|Inkrement}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; in jedem Schleifendurchlauf um die Laufvariable &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; erhöht. Da &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nacheinander die ungeraden Werte von&amp;amp;nbsp;1 bis&amp;amp;nbsp;10 annimmt, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von&amp;amp;nbsp;1 bis kleinergleich 10 gespeichert, also der Wert&amp;amp;nbsp;25. &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; hat nach der Schleife den Wert&amp;amp;nbsp;11.&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf = 1&amp;lt;/tt&amp;gt; bedeutet, dass der Variablen &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; vor dem ersten Schleifendurchlauf der Wert&amp;amp;nbsp;1 zugewiesen wird. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf &amp;lt;= 10&amp;lt;/tt&amp;gt; ist die Schleifenbedingung; ist sie nicht erfüllt, wird die Schleife beendet. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf += 2&amp;lt;/tt&amp;gt; bedeutet, dass &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nach jedem Durchlauf um&amp;amp;nbsp;2 erhöht wird.&lt;br /&gt;
&lt;br /&gt;
===continue-Anweisung===&lt;br /&gt;
Innerhalb einer Schleife darf die &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die nachfolgenden Anweisungen übersprungen werden und mit dem nächsten Schleifendurchlauf fortgesetzt wird &amp;amp;ndash; vorausgesetzt die Schleifenbedingung ist noch erfüllt. Ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; etc. stehen, wenn dieses innerhalb einer Schleife steht.&lt;br /&gt;
&lt;br /&gt;
==break-Anweisung==&lt;br /&gt;
Innerhalb einer Schleife oder eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; darf die &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die Schleifen-/Switch-Anweisung sofort verlassen wird und das Programm dahinter weiter macht. Bei mehrfach geschachtelten Schleifen wird nur die innere verlassen. Ein &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; stehen, wenn dieses innerhalb einer Schleife/Switch-Anweisung steht.&lt;br /&gt;
&lt;br /&gt;
==goto-Anweisung==&lt;br /&gt;
&lt;br /&gt;
Innerhalb ein und derselben Funktion kann mit &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; an eine andere Stelle gesprungen werden. Dazu gibt man hinter dem &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einen Bezeichner an, der dadurch als Label fungiert:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 goto {{Bezeichner}};&lt;br /&gt;
Die Bezeichner selbst steht irgendwo in der Funktion und wird dadurch zur Sprungmarke (Label), daß er von einem Doppelpunkt (und mindestens einer C-Anweisung, die auch leer sein darf) gefolgt wird.&lt;br /&gt;
&lt;br /&gt;
Das Beispiel durchsucht das 2-dimensionale &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array &amp;lt;tt&amp;gt;feld&amp;lt;/tt&amp;gt; mit den &amp;lt;tt&amp;gt;SIZE_X &amp;amp;times; SIZE_Y&amp;lt;/tt&amp;gt; Werten nach dem Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;. Wird er gefunden, dann wird die 2-fach geschachtelte Suchschleife verlassen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int x, y;&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y; y++)&lt;br /&gt;
       if (feld[x][y] == 0)&lt;br /&gt;
          goto done;&lt;br /&gt;
 {{Label|done:}};&lt;br /&gt;
&lt;br /&gt;
Der folgende Code hat die gleiche Funktion, arbeitet jedoch ohne &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int x, y;&lt;br /&gt;
 int found = 0; {{comment|FALSE}}&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X &amp;amp;&amp;amp; !found; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y &amp;amp;&amp;amp; !found; y++)&lt;br /&gt;
       found = (0 == feld[x][y]);&lt;br /&gt;
Der Nachteil der &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-losen Variante ist, daß man eine Variable, die merkt, ob das Suchziel gefunden wurde, mitschleppen und in ''jedem'' Schleifendurchlauf abtesten muss. Dies bedeutet einen höheren Programmier- und Laufzeitaufwand und ist nicht so klar formuliert wie das &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-Beispiel.&lt;br /&gt;
&lt;br /&gt;
Gleichwohl sei angemerkt, daß die Verwendung von &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einem gewissen Dogmatismus unterliegt, der sich wie folgt subsummieren liesse:&lt;br /&gt;
:''goto ist böse und sollte keinesfalls verwendet werden! Wer es dennoch tut, offenbart dadurch seinen schlechten Geschmach sowie mangelhafte C-Kenntnis.'' &amp;lt;div align=&amp;quot;right&amp;quot;&amp;gt;http://www.roboternetz.de/phpBB2/images/smiles/icon_wink.gif&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Funktionen=&lt;br /&gt;
Stellen Dir vor, Du hast eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben &amp;amp;ndash; was Dich Zeit beim Erstellen des Programms und Speicherplatz im ausführbaren Programm kostet &amp;amp;ndash; kannst Du den Code-Abschnitt in eine Funktion schreiben und diese von jeder Stelle des Programms aus verwenden. Die Hauptgründe, um Funktionen zu verwenden, sind:&lt;br /&gt;
;Wiederverwendung von Code: Mehrfach verwendete Codestücke müssen nicht mehrfach implementiert werden. Oft unterscheiden sich die Codesequenzen nur in Kleinigkeiten, die man der Funktion über Parameter mitteilen kann.&lt;br /&gt;
;Übersichtlichkeit: Ein gut gegliedertes C-Programm implementiert klar umrissene Aufgaben in einer Funktion, auch wenn diese Funktion nur einmal im Code aufgerufen wird! Dadurch bleibt der Code um die Aufrufstelle besser verständlich, und man kann auf verschiedenen &amp;quot;Ebenen&amp;quot; denken. Eine Funktion wie &amp;quot;Datei öffnen&amp;quot; kann recht komplex sein. Auf höherer Ebene interessieren die Innereien nicht mehr, man möchte sich um andere Dinge kümmern und will den Code an der Stelle garnicht sehen...&lt;br /&gt;
;Rekursive Funktionen: Eine Funktion kann sich auch selbst aufrufen. In dem Falle nennt man die Funktion ''rekursiv''. Zwar lässt sich das, was eine rekursive Funktion tut, auch mit anderen Mitteln formulieren, die keine rekursiven Funktionen brauchen, aber oft ist der rekursive Weg knackiger und klarer formulierbar als eine nicht-rekursiven Ansatz, auch wenn es etwas mehr Resourcen verbraucht.&lt;br /&gt;
;Modulare Programmierung: Funktionen können anhand ihres Aufgabenbereichs auf verschiedene C-Quellen &amp;amp;ndash; sogenannte ''Module'' &amp;amp;ndash; verteilt werden. Funktionen, die etwas mit dem USB-Bus anstellen, werden in einem anderen Modul sein als mathematische Funktionen. Dies erhöht die Übersichtlichkeit und vereinfacht die Entwicklung im Team.&lt;br /&gt;
;Bibliotheken: Standard-Funktionen wie das hier oft auftauchende &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; sind in Bibliotheken gespeichert. Wenn das eigene Programm übersetzt wird, dann müssen nicht mehr alle Standard-Funktionen übersetzt werden, sondern werden nur noch aus der Bibliothek gelesen und ihr Code zum Programm dazugelinkt. Die Bibliotheks-Funktionen wurden schon zu einem früheren Zeitpunkt compiliert und liegen in dieser compilerten Form in der Bibliothek. Das spart mächtig Entwicklungszeit. Man kann auch selbst solche Bibliotheken erstellen und in diversen Projekten wiederverwenden.&lt;br /&gt;
;Generische Programmierung: In C ist es möglich, einer Funktion eine andere Funktion zu übergeben. (Damit ist nicht gemeint, ihr deren ''Rückgabewert'' zu übergeben (was auch ginge), sondern ''die Funktion selbst'' wird als Parameter übergeben und kann aufgerufen werden.) Ein typisches Beispiel dafür sind Sortieralgorithmen. Einem Sortieralgorithmus kann es egal sein, ''was'' er sortiert. Er muss lediglich wissen, ''wie'' er das Zeug zu sortieren hat: aufsteigend, absteigend, als Zahl, in lexikographischer Ordnung, nach der Quersumme, Körper nach Oberfläche, Durchmesser, Gewicht oder Volumen... Diese Vergleichsfunktion, die für zwei Objekte entscheidet, welches davon &amp;quot;kleiner&amp;quot; ist, kann man dem Sortierer übergeben. Will er zwei Werte vergleichen, dann muss er nur die Vergleichsfunktion aufrufen, ohne zu wissen, was diese tut. Damit kann der Sortieralgorithmus unanhängig von den Objekten gehalten werden, mit denen er hantieren soll.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Definition==&lt;br /&gt;
&lt;br /&gt;
In der ''Definition'' der Funktion wird gesagt, welche Werte sie liefern kann, wie sie heisst (Bezeichner) und wieviele und welche Parameter sie hat. Danach folgt ihre Implementierung:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}} ({{Parameterliste}})&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 &lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
Für Funktionen, die keinen Wert zurückliefern, gibt es den speziellen Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der besagt, daß die Funktion nichts zurückgibt. Die einfachste denkbare Funktion ist eine solch void-Funktion. Sie bekommt keine Parameter, gibt nicht zurück und ihr Body ist leer:&lt;br /&gt;
 void dummy()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==return-Anweisung==&lt;br /&gt;
An jeder Stelle des Programmflusses einer Funktion kann diese mit &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; beendet werden.&lt;br /&gt;
&lt;br /&gt;
'''bei void-Funktionen:'''&lt;br /&gt;
 return;&lt;br /&gt;
'''Funktionen mit Rückgabe-Wert:'''&lt;br /&gt;
 return {{Ausdruck|}};&lt;br /&gt;
Die zweite Variante gibt an, welcher Wert zurückgegeben wird.&lt;br /&gt;
 int main (int argc, char * argv[])&lt;br /&gt;
 {&lt;br /&gt;
    if (argc &amp;lt; 2)&lt;br /&gt;
       return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
Falls die letzte Anweisung einer void-Funktion ein &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; ist, kann es auch weggelassen werden wie oben bei der Funktion &amp;lt;tt&amp;gt;dummy&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Aufruf==&lt;br /&gt;
Um die Funktion aufzurufen gibt man ihren Namen an, gefolgt von den durch Komma getrennten Argumenten in runden Klammern wie im Beispiel unten das&lt;br /&gt;
 quadrat (5) &lt;br /&gt;
Da &amp;lt;tt&amp;gt;quadrat&amp;lt;/tt&amp;gt; einen Wert liefert, kann man damit weiter rechnen wie mit einem normalen Ausdruck:&lt;br /&gt;
 if (quadrat (a) + quadrat (b) == quadrat (c))&lt;br /&gt;
    c = quadrat (quadrat (a)); {{comment|c &amp;amp;#61; a hoch 4}}&lt;br /&gt;
&lt;br /&gt;
==Rekursive Funktionen==&lt;br /&gt;
Eine Funktion die sich selbst &amp;amp;ndash; möglicheweise auch über andere Zwischenfunktionen &amp;amp;ndash; wieder selbst aufruft, wird als ''rekursive Funktion'' bezeichnet. In der Definition ist nichts besonderes zu beachten. Ist die Verschachtelungstiefe im laufenden Programm zu tief, dann gibt das natürlich Probleme, aber das gilt bei tief verschachtelten 'normalen' Funktionen abenso...&lt;br /&gt;
&lt;br /&gt;
Das Beispiel berechnet den Größten Gemeinsamen Teiler zweier Zahlen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int ggT (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
     if (0 == a)&lt;br /&gt;
        return b;&lt;br /&gt;
 &lt;br /&gt;
    return ggT (b % a, a);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Ein komplettes kleines Programm:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int quadrat (int param1)&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  zahl = param1 * param1;&lt;br /&gt;
  return zahl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl, ergebnis;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Bitte Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = quadrat (zahl);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, zahl, ergebnis);&lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, 5, quadrat (5));&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur ausserhalb von Blöcken. Geschachtelte Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen beim Aufruf die Klammern angeben werden:&lt;br /&gt;
 dummy();&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Prototypen==&lt;br /&gt;
Wie oben erwähnt, kann ein Unterprogramm an jeder beliebigen Stelle im Programm stehen. Damit ist jedoch eine Bedingung verknüpft: Das Unterprogramm muß in der Datei oberhalb des ersten Aufrufes definiert worden sein. Wenn Sie ein Unterprogramm in Zeile 10 zum ersten mal aufrufen, müssen Sie die Deklaration davor erledigt haben. Verstanden?&lt;br /&gt;
Um dies zu erreichen, gibt es zwei Möglichkeiten: &lt;br /&gt;
&lt;br /&gt;
Entweder Sie schreiben alle Unterprogramme vor &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; in die Datei. Dies muß jedoch wiederum so geschehen, dass Funktionen zum Zeitpunkt ihres Aufrufes bereits bekannt sind! &lt;br /&gt;
Wo dies nicht möglich ist (z.B. sich gegenseitig aufrufende Unterprogramme), oder wenn Sie das stört, müssen Sie Prototypen verwenden. &lt;br /&gt;
Wie definiert man nun Prototypen? Sie kopieren einfach die erste Zeile des Unterprogrammes (z.B. &amp;quot;&amp;lt;tt&amp;gt;void ausgeben (int zahl)&amp;lt;/tt&amp;gt;&amp;quot;), fügen einen Strichpunkt&amp;amp;nbsp;&amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;an und fügen es an einer geeigneten Stelle ein (so, dass alle Aufrufe später in der Datei kommen). &lt;br /&gt;
Solche Definitionen stehen gewöhnlich am Anfang der Quelldatei oder in einer Header-Datei, die eingebunden wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl);  /* Der Prototyp */&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
   ausgeben (12);&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl)   /* Die eigentliche Prozedur */&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Ausgabe: %d\n&amp;quot;, zahl);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Parameterübergabe==&lt;br /&gt;
&lt;br /&gt;
Alle Werte, die an Prozeduren und Funktionen übergeben werden, werden grundsätzlich '''kopiert'''.&lt;br /&gt;
Das hat folgende Auswirkungen:&lt;br /&gt;
&lt;br /&gt;
# Änderungen an einem Parameter in einer Funktion erscheinen ''nicht'' beim Aufrufer!&lt;br /&gt;
# Möchte man, dass eine Funktion einen Wert trotzdem dauerhaft ändern soll, so muss die Adresse des Wertes via [[#Zeiger|Zeiger]] übergeben werden.&lt;br /&gt;
# Werden [[#Strukturen|Strukturen]] übergeben, so wird von ihnen eine Kopie erstellt, was bei großen Strukturen viel Zeit und Arbeitsspeicher kostet. Deshalb wird häufig nur die Adresse von Strukturen übergeben, da die Adresse viel schneller und platzsparender als die Struktur selbst kopiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele:'''&lt;br /&gt;
 void erhoehe (int x)&lt;br /&gt;
 {&lt;br /&gt;
    x = x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe(a);&lt;br /&gt;
    {{comment|a ist immer noch 0}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Beim Aufruf von &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; wird eine Kopie des Wertes von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; (im Beispiel also 0) erstellt und der Prozedur als Parameter &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; übergeben. Weil dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat dies keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|erhoehe den Wert an der Adresse x um eins}}&lt;br /&gt;
    *x = *x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe (&amp;amp;a);&lt;br /&gt;
    {{comment|a ist jetzt 1}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Jetzt wird im Hauptprogramm mittels [[#Adress-Operator und Dereferenzierung|Adress-Operator]] &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; die Speicheradresse von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; bestimmt. Dann wird eine ''Kopie der Adresse'' an das Unterprogramm &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; übergeben. Jetzt kennt das Unterprogramm die&lt;br /&gt;
Adresse des Originals &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und kann direkt mit dem Inhalts-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&lt;br /&gt;
'''Besonderheit bei Feldern'''&lt;br /&gt;
&lt;br /&gt;
Bei der Übergabe von [[#Felder|Feldern]] gibt es eine Besonderheit. Schreibt man nämlich den Namen eines Feldes, so ist das nichts anderes als die '''Speicheradresse des ersten Elements'''.&lt;br /&gt;
Bei der Übergabe eines Feldes wird also eine Kopie der Startadresse übergeben. Somit kann das Unterprogramm auf den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 void erhoehe (int x[])&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
   int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
   erhoehe (a);&lt;br /&gt;
   {{comment|a hat jetzt folgenden Inhalte: 11, 23, 35}}&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Dass die Übergabe einer Adresse erfolgt, sieht man an folgendem Beispiel, das von der Funktionsweise '''absolut identisch''' mit dem vorhergehenden ist:&lt;br /&gt;
&lt;br /&gt;
 {{comment|Bei Parametern gibt es keinen Unterschied zwischen Zeiger und Feld}}&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
    int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
    erhoehe (a);&lt;br /&gt;
 &lt;br /&gt;
    {{comment|a hat jetzt folgenden Inhalt: 11, 23, 35}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
Die Länge des Feldes wird nicht automatisch übergeben. Dafür ist ggf. ein zusätzlicher Parameter notwendig.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Variable Argumentanzahl==&lt;br /&gt;
== Funktionen indirekt aufrufen ==&lt;br /&gt;
Siehe [[#Zeiger auf Funktionen|Zeiger auf Funktionen]]&lt;br /&gt;
&lt;br /&gt;
=Zeiger II=&lt;br /&gt;
&lt;br /&gt;
Zeiger haben wir bereits weiter oben kennen gelernt. Zeiger sind ein zentrales Konzept in C und sollen hier etwas eingehender behandelt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger-Arithmetik==&lt;br /&gt;
In C kann man den Wert eines Zeigers verändern. Betrachten wir dazu die Funktion &amp;lt;tt&amp;gt;suche_0&amp;lt;/tt&amp;gt;, die einen Zeiger auf einen &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; erhält. Die Funktion soll ab der gegebenen Adresse nach dem ersten long-Wert suchen, der 0 ist, und dessen Adresse zurückgeben:&lt;br /&gt;
 long * suche_0 (long * addr)&lt;br /&gt;
 {&lt;br /&gt;
    while (*addr != 0)&lt;br /&gt;
       addr = addr + 1;&lt;br /&gt;
 &lt;br /&gt;
    return addr;&lt;br /&gt;
 }&lt;br /&gt;
In der Bedingung der while-Schleife wird der Inhalt an der Speicherstelle &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf 0 getestet. Ist der Wert 0, dann wird die Schleife beendet und die Adresse zurückgeliefert. Ist der Wert ungleich 0, dann wird &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf den nächste long gesetzt, &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; also um 4 Bytes weitergezählt. &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ist ja ein Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, und ein &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; ist 4 Bytes lang.&lt;br /&gt;
&lt;br /&gt;
Die Bedeutung von&lt;br /&gt;
 address + n&lt;br /&gt;
ist also, die Adresse um das &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;-fache der Größe des Typs, auf den &amp;lt;tt&amp;gt;address&amp;lt;/tt&amp;gt; zeigt, zu erhöhen. Dabei ist &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; eine ganze Zahl und darf auch negativ sein.&lt;br /&gt;
&lt;br /&gt;
Hier noch ein Beispiel einer Funktion, die nach einer Person mit einer bestimmten ID sucht (für die Definition von &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; siehe [[#Strukturen|Strukturen]]). Der Parameter &amp;lt;tt&amp;gt;person&amp;lt;/tt&amp;gt; ist dabei ein Array von Strukturen. Eine Person mit der gesuchten ID muss existieren, ansonsten hat die Suchfunktion kein definiertes Verhalten.&lt;br /&gt;
 {{comment|Sucht nach einer Person mit der ID person_id}}&lt;br /&gt;
 struct Person * &lt;br /&gt;
 suche_person_id (struct Person * person, int person_id)&lt;br /&gt;
 {&lt;br /&gt;
    while (person-&amp;gt;id != person_id)&lt;br /&gt;
       person++;&lt;br /&gt;
 &lt;br /&gt;
    return person;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:1em; padding:1em; border:solid 2px #FF0040;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- Vorlage:FarbigerRahmen funzt hier net --&amp;gt;&lt;br /&gt;
Beachte, daß es nicht sinnvoll ist, zwei Zeiger zu addieren oder zu multiplizieren. Ausserdem ist das &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt; der Zeiger-Arithmetik nicht kommutativ. Eine Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, der an Adresse 1 im Speicher zeigt, wird man schreiben als&lt;br /&gt;
 (long *) 1&lt;br /&gt;
Addiert man darauf eine ganze Zahl, dann haben die entstehenden Ausdrücke unterschiedliche Werte:&lt;br /&gt;
 (long *) 1 + 2    {{comment|zeigt zu Adresse 9}}&lt;br /&gt;
 (long *) 2 + 1    {{comment|zeigt zu Adresse 6}}&lt;br /&gt;
 (long *) (1 + 2)  {{comment|zeigt zu Adresse 3}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==void-Pointer==&lt;br /&gt;
Eine besondere Art von Zeiger ist der void-Pointer&lt;br /&gt;
 void * addr;&lt;br /&gt;
Ein void-Pointer ist ein &amp;quot;Zeiger auf irgendwas&amp;quot;, dementsprechend kann er nicht dereferenziert werden, Anwenden von &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf einen solchen Zeiger gibt also einen Fehler. Ausserdem ist es nicht möglich, mit einem void-Pointer Zeigerarithmetik zu machen, weil er nicht auf eine definierte Art von Objekt zeigt. Der Vorteil eines void-Pointers ist, daß er jede Art von Zeiger aufnehmen kann.&lt;br /&gt;
&lt;br /&gt;
Dazu betrachten wir die Funktion &amp;lt;tt&amp;gt;send_buf&amp;lt;/tt&amp;gt;, die eine Adresse erhält und ab dieser Adresse &amp;lt;tt&amp;gt;num&amp;lt;/tt&amp;gt; Bytes versenden soll. Wir könnten die Funktion so schreiben:&lt;br /&gt;
 void send_buf (unsigned char * buf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   ...&lt;br /&gt;
Das ist jedoch hässlich, wenn wir damit etwas anderes verschicken wollen als &amp;lt;tt&amp;gt; unsigned char&amp;lt;/tt&amp;gt;, etwa eine Struktur wie &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; (vom Typ &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;):&lt;br /&gt;
 send_buf ((unsigned char*) &amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
Ohne den Cast der Adresse von &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; zu einem Zeiger auf &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt; bekommt man eine Warnung oder gar einen Compilerfehler.&lt;br /&gt;
Dieses Zeiger gecaste ist mühsam und hässlich, es muss bei jedem Aufruf der Funktion explizit hingeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Besser ist es, den ersten Parameter der Funktion als void-Pointer zu definieren und den Cast in der Funktion zu machen:&lt;br /&gt;
 void send_buf (void * vbuf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   unsigned char *buf = (unsigned char*) vbuf;&lt;br /&gt;
   ...&lt;br /&gt;
Durch den Cast in der Funktion kann auf den Inhalt des Zeigers zugegriffen werden. Man muss nur festlegen, ''wie'' man zugreifen will, nämlich als &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Der Aufruf kann jetzt ohne Pointer-Cast erfolgen: &lt;br /&gt;
 send_buf (&amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
&lt;br /&gt;
==Null-Pointer==&lt;br /&gt;
==Zeiger als Parameter==&lt;br /&gt;
Wenn Sie ein Unterprogramm aufrufen, können Sie diesem Parameter übergeben, aber keine Werte zurückgekommen (außer den Funktionswert bei Funktionen). Dies hat einen guten Grund: beim Aufruf werden nicht die aufgerufenen Parameter benutzt, sondern es werden deren Werte in neue Variablen kopiert. Diese Variablen werden am Ende des Unterprogrammes &amp;quot;zerstört&amp;quot;, ohne ihre Werte an die aufrufenden Parameter zu übergeben. Jede Veränderung eines Parameters hat daher keine Auswirkung auf den Parameter.&lt;br /&gt;
&lt;br /&gt;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der C-Compiler legt dann immer noch Kopien an. In dieser Kopie steht aber kein Wert, sondern die Adresse einer Varaiblen. Und auf diese können Sie dann zugreifen. Denken Sie nur an &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; &amp;amp;ndash; da übergeben Sie ja auch die Adresse einer Variablen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void erhoehe (int *zeiger)&lt;br /&gt;
{&lt;br /&gt;
  *zeiger = 1 + *zeiger;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  erhoehe (&amp;amp;zahl);&lt;br /&gt;
  printf (&amp;quot;\nDie erhoehte Zahl lautet: %d\n&amp;quot;, zahl);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Zeiger auf Funktionen==&lt;br /&gt;
&lt;br /&gt;
Stell dir vor, du willst einen Sortieralgorithmus wie Bubble-Sort oder Quick-Sort oder wie sie alle heissen implementieren. Für den Sortieralgorithmus ist eigentlich egal, ''was'' er zu sortieren hat. Ihm ist es egal, ob er Zahlen aufwärts sortieren soll oder Strings in lexikographischer Reihenfolge, ob Objekte nach Größe oder Gewicht, Personen nach Alter oder Adressen nach Postleitzahl. Das einzige, was der Algorithmus wissen muss, ist ''wie'' er zwei Objekte zu vergleichen hat und wann eines davon &amp;quot;kleiner&amp;quot; (im Sinne der Ordnung, nach der sortiert werden soll) ist. &lt;br /&gt;
&lt;br /&gt;
Eine einfache Sortierfunktion, die nur zwei Zahlen sortiert, könnte man also so schreiben: &lt;br /&gt;
 {{comment|Sortiert ein Array von 2 int-Zeigern nach den Inhalten &lt;br /&gt;
  * an den Zeiger-Adressen}}&lt;br /&gt;
 void sort2_a (int * p[])&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Inhalte vergleichen...}}&lt;br /&gt;
    if (*p[0] &amp;gt; *p[1])&lt;br /&gt;
    {&lt;br /&gt;
       {{comment|... und ggf. Dreieckstausch der 2 Zeiger}}&lt;br /&gt;
       int * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Die Funktion bekommt ein Array der Länge&amp;amp;nbsp;2. In diesem Array stehen Zeiger auf die zu sortierenden Zahlen. Ein Array mit Zeigern zu verwenden und nicht ein Array von &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; scheint recht umständlich, und das ist es hier auch. Aber stell dir vor, du willst Strukturen wie &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; sortieren. Das Tauschen zweier Strukturen würde bedeuten, ihre kompletten Inhalte umzukopieren! Das wäre sehr aufwändig. Viel einfacher ist das Kopieren, wenn nur die Adressen zu kopieren sind.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; könnte dann so aussehen:&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void sortiere (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|p[] enthält 2 int-Zeiger: die Adressen von a und b}}&lt;br /&gt;
    int * p[2];&lt;br /&gt;
    p[0] = &amp;amp;a; &lt;br /&gt;
    p[1] = &amp;amp;b; &lt;br /&gt;
 &lt;br /&gt;
    {{comment|Sortiere die Zeiger}} &lt;br /&gt;
    sort2_a (p);&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Sortiert: %d, %d\n&amp;quot;, *p[0], *p[1]);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Für den nächsten Schritt überlegen wir uns, daß das Array in &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; ebensogut void-Pointer enthalten kann. Die einzige Stelle, an der wir auf die endgültigen int-Objekte zugreifen, ist der Vergleich. Diesen Vergleich lagern wir in die Funktion &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; aus:&lt;br /&gt;
 {{comment|Bekommt zwei void-Pointer und vergleicht die Inhalte.&lt;br /&gt;
  * Liefert 0 bei Gleichheit,&lt;br /&gt;
  * -1 wenn der erste Wert kleiner ist als der zweite und&lt;br /&gt;
  * 1  wenn der erste Wert größer ist als der zweite}}&lt;br /&gt;
 int compare_int (void * p0, void * p1)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Um über die Zeiger zugreifen zu können müssen wir diese&lt;br /&gt;
     * erst zu int-Zeigern casten}}&lt;br /&gt;
    int a0 = * (int*) p0;&lt;br /&gt;
    int a1 = * (int*) p1;&lt;br /&gt;
 &lt;br /&gt;
    if (a0 &amp;gt; a1)  return  1;&lt;br /&gt;
    if (a0 &amp;lt; a1)  return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void sort2_b (void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare_int (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Ein Aufruf von &amp;lt;tt&amp;gt;sort2_b&amp;lt;/tt&amp;gt; sieht dann genauso aus wie ein Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt definieren wir uns den neuen Datentyp &amp;lt;tt&amp;gt;comparator_t&amp;lt;/tt&amp;gt;. Dieser ist ein Zeiger auf eine Funktion, die zwei void-Pointer erhält und einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; zurückliefert, also analog arbeitet zu &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; von oben. &lt;br /&gt;
&lt;br /&gt;
Unsere Sortierfunktion bekommt nun neben dem zu sortierenden Zeiger-Array auch eine Vergleichsfunktion &amp;lt;tt&amp;gt;compare&amp;lt;/tt&amp;gt; mitgeliefert, die sie aufruft, wenn sie zwei Objekte vergleichen will&lt;br /&gt;
 {{comment|comparator_t sind Zeiger auf Funktionen, die 2 void-Pointer&lt;br /&gt;
  * erhalten und einen int zurückliefern}}&lt;br /&gt;
 typedef int (*comparator_t) (void*, void*);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Der Sortierer bekommt einen Funktionszeiger auf den Vergleicher.&lt;br /&gt;
  * Der Aufruf vom compare geht so als wäre es eine &amp;quot;normale&amp;quot; Funktion&lt;br /&gt;
  * (ist es im Endeffekt ja auch)}}&lt;br /&gt;
 void sort2_c (comparator_t compare, void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Bei einem Aufruf von &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; muss man dann einen Komparator mit angeben. In einem Beispiel analog zu &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; von oben ist das:&lt;br /&gt;
 sort2_c (compare_int, p);&lt;br /&gt;
Um zwei Strings lexikographisch zu sortieren nehmen wie die Standard-Funktion &amp;lt;tt&amp;gt;strcmp&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void foo()&lt;br /&gt;
 {&lt;br /&gt;
    char * worte[] = { &amp;quot;Wort1&amp;quot;, &amp;quot;Wort2&amp;quot; };&lt;br /&gt;
 &lt;br /&gt;
    sort2_c ((comparator_t) strcmp, (void**) worte);&lt;br /&gt;
 }&lt;br /&gt;
Die Casts sind hier erforderlich. Alternativ könnte man &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; mit reinen void-Pointern versorgen und diese dann dort umcasten.&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
&lt;br /&gt;
Die Syntax zur Definition/Deklaration von Funktionszeigern ist etwas verzwackt. Zur Verdeutlichung ein paar Beispiele. Dabei legt das linke &amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt; jeweils den Return-Typ fest.&lt;br /&gt;
 {{comment|definiert einen neuen Funktionszeiger-Typ}}&lt;br /&gt;
 typedef {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert einen Funktionszeiger}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert ein Array von Funktionszeigern (mit Initializer)}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}[]) ({{type}}, {{type}}, ...) = { wert1, wert2, ... };&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer}}&lt;br /&gt;
 ({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer und ruft die Funktion auf}}&lt;br /&gt;
 (({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}) (arg1, arg2, ...);&lt;br /&gt;
&lt;br /&gt;
=Standard-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==String-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===strcpy===&lt;br /&gt;
Bei vielen Compilern können sie einem String nicht direkt einen Wert (Text) zuweisen. Dazu müssen Sie dann die Prozedur strcpy() benutzen. Diese erwartet als ersten Parameter den Namen einer String-Variablen (ohne eckige Klammern) und als zweiten Parameter den eines (anderen) Strings. Letzterer kann auch ein in doppelten Hochkommas (&amp;quot;) eingeschlossener Text sein. Die Funktion fügt am Ende automatisch ein 0-Zeichen ein. Um diese Funktion nutzen zu können, müssen Sie die Datei string.h includieren! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri1[21], eingabe[21];&lt;br /&gt;
&lt;br /&gt;
  strcpy (stri1, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Der 1. String: %s\n&amp;quot;, stri1);&lt;br /&gt;
  printf (&amp;quot;Bitte geben Sie maximal 20 Zeichen ein: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%s&amp;quot;, eingabe);&lt;br /&gt;
  strcpy (stri1, eingabe);&lt;br /&gt;
  printf (&amp;quot;\n%s = %s&amp;quot;, stri1, eingabe);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis:''' &lt;br /&gt;
Da ein String, wie jedes Feld, eigentlich ein Zeiger ist, dürfen Sie kein &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; bei &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; angeben!&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
Es werden zwei gleich große Strings definiert: &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;eingabe&amp;lt;/tt&amp;gt;, mit je 20 &amp;quot;nutzbaren&amp;quot; Zeichen. &lt;br /&gt;
In &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; wird die Zeichenkette &amp;lt;tt&amp;gt;&amp;quot;hallo&amp;quot;&amp;lt;/tt&amp;gt; hineinkopiert. Das 0-Zeichen am Ende wird automatisch angefügt. &lt;br /&gt;
Der String wird ausgegeben. Als neues &amp;quot;Sonderzeichen&amp;quot; kommt &amp;lt;tt&amp;gt;%s&amp;lt;/tt&amp;gt; ins Spiel. Es hat die gleiche Aufgabe wie &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt;, nur für Strings. &lt;br /&gt;
Sie werden gebeten, eine String einzugeben. &lt;br /&gt;
Dieser String wird danach in die Variable &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; kopiert. &lt;br /&gt;
Beide Strings, die ja nun die gleiche Zeichenkette enthalten, werden ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===strlen===&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;strlen&amp;lt;/tt&amp;gt;, die als Parameter eine String-Variable erwartet, liefert die Länge diese Strings zurück. Sie werden jetzt vermutlich sagen: &amp;quot;Das ist doch klar, wie lang der String ist. Ich habe es ja bei der Deklaratin angegeben&amp;quot;. Das stimmt schon, aber denken Sie noch einmal an die null-terminierten Strings. Das 0-Zeichen steht am Ende des Strings (am Ende der gültigen Zeichenfolge), aber nicht unbedingt am Ende des reservierten Speicherplatzes. Haben Sie eine Variable &amp;quot;char Variable[21];&amp;quot;, und ihr den Wert &amp;quot;hallo&amp;quot; zugewiesen, dann steht das null-Zeichen in Variable[5]. Der &amp;quot;gültige&amp;quot; String ist also 5 Zeichen (0-4) lang. Und genau das (5) würde strlen zurück liefern. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri[21];&lt;br /&gt;
  &lt;br /&gt;
  strcpy (stri, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
  printf (&amp;quot;Der String ist %d Zeichen lang&amp;quot;, strlen (stri));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird vor allem gebraucht, wenn Sie direkt auf den String zugreifen, mittels &amp;lt;tt&amp;gt;stri[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;stri[1]&amp;lt;/tt&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
==Ein- und Ausgabe-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===Bildschirm-Ausgabe===&lt;br /&gt;
Bisher war das Tutorial trotz aller Beispiele reine Theorie. Sie konnten zwar Programme schreiben, aber die Funktion nicht testen. Hier lernen Sie nun, wie Sie etwas am Bildschirm ausgeben.&lt;br /&gt;
&lt;br /&gt;
Die dazu notwendige Funktione heisst &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (das '&amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt;' ist kein Fehler!). Diese Anweisung gibt die ihr übergebenen Parameter auf das Standard-Ausgabegerät aus, in der Regel also auf den Bildschirm. Sie kann beliebig viele Parameter übernehmen. Es müssen jedoch Standard-Datentypen (z.B. &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;...) sein! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
    int zahl1 = 12;&lt;br /&gt;
    char zeichen1 = 'A';&lt;br /&gt;
    &lt;br /&gt;
    printf (&amp;quot;Das ist Text, und er wird als solcher ausgegeben. \n&amp;quot;);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zahl1' ist: %d \n&amp;quot;, zahl1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %c \n&amp;quot;, zeichen1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %d \n&amp;quot;, zeichen1);&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt Text aus. Das Zeichen am Ende (&amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;) bedeutet &amp;quot;New Line&amp;quot;, es bewegt den Cursor an den Anfang der nächsten Zeile. &lt;br /&gt;
&lt;br /&gt;
Der zweite &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt auch Text aus, am Ende befindet sich wieder das &amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;, um einen Zeilenvorschub zu erreichen. Das &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; wird vom Compiler durch den ersten Parameter ersetzt, der nach dem Text angegeben wird. In diesem Fall wird &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; also durch den Wert der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ersetzt. Das &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; im &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; bedeutet &amp;quot;Dezimalzahl&amp;quot;, der Computer gibt also eine ganze Zahl aus. &lt;br /&gt;
&lt;br /&gt;
In der dritten Ausgabe wird ein Zeichen ausgegeben. Diesmal bedeutet &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; &amp;quot;char&amp;quot; (Zeichen). Es wird also &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; durch ein &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt; ersetzt, denn die Variable &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; wird als Character interpretiert. &lt;br /&gt;
&lt;br /&gt;
Die letzte Ausgabe interpretiert den Inhalt von &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; als Zahl, und gibt dager den ASCII-Wert von &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, also 65 aus. Das ist ein typisches Beispiel für das mögliche unterschiedliche Interpretieren einer  Variablen!&lt;br /&gt;
&lt;br /&gt;
===Tastatur-Eingabe===&lt;br /&gt;
&lt;br /&gt;
Um ein &amp;quot;gscheites&amp;quot; Programm schreiben zu können, muß man wissen, wie der Benutzer über die Tastatur Befehle eingeben kann. Die dafür notwendigen Funktionen stelle ich in diesem Kapitel vor.&lt;br /&gt;
Die wichtigste Funktion ist &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt;. Er liest Daten von der Tastatur. Die Syntax entspricht derer von &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int  zahl1;&lt;br /&gt;
char zeichen1;&lt;br /&gt;
&lt;br /&gt;
printf (&amp;quot;Bitte geben Sie eine Zahl ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl1);&lt;br /&gt;
printf (&amp;quot;Geben Sie einen Zeichen ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%c&amp;quot;, &amp;amp;zeichen1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Programm gibt eine Eingabeaufforderung aus. Dann erwartet es vom Benutzer, daß er eine Zahl eingibt, die mit [ENTER] bestätigt wird. Dieser Wert wird in &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; abgespeichert. Danach erfolgt wiederum eine Aufforderung zur Eingabe, diesmal eines einzelnen Zeichens. Dieses kann man nun eingeben und ebenfalls mit [ENTER] bestätigen.&lt;br /&gt;
&lt;br /&gt;
Macht man keine dem Datentyp der erwarteten Variable entsprechende Eingabe, dann bricht das Programm mit einer Fehlermeldung ab (wenn man z.B. &amp;quot;1_T2&amp;quot; eingibt, wenn eine Zahl erwartet wird)!&lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; vor den Parametern ist notwendig. Warum, das erfahren Sie im Kapitel &amp;quot;Unterprogramme&amp;quot;. Für die Profis eine Kurz-Erklärung: Das Unterprogramm &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; bekommt zwar einen Wert übergeben, kann aber keinen zurückliefern (&amp;quot;call by value&amp;quot;). Daher wird kein Wert, sondern ein Zeiger auf eine Variable übergeben. Mit dem &amp;amp; Zeichen bekommen Sie die Adresse einer Variablen (&amp;quot;call by reference&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=Parameter von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;=&lt;br /&gt;
Das Unterprogramm &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; kann, wie jede andere Funktion, Parameter besitzen. Doch keine selbst gewählten, sondern nur bestimmte. Doch warum braucht main Parameter? Denken Sie einmal an alle Betriebssystembefehle:&lt;br /&gt;
&amp;lt;tt&amp;gt;dir *.exe &amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;copy *.* a:&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;ls -la &amp;lt;/tt&amp;gt;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;&amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen!&lt;br /&gt;
&lt;br /&gt;
=Kurzreferenz=&lt;br /&gt;
==Syntax-Bausteine==&lt;br /&gt;
&lt;br /&gt;
Die Erklärung des Aufbaus von C-Befehlen erfolgt neben einfachen Beispielen auch durch ihren prinzipellen Aufbau. In diesen Syntax-Beschreibungen finden sich immer wieder die gleichen Bausteine, die hier näher erklärt werden sollen. Falls die solch ein Syntax-Baustein begegnet, kannst Du ihn anclicken und kommst dann zu seiner Erläuterung. &lt;br /&gt;
&lt;br /&gt;
In den Beispielen selbst gehören auch die spitzen Klammern zu dem Baustein (was daran zu erkennen ist, daß auch die Klammern eingefärbt sind). Die Klammern dürfen in einem konkreten C-Programm daher nicht eingetippt werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bezeichner&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Bezeichner in C dienen dazu, Variablen zu identifizieren und ihnen sprechende Namen zu geben, um die Quelle lesbarer zu machen. Man braucht Bezeichner auch, um selbstdefinierte Datentypen zu benennen und zum Benennen von Struct- und Union-Komponenten sowie als Namen für Funktionen und Sprungmarken (Labels).&lt;br /&gt;
&lt;br /&gt;
Bezeichner dürfen aus den Kleinbuchstaben &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;z&amp;lt;/tt&amp;gt;, den Großbuchstaben &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;Z&amp;lt;/tt&amp;gt;, dem Unterstrich&amp;amp;nbsp;&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt; und den Ziffern &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;9&amp;lt;/tt&amp;gt; aufgebaut werden, wobei an erster Stelle jedoch keine Ziffer stehen darf.&lt;br /&gt;
&lt;br /&gt;
Es wird zwischen Groß- und Kleinschreibung unterschieden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Ausdruck in C ist ein Konstrukt, das einen Wert hat. Ob dieser Wert eine ganze Zahl ist, eine Kommazahl oder ein Zeiger, etc. ist dabei egal. Die einfachsten Ausdrücke sind Konstanten wie&lt;br /&gt;
 2&lt;br /&gt;
oder Variablen wie&lt;br /&gt;
 ein_zahl&lt;br /&gt;
Mehrere Ausdrücke können durch [[#Liste der Operatoren|Operatoren]] zu komplexeren Ausdrücken kombiniert werden, etwa&lt;br /&gt;
 eine_zahl + andere_zahl == 2&lt;br /&gt;
oder &lt;br /&gt;
 eine_zahl = 2&lt;br /&gt;
Letzterer hat den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; und den Nebeneffekt, daß er diesen Wert an &amp;lt;tt&amp;gt;eine_zahl&amp;lt;/tt&amp;gt; zuweist.&lt;br /&gt;
&lt;br /&gt;
Auch der Aufruf einer Funktion, die einen Rückgabewert liefert, ist ein Ausdruck:&lt;br /&gt;
 sin (1.2)&lt;br /&gt;
und kann zum Aufbau komplexerer Ausdrüche verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bedingung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Bedingung ist ein Ausdruck, bei der nur interessiert, ob dieser zu&amp;amp;nbsp;0 (unwahr) auswertet oder zu ungleich&amp;amp;nbsp;0 (wahr). Solche Ausdrücke findet man in if-Anweisungen, in Schleifenbedingungen und bedingten Zuweisungen&lt;br /&gt;
 (ein_wert &amp;lt; 2) || (ein_wert &amp;gt; 40)&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Lvalue ist ein Ausdruck, dem etwas zugewiesen werden kann. Der Name ''Lvalue'' kommt aus dem Englischen. Das ''L'' steht abkürzend für left. Ein Lvalue ist damit ein Ausdruck, der auf der linken Seite eine Zuweisung in C stehen darf. Das &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; in den folgenden Beispiel-Ausdrücken muss ein Lvalue sein:&lt;br /&gt;
 x = y-1&lt;br /&gt;
&lt;br /&gt;
 x++&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Konstante&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Konstante ist ein Ausdruck, dessen Wert dem Compiler bekannt ist. Beispiele für Konstanten sind etwa&lt;br /&gt;
 7&lt;br /&gt;
 'B'&lt;br /&gt;
 -13.98e12&lt;br /&gt;
 1+(2*3)&lt;br /&gt;
und die Werte von [[#Enum|Enum]]s. &lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; aus dem folgenden Codestück definiert jedoch keine Konstante in diesem Sinne&lt;br /&gt;
 const double Pi = 3.14159256;&lt;br /&gt;
denn in einem anderen Quellmodul könnte durch die Deklaration&lt;br /&gt;
 extern const double Pi;&lt;br /&gt;
das Symbol &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; bekannt sein, ohne daß sein Wert bekannt ist!&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Adresse&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Adresse ist ein Ausdruck, der einen Speicherort (physikalisch oder virtuell) halten kann. Adressen erhält man dadurch, daß man einem Bezeichner den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt;voranstellt, Adressen durch Arithmetik berechnet oder Zahlen zu Adressen castet. Folgende Ausdrücke sind Adressen (eine sinnvolle Deklaration der auftretenden Variablen vorausgesetzt)&lt;br /&gt;
 &amp;amp; eine_zahl&lt;br /&gt;
 &amp;amp; ein_array[10]&lt;br /&gt;
 &amp;amp; ein_struct&lt;br /&gt;
 &amp;amp; ein_struct.komponente&lt;br /&gt;
 (int *) 0x1234&lt;br /&gt;
 (int *) eine_zahl&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Deklaration&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Anweisungen sind gewissermassen die Atome (oder Moleküle?), aus denen ein C-Programm besteht. Jedes C-Programm ist eine Abfolge von Deklarationen und Anweisungen. Einfache Anweisungen erhält man, in dem man einen Ausdruck nimmt und einen Strichpunkt dahinter schreibt:&lt;br /&gt;
 {{Ausdruck|}};&lt;br /&gt;
wie in&lt;br /&gt;
 x = x+1;&lt;br /&gt;
&lt;br /&gt;
Andere Anweisungen sind die unten aufgeführten Schleifen und die if- sowie die switch-Anweisung.&lt;br /&gt;
&lt;br /&gt;
Mehrere Deklarationen und Anweisungen können zu einem Block zusammengefasst werden. Dieser Block stellt dann wieder eine einzelne Anweisung dar und kann genau so gehandhabt werden!&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
In diesem Sinne ist auch z.B. die Syntax der if-Anweisung zu verstehen&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
besagt, daß der abhängig ausgeführte Code eine einzelne Anweisung sein darf oder eben ein kompletter Block oder die Verschachtelung mehrerer Blöcke etc.&lt;br /&gt;
&lt;br /&gt;
Eine Anweisung kann auch &amp;quot;leer&amp;quot; sein, also nichts tun. Diese Anweisungen sind der leere Block&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
und der Strichpunkt&lt;br /&gt;
 ;&lt;br /&gt;
die man gelegentlich in Schleifen findet:&lt;br /&gt;
 while (!timeout())&lt;br /&gt;
    {}&lt;br /&gt;
oder hinter Sprungmarken, die sonst direkt vor einer schliessenden Blockklammer stünden:&lt;br /&gt;
 {&lt;br /&gt;
    ...&lt;br /&gt;
    goto ein_label;&lt;br /&gt;
    ...&lt;br /&gt;
    {{Label|ein_label}}:;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Nicht jede Anweisung ist an jeder Stelle eines C-Programms erlaubt, so darf ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; nut innerhalb einer Schleife stehen. Gleiches gilt für &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;, das aber auch innerhalb eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; vorkommen darf.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Dies steht für einen Datentyp. Es kann ein elementarer Typ sein wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;, ein Zeiger darauf wie &amp;lt;tt&amp;gt;char*&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;void*&amp;lt;/tt&amp;gt;, und auch Qualifier enthalten wie das &amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt; im Typ &amp;lt;tt&amp;gt;unsigned long long&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Zu den Typen gehören auch zusammengesetzte Datentypen wie Strukturen und Unions, mit &amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt; selbst definierte Typen und natürlich Zeiger darauf, wie aus dem Abschnitt [[#Datentypen|Datentypen]]:&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person *&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;data32_t&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;&lt;br /&gt;
und Zeiger auf Funktionen.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Parameterliste&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
Die Parameterliste bei einer Funktionsdefinition gibt an, wieviel Übergabeparameter sie bekommt, wie diese heissen und welchen Typs diese sind. Der prinzipielle Aufbau ist&lt;br /&gt;
 {{Type}} {{Bezeichner}}, {{Type}} {{Bezeichner}}, ...&lt;br /&gt;
Falls die Funktion keine Parameter hat, dann ist die Parameterliste leer.&lt;br /&gt;
&lt;br /&gt;
Hier als Beispiel die zweiparametrige Funktion &amp;lt;tt&amp;gt;produkt&amp;lt;/tt&amp;gt;. Der erste Parameter heisst&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und ist ein &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;. Der zweite namens&amp;amp;nbsp;&amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; ist vom Typ &amp;quot;Zeiger auf double&amp;quot;, der Inhalt &amp;lt;tt&amp;gt;*b&amp;lt;/tt&amp;gt; ist also auch ein double.&lt;br /&gt;
&lt;br /&gt;
'''Definition der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b)&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
In älteren C-Quellen findet man noch eine andere Syntax für die Deklaration der Parameter, die aber heute praktisch nicht mehr verwendet wird:&lt;br /&gt;
'''alte Definition der Funktion:'''&lt;br /&gt;
 double produkt (a, b)&lt;br /&gt;
 double a, *b;&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Um die Funktion bekannt zu machen, werdendet man eine Deklaration bzw. den Prototypen, der dem Compiler nur mitteilt, welche Parameter die Funktion bekommt und was sie zurückliefert. Für den Aufruf der Funktion muss der Compiler nur diesen Prototyp kennen, ''was'' die Funktion im Endeffekt macht und wie sie implementiert wurde ist egal, sie wird als BlackBox angesehen.&lt;br /&gt;
&lt;br /&gt;
'''Prototyp der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b);&lt;br /&gt;
Hier dürfen die Bezeichner auch fehlen:&lt;br /&gt;
 double produkt (double, double*);&lt;br /&gt;
&lt;br /&gt;
==if==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==if-else==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==for==&lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Eine for-Schleife entspricht folgendem Konstrukt. Dabei sind die drei Ausdrücke optional. Fehlt die Bedingung, dann wird diese als &amp;quot;wahr&amp;quot; angenommen. Die beiden anderen Ausdrücke wird man als Ausdrücke mit Nebeneffekt wählen wie z.B. &amp;lt;tt&amp;gt;x=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;x=x-2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
 {&lt;br /&gt;
    {{Ausdruck|1}};&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_loop}}:&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
    else&lt;br /&gt;
       goto _break;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_continue}}:&lt;br /&gt;
    {{Ausdruck|2}};&lt;br /&gt;
    goto _loop;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_break}}:;&lt;br /&gt;
 }&lt;br /&gt;
Die Labels &amp;lt;tt&amp;gt;_break&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_continue&amp;lt;/tt&amp;gt; entsprechen den Sprungzielen einer &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Anweisung innerhalb von &amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==do-while==&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while  ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
==while==&lt;br /&gt;
 while  ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==switch==&lt;br /&gt;
 switch  ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    ...&lt;br /&gt;
  &lt;br /&gt;
    default:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#break-Anweisung|&amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Konstanten|&amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#continue-Anweisung|&amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#do-while-Schleife|&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Enum|&amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#for-Schleife|&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#goto-Anweisung|&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#return-Anweisung|&amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Liste der Operatoren|sizeof]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Strukturen|&amp;lt;tt&amp;gt;struct&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Eigene Datentypen|&amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Unions|&amp;lt;tt&amp;gt;union&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#while-Schleife|&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund2}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Arithmetische Operatoren&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Dies sind die &amp;quot;normalen&amp;quot; arithmetischen Operationen, wie man sie aus der Schule kennt. Man kann damit und allen anderen Operatoren auch komplexere Ausdrücke aufbauen. Die Prioritäten sind so, wie man sie kennt, also &amp;quot;Punktrechnung vor Strichrechnung&amp;quot;. Will man dies ändern, dann mit den runden Klammern:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;1+2*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 7&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(1+2)*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 9&amp;lt;br/&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}}&amp;amp;nbsp;+&amp;amp;nbsp;{{Ausdruck|}}&amp;lt;/tt&amp;gt; || Addition&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} - {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Subtraktion&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} * {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Multiplikation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} / {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Division&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} % {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Rest der Division (modulo)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;- {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Vorzeichenumkehr, Zweier-Komplement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Logische Operatoren und Vergleiche&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die logischen und die vergleichenden Operatoren liefern als Ergebnis den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (wahr) oder einen Wert ungleich&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (falsch, um genau zu sein den Wert &amp;lt;tt&amp;gt;!0&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Man kann das Ergebnis zwar einer Variablen zuweisen, in aller Regel wird man solche Ausdrücke jedoch in Bedingungen zu &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder in Abbruch-Bedingungen von Schleifen finden.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;&amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches AND: beides wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124;&amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches OR: mind. eines ist wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;! {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches NOT (0 &amp;amp;harr; ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} == {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} != {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist nicht gleich&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bitweise Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~ {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise NOT (Einser-Komplement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise AND&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise ODER&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} ^ {{Ausdruck|}}&amp;lt;/tt&amp;gt; ||bitweise XOR&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Shift-Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;lt;&amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Bits nach links schieben&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;gt;&amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Schieben nach rechts schieben&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Typen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Ein Cast in C kann dazu verwendet werden, den Typ eines Ausdruckes zu ändern oder den Ausdruck mit einer bestimmten Genauigkeit zu berechnen. Wird z.B. eine Berechnung standardmässig in 16 Bit ausgeführt, dann kann man mit einem Cast &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(long) &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
ausdrücken, daß die Berechnung in 32 Bit erfolgen soll. Des weiteren kann man Zeiger und ganze Zahlen und Gleitkommazahlen ineinander umwandeln.&lt;br /&gt;
&lt;br /&gt;
Casts können ''nicht'' dazu verwendet werden, um z.B. eine Zahl in einen String zu konvertieren, der diese Zahl darstellt! Dafür gibt es spezielle Funktionen wie &amp;lt;tt&amp;gt;itoa&amp;lt;/tt&amp;gt;!&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Type}}) {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Cast, Typwandlung&lt;br /&gt;
|-&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;| &amp;lt;tt&amp;gt;sizeof ({{Type}})&amp;lt;/tt&amp;gt; || Eine Konstante, deren Wert die Größe (in Bytes) des Typs ist. &amp;lt;tt&amp;gt;sizeof&amp;lt;/tt&amp;gt; ist auch auf Objekte anwendbar wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, Arrays bekannter Größe, Strukturen und Unions,  Array-, Struktur- und Union-Komponenten, Pointer, etc. Beispiel:&amp;lt;br/&amp;gt;&lt;br /&gt;
 int i, sum=0, array[] = { 1, -13, 4, 0, sizeof (int*) };&lt;br /&gt;
 &lt;br /&gt;
 for (i=0; i&amp;lt; sizeof (array) / sizeof (array[0]); i++)&lt;br /&gt;
    sum += array[i];&lt;br /&gt;
Alle Elemente des Arrays werden aufaddiert, ohne daß deren Anzahl explizit in der Schleife genannt ist.&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zeiger und Adressen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;* {{Adresse}}&amp;lt;/tt&amp;gt; || der Inhalt an Adresse&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp; {{Lvalue}}&amp;lt;/tt&amp;gt; || Adresse von&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Strukturen, Unions, Arrays&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Struct&amp;gt;}}.{{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Zeiger-auf-Struct&amp;gt;}} -&amp;gt; {{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union, deren Adresse man hat&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Adresse}}&amp;amp;#91;{{Ausdruck|}}&amp;amp;#93;&amp;lt;/tt&amp;gt; || Array-Element&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bedingte Auswertung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Bedingung}}) ? {{Ausdruck|}} : {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Auswahl des Wertes abhängig von der Bedingung&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zuweisung und Operatoren mit Nebeneffekt&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die Unterschiede der post- und pre-Varianten der Increment/Decrement kommen in Konstrukten wie &amp;lt;tt&amp;gt;x = *p++&amp;lt;/tt&amp;gt; zum tragen:&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *p++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; p = p+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *++p;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; p = p+1; x = *p;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = (*p)++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; *p = (*p)+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = ++(*p);&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; *p = (*p)+1; x = *p;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} = {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Zuweisung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++ {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-- {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Decrement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ++&amp;lt;/tt&amp;gt; || Post-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} --&amp;lt;/tt&amp;gt; || Post-Decrement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Kurzschreibweisen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Für ganz Faule gibt es anstatt&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a = a @ b&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
für viele Operatoren (hier dargestellt durch ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;@&amp;lt;/tt&amp;gt;) die abkürzende Schreibweise&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a @= b&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} += {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} -= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} *= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} /= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} %= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ^= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;lt;&amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;gt;&amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Autoren'''&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
* Kernighan und Ritchie - Buch&lt;br /&gt;
* Christian Wirth , C Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://wwwuser.gwdg.de/~kboehm/ebook/inhalt.html C-Programmieren unter Linux]&lt;br /&gt;
* [http://www.gdv.uni-hannover.de/documentation.php Skripte zum Selbststudium: C, C++, Java, etc]&lt;br /&gt;
* [http://info.baeumle.com/ansic.html Einführung in ANSI-C]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Quellcode C|!]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Inrfb2</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10394</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10394"/>
				<updated>2007-03-13T11:11:22Z</updated>
		
		<summary type="html">&lt;p&gt;Inrfb2: /* Reihenfolge der Auswertung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Programmiersprache C wurde 1971 als Gundlage für das Betriebssystem UNIX in den USA entwickelt (UNIX ist zu über 90% in C geschrieben). 1978 wurde von Brian Kernighan und Dennis Ritchie eine eindeutige Sprachdefinition entwickelt. Mittlerweile ist C von ANSI und ISO standardisiert.&lt;br /&gt;
&lt;br /&gt;
Heute sind C und ihr Nachfolger C++ die dominierenden Programmiersprachen. Sehr viele Anwendungen sind in C geschrieben, was inzwischen auch auf eingebettete Systeme zutrifft, die lange in Assembler programmiert werden mussten, da keine ausreichend leistungsfähigen Compiler zur Verfügung standen. &lt;br /&gt;
&lt;br /&gt;
Leider ist C nicht einfach zu lernen &amp;amp;ndash; es wurde weder von noch für Hobby-Programmierer entwickelt &amp;amp;ndash; und eignet sich daher nur bedingt für den Einsteiger. Mit etwas Übung und einem optimierenden Compiler kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
Vom Design her ist C eine Hardware-unabhängig Sprache. Das bedeutet, daß C-Programme mit vertretbarem Aufwand auf ein anderes System portiert werden können. Dazu benötigt man lediglich einen anderen Compiler, und Inline-Assembler-Anweisungen (Assembleranweisungen innerhalb eines C-Programmes) müssen der neuen Hardware (Prozessor) angepasst werden. &lt;br /&gt;
&lt;br /&gt;
==Geschichte==&lt;br /&gt;
;1971: C wird entwickelt&lt;br /&gt;
;1978: Kernighan und Ritchie definieren die Sprache.&lt;br /&gt;
;1983: ANSI und ISO standardisieren C.&lt;br /&gt;
;1992: Bjarne Stroustrup enwickelt die Nachfolgesprache C++.&lt;br /&gt;
&lt;br /&gt;
=Aufbau eines C-Programmes=&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
   C-Programme haben keinen fixen Aufbau wie z.B. Pascal. Es gibt zwar gewisse Regeln, aber sonst sind dem Programmierer alle Freiheiten überlassen. Der folgende &amp;quot;Beispiel-Aufbau&amp;quot; ist daher nicht zwingend und kann durchaus verändert werden.&lt;br /&gt;
&lt;br /&gt;
   Natürlich haben C-Programme einen fixen Aufbau! Ebenso wie Pascal-Programme auch unterliegen sie einer strikten Grammatik! &lt;br /&gt;
Auskommentiert --[[Benutzer:SprinterSB|SprinterSB]] 10:23, 17. Feb 2006 (CET)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Ein einfaches C-Programm könnte folgendermassen aussehen. Das Programm tut eigentlich nichts, aber das Beispiel zeigt den prinzipiellen Aufbau. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 int Zahl1;&lt;br /&gt;
 char Zeichen1;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int zahl2;&lt;br /&gt;
 &lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Beschreibung:'''&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndash; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
 {{comment|void-Definition von main ist nur beim Controller ueblich}}&lt;br /&gt;
 {{comment|spezielle Compilereinstellungen sind noetig, damit bei dieser Definition von main}}&lt;br /&gt;
 {{comment|kein Fehler/Warnung erzeugt wird.}}&lt;br /&gt;
 void main ()&lt;br /&gt;
 {&lt;br /&gt;
     ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
 int main (void)&lt;br /&gt;
 {  {{comment|der Block &amp;quot;main&amp;quot; beginnt}}&lt;br /&gt;
    int zahl;&lt;br /&gt;
    &lt;br /&gt;
    {   {{comment|ein Block beginnt}}&lt;br /&gt;
        {{comment|hier koennen Deklarationen und Anweisungen stehen}}&lt;br /&gt;
    }   {{comment|der Block endet}}&lt;br /&gt;
   &lt;br /&gt;
    return 0;&lt;br /&gt;
 }  {{comment|&amp;quot;main&amp;quot; endet}}&lt;br /&gt;
&lt;br /&gt;
=Datentypen=&lt;br /&gt;
==Elementare Datentypen==&lt;br /&gt;
Der Datentyp einer Variable gibt an, welche Werte eine Variable enthalten kann, welcher Art diese Daten sind und wie sie verarbeitet werden, etwa in arithmetischen Operationen wie einer Addition. So ist es zum Beispiel möglich, in eine Variable vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ganze Zahlen zwischen ca. -32000 und +32000 einzutragen. In einer char-Variable können ASCII-Zeichen gespeichert werden (alles, was Sie mit der Tastatur erzeugen können) oder ganze Zahlen von -128 bis 127.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da C plattformabhängig ist, hängt die Größe eines Datentypes zum Teil von der genutzten Hardware (z.B. 8, 16 oder 32 Bit-Controller) und dem Compiler und dessen Einstellungen ab!&lt;br /&gt;
&lt;br /&gt;
===int, char, short, long (ganze Zahlen)===&lt;br /&gt;
In Variable dieser Typen können Sie ganze Zahlen abspeichern, also z.B. 1, &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;2, 100, 12345. Jeden dieser Typen gibt es in zwei Ausprägungen: als &amp;quot;&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;quot;, also als vorzeichenbehafteten Typ, und als &amp;quot;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&amp;quot;, also ohne Vorzeichen, d.h. das Vorzeichen wird als 0 oder +1 genommen. &lt;br /&gt;
&lt;br /&gt;
Vorzeichenbehaftete Ganzzahl-Typen werden intern im &amp;lt;tt&amp;gt;n-1&amp;lt;/tt&amp;gt;-Komplement dargestellt, das Vorzeichen selbst findet sich also im höchstwertigen Bit. Werden zur Speicherung ''b'' Bits verwendet, dann reicht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;z.B. *zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==Enum==&lt;br /&gt;
&lt;br /&gt;
Über &amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt; können Aufzählungen definiert werden. Die Werte sind &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Werte und beginnen mit&amp;amp;nbsp;0. Der folgende enum hat einen um&amp;amp;nbsp;1 grösseren Wert. Mit einer Zuweisung können auch andere Werte zugeordnet werden. Klarer wird's im Beispiel:&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 enum Farben&lt;br /&gt;
 {&lt;br /&gt;
    ROT,&lt;br /&gt;
    GRUEN,&lt;br /&gt;
    BLAU,&lt;br /&gt;
    BRAUN = 5,&lt;br /&gt;
    SCHWARZ&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
Dies definiert die Konstanten &amp;lt;tt&amp;gt;ROT=0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;GRUEN=1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BLAU=2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BRAUN=5&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;SCHWARZ=6&amp;lt;/tt&amp;gt; und den Typ &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void foo (enum Farben farbe)&lt;br /&gt;
{&lt;br /&gt;
   switch (farbe)&lt;br /&gt;
   {&lt;br /&gt;
      case ROT:&lt;br /&gt;
         ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit kann man anstatt &amp;quot;magischer&amp;quot; Zahlen sprechende Namen im Code verwenden, etwa in Berechnungen und Zuweisungen, Vergleichen oder als Konstante hinter einem &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zusammengesetzte Datentypen==&lt;br /&gt;
===Arrays===&lt;br /&gt;
Oft muß man sehr viele Werte gleichzeitig abspeichern und betrachten, die alle der selben Aufgabe dienen. Man schreibt z.B. ein Programm, das 10 Zahlen einlesen und anschließend wieder ausgeben soll. Man könnte das natürlich mit 10 einzelnen Variablen bewerkstelligen, aber es ist sinnvoller, dabei Arrays &amp;amp;ndash; teilweise auch als ''Felder'' bezeichnet &amp;amp;ndash; zu verwenden.&lt;br /&gt;
&lt;br /&gt;
In einem Array werden mehrere Variablen gleichen Typs zusammengefasst und hintereinander im Speicher abgelegt. So kann man viele tausend Variablen anlegen mit nur einer Zeile Code. Doch es gibt noch größere Vorteile: Sie können das Array mit einer Schleife ganz einfach nach Werten durchsuchen. Stellen Sie sich vor, Sie müssten mit 100 verschiedenen Variablen &amp;lt;tt&amp;gt;Zahl_00&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;Zahl_99&amp;lt;/tt&amp;gt; arbeiten!&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}}&amp;amp;#91;{{Konstante}}&amp;amp;#93;;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 unsigned int werte[100];&lt;br /&gt;
&lt;br /&gt;
Der Name muß natürlich ein gültiger Bezeichner sein, als Datentyp kann jeder Typ genommen werden &amp;amp;ndash; sowohl elementare Datentypen als auch Zeiger, Strukturen, Unions oder selbst definierte Datentypen. In der eckigen Klammer wird die Anzahl der Elemente bekanntgegeben. Ein mit [3] definiertes Array hat Platz für drei Variablen. Da der Index immer bei 0 beginnt, greift man also mit &amp;lt;tt&amp;gt;[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;[1]&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;[2]&amp;lt;/tt&amp;gt; auf den jeweilige Inhalt zu. Um auf eine der im Array enthaltenen Variablen zugreifen zu können, müssen Sie den Variablennamen und in eckigen Klammern den Index (die &amp;quot;Nummer&amp;quot;) der Variablen angeben. Diese Variable verhält sich dann wie eine ganz normale Variable des jeweiligen Datentypes. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #define NZAHLEN 10&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int i;&lt;br /&gt;
    int zahlen[NZAHLEN];  {{comment|zahlen[0] ... zahlen[9]}}&lt;br /&gt;
  &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++)&lt;br /&gt;
    {&lt;br /&gt;
       printf (&amp;quot;Bitte Zahl %d eingeben: &amp;quot;, i);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; zahlen[i]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++) &lt;br /&gt;
       printf (&amp;quot;Zahl %d ist: %d\n&amp;quot;, i, zahlen[i]);&lt;br /&gt;
      &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 10 int-Variablen großes Array angelegt. &lt;br /&gt;
In dieses wird nun der Reihe nach 10 Zahlen eingelesen. &lt;br /&gt;
Anschließend werden alle 10 Zahlen ausgegeben. &lt;br /&gt;
&lt;br /&gt;
Dabei wird die Größe der Arrays und das Schleifenende über das Define &amp;quot;&amp;lt;tt&amp;gt;NZAHLEN&amp;lt;/tt&amp;gt;&amp;quot; angegeben. Dadurch muss nur ''eine Stelle'' im Code geändert werden, wenn die Größe des Arrays einmal einen anderer Wert als 10 haben soll &amp;amp;ndash; dies vermeidet Fehler die dadurch entstehen, wenn man beim Anpassen der Array-Größe eine Codestelle vergisst, zudem wird der Code lesbarer als wenn irgendwo die Zahl &amp;quot;10&amp;quot; auftaucht.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
:Wird ein ungültiger Index angeben (einer, der in der Deklaration nicht enthalten ist) können  undefinierte Dinge passieren, wenn dadurch andere Variableninhalte oder Programmcode überschrieben wird, der hinter oder vor dem Array im Speicher liegt. Schlimmstenfalls kann sogar der Computer/Controller abstürzen. Also darauf achten, daß keine ungültigen Werte als Index auftreten!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Strings (Zeichenketten)===&lt;br /&gt;
Ein String ist nichts anderes als ein Array, das aus einzelnen Zeichen (&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;) gebildet wird. Die Ausgabe auf dem Bildschirm funktioniert am einfachsten mittels Strings.&lt;br /&gt;
&lt;br /&gt;
Die Definition eines Strings erfolgt also genauso wie bei Arrays:&lt;br /&gt;
 char string[21];&lt;br /&gt;
&lt;br /&gt;
Nun haben Sie eine String, in dem Sie 21 Zeichen speichern können. Ganz richtig ist das jedoch nicht. C arbeitet mit &amp;quot;null-terminierten Strings&amp;quot;. Das beudeutet, dass die Länge des Strings nicht abgespeichert wird, sondern das Zeichen mit dem ASCII-Wert 0 das Stringende kennzeichnet. Daher auch die Bezeichnung  &amp;quot;null terminiert&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Das letzte Zeichen eines Strings muß daher immer das ASCII-Zeichen Nr. 0 sein. Ist es das nicht, hat der String kein definiertes Ende, und wenn Sie versuchen, ihn durch eine Standard-Funktion auszugeben zu lassen, könnte es eine Weile dauern, bis sich im Speicher zufällig irgendwo eine 0 befindet. Es stehen ihnen daher bei dem Beispiel nur 20 Zeichen zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
===Mehrdimensionale Arrays===&lt;br /&gt;
Manchmal benötigt man mehr als nur ein eindimensionales Array, wie Sie es bisher kennengelernt haben. Auch dies ist kein Problem. In der Deklaration geben Sie einfach mehrere eckige Klammern hintereinander an. Aber Vorsicht: der Speicherplatz ist begrenzt, ein &amp;quot;&amp;lt;tt&amp;gt;char feld[1024][1024]&amp;lt;/tt&amp;gt;&amp;quot; hat die Speicherplatzgrenzen vermutlich bereits weit überschritten, und der Compiler wird einen (bei gewissen Einstellung auch keinen) Fehler liefern.&lt;br /&gt;
Beim Zugriff auf mehrdimensionale Felder müssen auch mehrere Indizes angeben werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  int x,y;&lt;br /&gt;
  int feld[3][5];&lt;br /&gt;
 &lt;br /&gt;
  for (x=0; x&amp;lt;3; x++) &lt;br /&gt;
  {&lt;br /&gt;
     for (y=0; y&amp;lt;5; y++)&lt;br /&gt;
     {&lt;br /&gt;
       printf (&amp;quot;Feldwert x: %d,  y: %d &amp;quot;, x, y);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; feld[x][y]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  for(x=0; x&amp;lt;3; x++) &lt;br /&gt;
     for (y=0; y&amp;lt;5; y++) &lt;br /&gt;
        printf (&amp;quot;Wert: feld[%d][%d] = %d\n&amp;quot;, x, y, feld[x][y]);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 3 mal 5 &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array angelegt. &lt;br /&gt;
Dann werden die Werte eingegeben: zuerst &amp;lt;tt&amp;gt;feld[0][0]&amp;lt;/tt&amp;gt;, dann &amp;lt;tt&amp;gt;feld[0][1]&amp;lt;/tt&amp;gt;, usw. bis &amp;lt;tt&amp;gt;feld[2][4]&amp;lt;/tt&amp;gt;. &lt;br /&gt;
Zum Schluß werden alle Werte noch einmal ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===Strukturen===&lt;br /&gt;
In C können Sie sogenannte &amp;quot;Strukturen&amp;quot; definieren. Dabei handelt es sich um eine Zusammenfassung mehrerer Datentypen zu einem größeren. Im Unterschied zu Feldern können in Strukturen unterschiedliche Datentypen zusammengestellt und gespeichert werden: &lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 struct {{Bezeichner}}&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur 'Person'}}&lt;br /&gt;
 struct Person &lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;lt;tt&amp;gt;struct Person {&amp;lt;/tt&amp;gt;&amp;quot; leitet die Definition der Struktur mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;Person&amp;lt;/tt&amp;gt;&amp;quot; ein. &lt;br /&gt;
Dann werden in dieser Struktur fünf Komponenten definiert: drei Strings und zwei &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. &lt;br /&gt;
mit &amp;lt;tt&amp;gt;}&amp;lt;/tt&amp;gt; wird die Definition abgeschlossen. Sie haben damit einen Datentyp erstellt. Um eine Variable des Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach an&lt;br /&gt;
 struct Person {{Bezeichner}};&lt;br /&gt;
&lt;br /&gt;
Zum Zugriff auf eine Komponente der Struktur gibt man den Namen der Struktur-Variablen an (im folgenden Beispiel also &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;klaus&amp;lt;/tt&amp;gt;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
 {{comment|Definition zweier Struktur-Variablen}}&lt;br /&gt;
 struct Person hubert, klaus;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Zugriff auf Struktur-Komponenten}}&lt;br /&gt;
 hubert.alter = 32;&lt;br /&gt;
 klaus.alter = hubert.alter + 1;&lt;br /&gt;
&lt;br /&gt;
===Unions===&lt;br /&gt;
Eine Union wird ganz analog zu einer Struktur deklariert und verwendet. Sie unterscheidet sich von einer Struktur jedoch dadurch, daß ihre Elemente nicht nacheinander im Speicher abgelegt werden, sondern sich überlagern. Auf die in einer Union enthaltenen Daten gibt es also verschiedene Sichten: je nachdem, welche Sicht bzw. Interpretation der Daten man gerne hätte, wählt man den gewünschten Zugriff.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
union Daten &lt;br /&gt;
{&lt;br /&gt;
   int id;&lt;br /&gt;
&lt;br /&gt;
   struct Person u_person;&lt;br /&gt;
&lt;br /&gt;
   struct u_double&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      double wert;&lt;br /&gt;
   };&lt;br /&gt;
&lt;br /&gt;
   struct u_pointer&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      union Daten * p1;&lt;br /&gt;
      union Daten * p2;&lt;br /&gt;
   };&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
union Daten data;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies definiert eine Union mit den vier Zugriffsmöglichkeiten &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_double&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Größe der Union richtet sich dabei nach der grössten Komponente. In diesem Beispiel sind alle Komponenten so angelegt worden, daß sie an erster Stelle ein &amp;lt;tt&amp;gt;int id&amp;lt;/tt&amp;gt; enthalten. In &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; könnte man sich also merken, wie die Daten in der Union zu interpretieren sind. Würde &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; nicht dieses &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; enthalten, so würde sich &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; mit &amp;lt;tt&amp;gt;data.u_person.vname&amp;lt;/tt&amp;gt; überlagern. Ein Ändern der ersten Buchstaben von &amp;lt;tt&amp;gt;vname&amp;lt;/tt&amp;gt; hätte also ein Ändern von &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; zur Folge, und man könnte es nicht mehr als Merker verwenden. Mit diesem Feld überlagert das &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; die &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;-Felder der anderen Sichten, z.B. ist &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; der selbe Zugriff wie auf &amp;lt;tt&amp;gt;data.u_person.id&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein anderes Beispiel ist eine Union, die es ermöglicht, auf die einzelnen Bytes eines &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; zuzugreifen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef union&lt;br /&gt;
{&lt;br /&gt;
   unsigned long  as_long;&lt;br /&gt;
   unsignen short as_short[2];&lt;br /&gt;
   unsignen char  as_byte[4];&lt;br /&gt;
} data32_t;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies überlagert einen &amp;lt;tt&amp;gt;unsigned long&amp;lt;/tt&amp;gt; &amp;amp;ndash; also eine 32-Bit-Zahl &amp;amp;ndash; mit vier Bytes bzw. zwei Shorts.&lt;br /&gt;
 data32_t wert;&lt;br /&gt;
 &lt;br /&gt;
 wert.as_long = 0x12345678;&lt;br /&gt;
 wert.as_byte[0] = 0xab;&lt;br /&gt;
 {{comment|nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform)}}&lt;br /&gt;
&lt;br /&gt;
==Eigene Datentypen==&lt;br /&gt;
&lt;br /&gt;
=Variablen=&lt;br /&gt;
Eine Variable ist ein Synonym (=anderer Name) für eine Speicherstelle in einem Computer. Einfacher gesagt, eine Variable bietet Raum, um Daten wie Zahlen oder Zeichen zu speichern und wieder zu lesen.&lt;br /&gt;
&lt;br /&gt;
==Variablennamen==&lt;br /&gt;
Ein Variablenname kann zusammengesetzt werden aus den Buchstaben &amp;lt;tt&amp;gt;'''A'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''Z'''&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;'''a'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''z'''&amp;lt;/tt&amp;gt;, den Ziffern &amp;lt;tt&amp;gt;'''0'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''9'''&amp;lt;/tt&amp;gt;, sowie dem Sonderzeichen &amp;quot;Unterstrich&amp;quot; (underscore) &amp;lt;tt&amp;gt;'''_'''&amp;lt;/tt&amp;gt;. Dabei darf an erster Stelle keine Ziffer stehen. Die Bezeichner &amp;lt;tt&amp;gt;hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALLO&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALL0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;_123&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_HALLO&amp;lt;/tt&amp;gt; sind also alle gültige und unterschiedliche Variablennamen.&lt;br /&gt;
&lt;br /&gt;
==Anlegen von Variablen==&lt;br /&gt;
Um eine Variable verwenden zu können, muss sie zuerst vereinbart (&amp;quot;erzeugt&amp;quot;) werden. Dies wird auch als &amp;quot;''Definition der Variablen''&amp;quot; bezeichnet und geht so: Schreiben Sie zuerst den Datentyp, dann den Namen der Variablen. Zum Schluß kommt noch der Strichpunkt, wie nach jeder C-Anweisung oder Deklaration. Und nicht vergessen: C unterscheidet zwischen  Groß- und Kleinschreibung! &lt;br /&gt;
 int Zahl1, Zahl2;&lt;br /&gt;
 char Zeichen;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    float gleitZahl;&lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:'''&lt;br /&gt;
In einer Zeile können auch mehrere Variablen gleichen Types vereinbart werden, wenn man ein Komma dazwischen setzt. Variablen können in jedem Block vereinbart werden. Siehe [[#Gültigkeitsbereich|Gültigkeitsbereich]].&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen==&lt;br /&gt;
Man kann einer vereinbarten Variable Werte [[#Zuweisungen|zuweisen]]. Dazu schreibt man zuerst den Variablennamen, ein Gleichheitszeichen &amp;quot;&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;&amp;quot; und anschliessend den zuzuweisenden [[#Ausdrücke|Ausdruck]]. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, zahl2 = 12;&lt;br /&gt;
  char zeichen1 = 'A';&lt;br /&gt;
&lt;br /&gt;
  zahl1 = 52;&lt;br /&gt;
  zeichen1 = zeichen1 + 1; &lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Zuerst werden drei Variablen angelegt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;: wird gleich bei der Vereinbarung der Wert 12 zugewiesen. &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl1 = 52&amp;lt;/tt&amp;gt;: Hier wird der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; der Wert 52 zugewiesen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;: wird um 1 erhöht. Da in der Variablen &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; gespeichert ist, gibt sich ihr neuer Wert aus &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt;. Weil &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; dem Wert 65 entspricht, ist &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt; gleich 66, was dem Wert für &amp;lt;tt&amp;gt;'B'&amp;lt;/tt&amp;gt; entspricht.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei float==&lt;br /&gt;
Das funktioniert genau wie bei normale Zuweisungen. Nachkommastellen werden durch einen Punkt abgegrenzt: &lt;br /&gt;
 floatVariable = 3.14;&lt;br /&gt;
Zusätzlich kann eine Zehnerpotenz angegeben werden:&lt;br /&gt;
 floatVariable2 = -1.234E-6;&lt;br /&gt;
Dadurch wird der erst Wert mit 10&amp;lt;sup&amp;gt;&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;6&amp;lt;/sup&amp;gt; multipliziert, der Wert der Variablen ist also &lt;br /&gt;
:&amp;lt;math&amp;gt;-1{,}234\cdot10^{-6} = -0.000001234&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei logischen Variablen==&lt;br /&gt;
Wie bereits erwähnt, besitzt C keinen logischen Datentyp. Es müssen also &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; dafür genutzt werden. Die Zuweisung entpricht der Standard-Zuweisung. Wird der Wert 0 zugewiesen, dann ist die Variable &amp;quot;unwahr&amp;quot;, ansonsten ist sie &amp;quot;wahr&amp;quot;. &lt;br /&gt;
 intVariable = !0;   /* entspricht &amp;quot;wahr&amp;quot;   */&lt;br /&gt;
 intVariable = 0;    /* entspricht &amp;quot;unwahr&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
==Konstanten==&lt;br /&gt;
Konstanten können als Variable angesehen werden, die nicht beschrieben, sondern nur gelesen werden können. Ein typisches Beispiel dafür ist die Zahl &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; (rund 3,141592654). Niemand würde in der realen Welt versuchen, ihr einen anderen Wert zuzuweisen. Würde man &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; jedoch wie eine normale Variable anlegen, wäre dies ohne weiteres möglich. Um dies zu verhindern, gibt es das Schlüsselwort &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in C:&lt;br /&gt;
 const {{Type}} {{Bezeichner}} = {{Konstante}};  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Wichtig dabei ist, dass man Konstanten nur bei der Vereinbarung einen Wert zuweisen kann. &lt;br /&gt;
Da Konstanten gewöhnlich im gesamten Programm, zumindest einer Quelldatei genutzt werden, definiert man diese allerdings gewöhnlich außerhalb des main-Blockes entweder am Anfang eines Programmes, oder in einer sogenannten Header-Datei, die per &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; eingebunden wird.&lt;br /&gt;
 const float PI = 3.141592;  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Es sei jedoch erwähnt, daß auch einer Konstanten nachträglich ein anderer Wert zugewieden werden kann. Im obigen Beispiel könnte mit&lt;br /&gt;
 * ((float*) &amp;amp;PI) = 2;&lt;br /&gt;
der Wert von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; im Nachhinein verändert werden. Es wird die Adresse von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; genommen und diese Adresse durch den Cast in eine ganz normale &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;-Adresse umgewandelt, über welche der Wert geändert wird. Die sei der Vollständigkeit halber erwähnt.&lt;br /&gt;
&lt;br /&gt;
Je nachdem, an welcher Stelle sich das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; bei einer Pointer-Deklaration befindet, markiert es den Pointer als konstant oder das Objekt, auf das dieser Pointer zeigt. Eine häufige Parameterdeklaration in Ausgabe-Funktionen, die einen String erhalten, ist&lt;br /&gt;
 void foo (const char * str, ...);&lt;br /&gt;
Dadurch ist &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; der Zeiger auf eine Zeichenkette, die innerhalt der Funktion nicht verändert wird bzw. verändert werden darf. Eine Zuweisung wie &amp;lt;tt&amp;gt;*str = 'a'&amp;lt;/tt&amp;gt; ergibt also einen Fehler. &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; selbst kann aber sehr wohl verändert werden, etwa mit &amp;lt;tt&amp;gt;str++&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Soll ausgedrückt werden, daß &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; unveränderlich ist, dann so:&lt;br /&gt;
 void foo (char * const str, ...);&lt;br /&gt;
Jetzt wäre eine Änderung des Strings in Ordnung, etwa durch &amp;lt;tt&amp;gt;str[10] = 'a'&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Um sich zu merken, worauf das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; wirkt, trennt man die Deklaration in Gedanken beim&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf: Steht das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; links vom&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, dann gehört es zum &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, steht es rechts davon, dann gehört es zum Pointer. Natürlich ist es auch denkbar, beides &amp;amp;ndash; also den Zeiger und sein Ziel &amp;amp;ndash; als konstant zu markieren.&lt;br /&gt;
&lt;br /&gt;
==Gültigkeitsbereich==&lt;br /&gt;
In C können mehrere Variablen den gleichen Namen haben, solange eindeutig ist, welche in welchen Block gültig ist. Dabei gelten folgende Regeln: &lt;br /&gt;
&lt;br /&gt;
;Lokale Variablen: sind Variablen, die innerhalb eines Blockes definiert werden. Jede Variable ist nur in dem Block gültig, in dem sie vereinbart wurde, sowie in allen darin enthaltenen Blöcken; es sei denn, in einem Unter-Block wird eine Variable gleichen Namens definiert. Dann bezieht sich in diesem Unter-Block der Bezeichner auf die im Unter-Block angelegte Variable.&lt;br /&gt;
;Globale Variablen: werden ausserhalb jedes Blockes definiert und gelten ab der Stelle, an der sie deklariert werden, siehe auch [[#Deklaration und Definition|Deklaration und Definition]]. Wird jedoch in einem Block eine Variable gleichen Namens angelegt, gilt ab hier bis zum Ende des Blocks nicht mehr die globale Variable, sondern die im Block deklarierte. Das Spiel kann man weiterspielen: wird in einem Unter-Block wieder eine namensgleiche Variable angelegt, gilt diese in dem Unterblock.&lt;br /&gt;
&lt;br /&gt;
==Speicherklassen==&lt;br /&gt;
Jede Variable in C gehört zu einer bestimmten Speicherklasse&lt;br /&gt;
;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;: Lokale Variablen sind in aller Regal sogenannte ''automatische Variablen''. Das bedeutet, sie werden automatisch angelegt, wenn ein Block bzw. eine Funktion betreten wird und danach wieder entfernt. Das Schlüsselwort &amp;quot;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;&amp;quot; wird praktisch nie hingeschrieben, denn lokale Variablen ohne die ausdrückliche Angabe einer Speicherklasse, sind automatisch automatische Variablen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;: Eine externes Symbol ist im ganzen Programm bekannt bzw. in dem Block, in der die Deklaration steht. In unterschiedlichen Blöcken stehende Deklarationen beziehen sich auf das gleiche Symbol! Obgleich das Datum global zugreifbar ist, ist der Gültigkeitsbereich auf den deklarierenden Block begrenzt bzw. auf das deklarierende Quell-Modul, sofern das Symbol ausserhalb jedes Blocks des Moduls deklariert wird. Siehe auch [[#Deklaration und Definition|Deklaration und Definition]].&lt;br /&gt;
;&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;: Die Variable ist im Block gültig bzw. im Quell-Modul (also in der C-Datei, in der die angelegt wurde), wenn sie nicht innerhalb eines Blockes angelegt wurde. Statische Variablen werden nicht in Registern oder im Frame der Funktion angelegt, sondern im selben Speicherbereich, in dem auch die globalen Variablen liegen; Konstanten evtl. auch im Flash. Eine lokale Variable, die als &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; angelegt wird, &amp;quot;überlebt&amp;quot; also das Verlassen des Blocks und hat beim neuerlichen Betreten des Blockes ihren bisherigen Wert. In unterschiedlichen Blöcken angelegte lokale statische Variablen beziehen sich auf unterschiedliche Speicherstellen, genau wie bei lokalen Variablen auch.&lt;br /&gt;
;&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;: Durch diese Speicherklasse wird eine Variable &amp;amp;ndash; falls möglich &amp;amp;ndash; als Registervariable angelegt, also in einem Maschinenregister des Computer/Controllers gehalten. Dadurch kann auf solche Variablen besonders schnell zugegriffen werden. Dieses Schlüsselwort ist bei modernen Compilern weitgehend überflüssig, da die entsprechenden Optimierungen selbständig vorgenommen werden, wenn ausreichend Register vorhanden sind. Auch globale Variablen können als Register angelegt werden, davon ist dem Anfänger aber dringend abzuraten, weil leicht schwerauffindbare Fehler und Abstürze auftreten, wenn man nicht genau weiss, welche Implikationen in einer solchen Definition stecken!&lt;br /&gt;
;&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;: (FIXME: volatile ist ein Qualifier und keine Speicherklasse) Dies ist das genaue Gegenteil von &amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt; und bewirkt, dass die Variable auf keinen Fall in einem Register zwischengespeichert werden darf, sondern immer aus dem RAM gelesen und ins RAM geschrieben werden soll. &amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt; müssen alle ''globalen'' Variablen markiert werden, die in [[ISR | Interrupt-Handlern]] verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Ausdrücke=&lt;br /&gt;
Eine Variable oder eine Konstante in C stellen einfache Ausdrücke dar.&lt;br /&gt;
Diese elementaren Ausdrücke können durch Operatoren miteinander verknüpft werden und so zu neuen, komplexeren Ausdrücken zusammen gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Einfache Beispiele für Ausdrücke sind also z.B.:&lt;br /&gt;
 1&lt;br /&gt;
 a&lt;br /&gt;
 'a'&lt;br /&gt;
 1 + a&lt;br /&gt;
 a == 1&lt;br /&gt;
&lt;br /&gt;
Auch Funktionen können einen Wert zurückliefern und in Ausdrücken weiter benutzt werden.&lt;br /&gt;
In den folgenden Abschnitten wird gezeigt, welche Operatoren in C vorhanden sind,&lt;br /&gt;
und wei man damit neue Ausdrücke aufbauen kann.&lt;br /&gt;
&lt;br /&gt;
==Lvalues==&lt;br /&gt;
&lt;br /&gt;
Ein Lvalue in C ist ein Ausdruck, dem ein anderer Ausdruck zugewiesen werden kann, dessen Wert also durch eine Zuweisung verändert werden kann.&lt;br /&gt;
das 'L' leitet sich ab von 'left' bwz. 'links' und das 'value' bedeutet Wert: Ein Lvalue ist ein Ausdruck, der auf der linken Seite einer Zuweisung stehen darf. Ein Lvalue ist also immer auch ein gültiger Ausdruck, aber die Umkehrung gilt in alles Regel nicht.&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für einen Lvalue ist eine &amp;quot;normale&amp;quot; Variable, die nicht mit &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; als Konstante markiert ist:&lt;br /&gt;
 a = 1;&lt;br /&gt;
Hingegen ist der Ausdruck &amp;lt;tt&amp;gt;a+1&amp;lt;/tt&amp;gt; kein Lvalue, denn eine Zuweisung wie&lt;br /&gt;
 a+1 = 2;&lt;br /&gt;
die mathematisch durchaus sinnvoll ist, erzeugt einen Compilerfehler, der etwa lauten könnte &amp;quot;illegal lvalue in assignment&amp;quot;:&lt;br /&gt;
&amp;quot;ungültiger Wert in Zuweisung&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Andere Beipiele für Lvalues sind die Komponenten von (nicht-konstanten) [[#Strukturen|Strukturen]] und [[#Unions|Unions]], [[#Arrays|Array]]-Elemente und die Dereferenzierungen von Pointern: Die Konstante&amp;amp;nbsp;4 wird durch den Cast in eine Adresse umgewandelt. Über die Dereferenzierung&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; wird an die Adresse&amp;amp;nbsp;4 im Speicher eine&amp;amp;nbsp;3 geschrieben. Ob das erlaubt bzw. sinnvoll ist, ist abhängig von der jeweiligen Architektur.&lt;br /&gt;
 * ((unsigned int *) 4) = 3;&lt;br /&gt;
Hier ist der gesamte &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;-Ausdruck ein Lvalue&lt;br /&gt;
&lt;br /&gt;
==Logische (boolsche) Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp;amp;&amp;amp;amp; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr oder &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; || gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; || ungleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;= b&amp;lt;/tt&amp;gt; || kleiner oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt; b&amp;lt;/tt&amp;gt; || kleiner als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt;= b&amp;lt;/tt&amp;gt; || glösser oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt; b&amp;lt;/tt&amp;gt; || grösser als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; nicht wahr und vice versa&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine interessante Eigenschaft der Operatoren &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;amp;amp;&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; ist, dass&lt;br /&gt;
sie die Auswertung abbrechen, sobald das Ergebnis feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet. Ein oft anzutreffendes Codestück sieht so aus, dabei sei &amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
  if (p &amp;amp;&amp;amp; *p == 5)&lt;br /&gt;
  {&lt;br /&gt;
     {{comment|mach was}}&lt;br /&gt;
  }&lt;br /&gt;
Zuerst wird in der Bedinung geprüft, ob Zeiger&amp;amp;nbsp;&amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; einen Wert ungleich Null hat, also ob er überhaupt einen gültigen Wert enthält. Es ist weit verbreitete Konvention in C, daß Zeiger, die keinen gültigen Wert haben, die Adresse&amp;amp;nbsp;0 enthalten. '''Nur dann, wenn ein Zeiger nicht ein Null-Pointer ist, darf überhaupt ein Zugriff über ihn erfolgen!'''&lt;br /&gt;
&lt;br /&gt;
==Vergleich von Variablen==&lt;br /&gt;
Skalare Variablen (also ganze Zahlen, Gleitkommazahlen, Zeiger) können miteinander verglichen werden. Dazu gibt es die folgenden Operatoren in C: &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; || ist nicht gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;=&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;=&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das Ergebnis der Auswertung ist eine ganze Zahl. Ist die Bedingung erfüllt, dann ist der Wert ungleich&amp;amp;nbsp;0. Ist die Bedingung nicht erfüllt, dann ist ihr Wert gleich&amp;amp;nbsp;0.&lt;br /&gt;
Meistens wird man diese Operatoren in &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Konstrukten finden wie zum Beispiel&lt;br /&gt;
 if (x &amp;gt;= 10)&lt;br /&gt;
    x = 10;&lt;br /&gt;
oder in Abbruchbedingungen von Schleifen, wie sie weiter unten erklärt werden.&lt;br /&gt;
&lt;br /&gt;
Es ist auch möglich, das Ergebnis der Auswertung in einer &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Variablen zu speichern:&lt;br /&gt;
 int i;&lt;br /&gt;
 int z1, z2;&lt;br /&gt;
 &lt;br /&gt;
 z1 = 5;&lt;br /&gt;
 z2 = 100;&lt;br /&gt;
 i = z1 &amp;lt;= z2;  {{comment|Ein Vergleich. i wird &amp;quot;wahr&amp;quot;, da z1 kleinergleich z2 ist}}&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich&amp;amp;nbsp;0 (&amp;quot;wahr&amp;quot;), wenn &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; kleiner oder gleich &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt; ist. Ist &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; jedoch größer als &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt;, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich&amp;amp;nbsp;0 (&amp;quot;unwahr&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
==Arithmetische Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a + b&amp;lt;/tt&amp;gt; || Summe (Addition)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a - b&amp;lt;/tt&amp;gt; || Differenz (Subtraktion)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a * b&amp;lt;/tt&amp;gt; || Produkt (Multiplikation)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a / b&amp;lt;/tt&amp;gt; || Quotient (Division, evtl. mit Rest)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a % b&amp;lt;/tt&amp;gt; || Rest bei Division (Modulo)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;-a&amp;lt;/tt&amp;gt; || Vorzeichenumkehr (Zweierkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Bit-Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp; b&amp;lt;/tt&amp;gt; || bitweise und (and)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || bitweise oder (or)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a ^ b&amp;lt;/tt&amp;gt; || bitweise exclusiv-oder (xor, exor)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;~a&amp;lt;/tt&amp;gt; || jedes Bit in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; invertieren (not, Einerkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Index-Operator bei Arrays==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a[b]&amp;lt;/tt&amp;gt; || das (b+1)ste Element des Feldes a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Folgendes gilt es bei der Verwendung des Indexoperators zu beachten:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; muss ein [[C-Tutorial#Felder | Feld]] oder [[C-Tutorial#Zeiger | Zeiger]] sein&lt;br /&gt;
# &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; muss ein Integer sein oder ein Datentyp, der sich in einen int umwandeln läßt (z.B. char)&lt;br /&gt;
# Es wird nicht geprüft, ob der Index &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; im Feld &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gültig ist!&lt;br /&gt;
# Der erste Index eines Feldes ist immer 0. Daher ''(b+1)stes Element'' in der Beschreibung&lt;br /&gt;
&lt;br /&gt;
==Komponenten-Auswahl bei Structs und Unions==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a.b&amp;lt;/tt&amp;gt; || Element b der [[C-Tutorial#Strukturen | Struktur]] oder des Unions a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adress-Operator und Dereferenzierung==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&amp;amp;amp;a&amp;lt;/tt&amp;gt; || Speicheradresse der Variablen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;*a&amp;lt;/tt&amp;gt; || Wert, der an der Adresse &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a-&amp;amp;gt;b&amp;lt;/tt&amp;gt; || Wert des Elements &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; der Struktur, deren Adresse in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Adressoperator &amp;amp; kann auf Variablen angewendet werden und&lt;br /&gt;
gibt die Startadresse der Variablen im Speicher zurück.&lt;br /&gt;
&lt;br /&gt;
Handelt es sich bei einer Variable um einen [[C-Tutorial#Zeiger | Zeiger]], so enthält&lt;br /&gt;
sie eine Speicheradresse. Um an den '''Wert''' zu gelangen, der&lt;br /&gt;
an dieser Adresse steht, wird der Operator * vorangestellt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
&lt;br /&gt;
 {{comment|x ist eine Integervariable und hat den Wert 5}}&lt;br /&gt;
 int x = 5;&lt;br /&gt;
     &lt;br /&gt;
 {{comment|z ist ein Zeiger auf eine Integer-Variable und enthaelt somit}}&lt;br /&gt;
 {{comment|die Speicheradresse einer Integer-Variablen}}&lt;br /&gt;
 int *z;       &lt;br /&gt;
  &lt;br /&gt;
 {{comment|Verwendung des Adress-Operators: weist an z die Adresse von x zu}}&lt;br /&gt;
 z = &amp;amp;x;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Verwendung der Dereferenzierung}}&lt;br /&gt;
 {{comment|erhoehe den Wert, der bei Adresse z steht, um eins}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|da z auf x zeigt, hat x jetzt den Wert 6}}&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff auf Struktir- und Union-Elemente eine abkürzende Schreibweise möglich:&lt;br /&gt;
&lt;br /&gt;
Statt &lt;br /&gt;
  (*strukturZeiger).element&lt;br /&gt;
kann geschrieben werden&lt;br /&gt;
  strukturZeiger-&amp;gt;element&lt;br /&gt;
Beide Schreibweisen sind absolut gleichbedeutend, die Klammern bei der ersteren sind notwendig.&lt;br /&gt;
&lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
:Bei der Dereferenzierung durch &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; findet keine Prüfung statt, ob der Zeiger auch auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu einer Änderung '''irgendeiner''' Speicherstelle!&lt;br /&gt;
&lt;br /&gt;
 int *z; {{comment|z ist ein Zeiger auf einen int}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.}}&lt;br /&gt;
 {{comment|z enthaelt irgendeine ungueltige Adresse!!}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|&amp;quot;Erhoehe einen Integer _irgendwo_ im Speicher um 1&amp;quot; -&amp;gt; CRASH !!!}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
&lt;br /&gt;
==Cast-Operator==&lt;br /&gt;
&lt;br /&gt;
Der Cast Operator dient dazu, den Datentyp eines Wertes zu ändern. Dafür wird einfach der neue Datentyp in Klammern vor den Wert geschrieben.&lt;br /&gt;
&lt;br /&gt;
Um zum Beispiel aus einem Float ein Integer zu machen:&lt;br /&gt;
 var  = (int) 5.60;&lt;br /&gt;
Dabei wird der Wert aber auch gerundet, und es findet somit ein Informationsverlust statt.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Umwandeln einer ganzen Zahl in eine Adresse:&lt;br /&gt;
 int * addr;&lt;br /&gt;
 addr = (int*) 0x1234;&lt;br /&gt;
Damit ist &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; an Adresse 0x1234.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
Der Cast-Operator selbst führt ''keine Konvertierung'' von Darstellungen durch, etwa die Umwandlung der ganzen Zahl 123 ein den String &amp;lt;tt&amp;gt;&amp;quot;123&amp;quot;&amp;lt;/tt&amp;gt;, der diese Zahl darstellt! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
  int main(int argc, char ** argv)&lt;br /&gt;
  {&lt;br /&gt;
        char text[] = &amp;quot;5.6&amp;quot;;&lt;br /&gt;
        int zahl = (int) text;&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, zahl);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Anfangsadresse des Strings &amp;lt;tt&amp;gt;&amp;quot;5.6&amp;quot;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Komma-Operator==&lt;br /&gt;
Mit einem &amp;lt;tt&amp;gt;,&amp;lt;/tt&amp;gt; können mehrere Ausdrücke nacheinander ausgewertet werden.&lt;br /&gt;
Die Auswertung erfolgt von links nach rechts.&lt;br /&gt;
&lt;br /&gt;
Solche Konstrukte sieht man manchmal in Abfragen wie&lt;br /&gt;
 FILE  *file;&lt;br /&gt;
 if (file = fopen (&amp;quot;foo.exe&amp;quot;, &amp;quot;r&amp;quot;), file != NULL)&lt;br /&gt;
was erst an &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; einen Wert zuweist und den &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Block nur betritt,&lt;br /&gt;
wenn &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; nicht der Nullpointer ist.&lt;br /&gt;
&lt;br /&gt;
Bequem kann das auch in einer [[#for-Schleife|for-Schleife]] sein, wenn man zwei (oder mehr) Laufvariablen hat oder so:&lt;br /&gt;
 for (i=0, j=0; i &amp;lt; 10; i++, j += 2)&lt;br /&gt;
    &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Zuweisung===&lt;br /&gt;
=== ++ und -- ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; stellen einfachere Schreibweisen dar zum Addieren bzw. Subtrahieren von&amp;amp;nbsp;1.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; (Inkrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo++; &lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo + 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; 3}}&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; (Dekrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo--;&lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo - 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; -1}}&lt;br /&gt;
&lt;br /&gt;
Die beiden Operatoren können sowohl in der Präfix-Schreibweise (vor der Variablen) als auch als Postfix-Schreibweise (hinter der Variablen) notiert werden. &lt;br /&gt;
Der Unterschied liegt darin, dass beim Präfix der Wert zuerst neu berechnet wird und die Variable dann verwendet wird. Beim Postfix wird die Variable zuerst verwendet und erst nach Auswertung des Ausdrucks, in dem sie enthalten ist, neu berechnet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 int ausgabe1, ausgabe2, var1 = 10, var2 = 10;&lt;br /&gt;
 ausgabe1 = 3 * ++var1; {{comment|ausgabe1 &amp;amp;#61; 33; var1 &amp;amp;#61; 11;}}&lt;br /&gt;
 ausgabe2 = 3 * var2++; {{comment|ausgabe2 &amp;amp;#61; 30; var2 &amp;amp;#61; 11;}}&lt;br /&gt;
&lt;br /&gt;
Für Zeiger arbeiten diese Operatoren etwas anders, siehe dazu [[#Zeiger-Arithmetik|Zeiger-Arithmetik]].&lt;br /&gt;
&lt;br /&gt;
===Bedingter Ausdruck===&lt;br /&gt;
 ({{Bedingung}}) ? {{Ausdruck|1}} : {{Ausdruck|2}}&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; erfüllt ist, dann wertet dieser Ausdruck aus zu &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt;. Ist er nicht erfüllt, dann wertet er aus zu &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 x = (x &amp;gt;= 3) ? 0 : x+1;&lt;br /&gt;
Startet man &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; mit dem Wert 0, dann nimmt es bei mehrfacher Anwendung dieser Zeile (z.B. in einer Schleife) nacheinander die folgende Werte an:&lt;br /&gt;
:&amp;lt;tt&amp;gt;1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, ...&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Priorität ||Operator||Assoziativität&lt;br /&gt;
|-&lt;br /&gt;
  &lt;br /&gt;
|&amp;lt;tt&amp;gt;15&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ( ) [ ] -&amp;gt; . &amp;lt;/tt&amp;gt;                      ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;14&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;! ~ ++ -- + - (TYP) * &amp;amp; sizeof &amp;lt;/tt&amp;gt;    ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;13&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; * / % (Rechenoperationen) &amp;lt;/tt&amp;gt;         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;12&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; + - (binär) &amp;lt;/tt&amp;gt;                       ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;11&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;&amp;lt; &amp;gt;&amp;gt; &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;10&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt; &amp;lt;= &amp;gt; &amp;gt;= &amp;lt;/tt&amp;gt;                         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 9&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; == != &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 8&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp; (bit-AND-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 7&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ^ (bit-XOR-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 6&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; (bit-OR-Operator)&amp;lt;/tt&amp;gt;   ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 5&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp;&amp;amp; &amp;lt;/tt&amp;gt;                                ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 4&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; &amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 3&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt;? : &amp;lt;/tt&amp;gt;                               ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 2&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; = += -= /= *= %= &amp;gt;&amp;gt;= &amp;lt;&amp;lt;= &amp;amp;= &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;= ^= &amp;lt;/tt&amp;gt; ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 1&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; , (Sequenz-Operator) &amp;lt;/tt&amp;gt;              ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
Eine Kontrollanweisung ist eine Anweisung, die Einfluss auf den Programmfluss hat. Normalerweise werden Anweisungen so ausgeführt, wie sie in der Quelldatei stehen: Von links nach rechts (falls mehrere Anweisungen in einer Zeile stehen sollten, wovon i.A. abzuraten ist) und von oben nach unten. Mit einer Kontrollanweisung kann dieser lineare Programmfluss durchbrochen werden: Die Codeausführung kann kann abhängig von einer Bedingung gemacht werden (&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;), kann wiederholt werden (Schleife) oder an einer anderen Stelle der Funktion fortgesetzt werden (&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==if-Anweisung==&lt;br /&gt;
Mit Hilfe des if-Befehls kann man Codeteile abhängig davon einer Bedingung ausführen lassen:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
oder mit else-Teil&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 if (x &amp;gt; 100)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;gt; 100 ist: Fehlerausgabe}}&lt;br /&gt;
    printf (&amp;quot;x = %d ist zu gross fuer die Berechnung!\n&amp;quot;, x);&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;lt;&amp;amp;#61; 100 ist: Berechne Summe der Zahlen 1...x}}&lt;br /&gt;
    {{comment|Die lokale Variable x2 lebt nur innerhalb dieses alse-Blocks}}&lt;br /&gt;
    int x2 = x;&lt;br /&gt;
 &lt;br /&gt;
    for (x = 0; x2 &amp;gt; 0; x2--)&lt;br /&gt;
       x += x2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Wenn die Bedingung wahr ist (&amp;lt;tt&amp;gt;x &amp;gt; 100&amp;lt;/tt&amp;gt;), dann wird eine Meldung ausgegeben; danach ist die if-Anweisung beendet. Der else-Block wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung nicht erfüllt (&amp;lt;tt&amp;gt;x &amp;amp;le; 100&amp;lt;/tt&amp;gt;), dann wird gleich zum else-Teil gesprungen, und nach dessen Ausführung der if-Befehl beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Ein häufiger Fehler ist es, statt &amp;lt;tt&amp;gt;if (a &amp;amp;#61;&amp;amp;#61; 23)&amp;lt;/tt&amp;gt; etwas wie &amp;lt;tt&amp;gt;if (a &amp;amp;#61; 23)&amp;lt;/tt&amp;gt; zu schreiben. &lt;br /&gt;
Dann wird allerdings nicht geprüft, ob die Variable&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gleich 23 ist, sondern der Variablen&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wird der Wert 23 zugewiesen. Der Ausdruck &amp;lt;tt&amp;gt;a &amp;amp;#61; 23&amp;lt;/tt&amp;gt; hat den Wert&amp;amp;nbsp;23 und ist damit immer &amp;quot;wahr&amp;quot;! Daher ist diese if-Bedingung immer erfüllt!&lt;br /&gt;
&lt;br /&gt;
Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken sondern bestenfalls eine Warnung. Damit ist dieser Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise &amp;lt;tt&amp;gt;if (23 &amp;amp;#61;&amp;amp;#61; a)&amp;lt;/tt&amp;gt;. Wenn man dort anstatt des Vergleichsoperators '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;amp;#61;&amp;lt;/tt&amp;gt;' den Zuweisungsoperator '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;lt;/tt&amp;gt;' verwendet, spuckt der Compiler sehr wohl einen Fehler aus! Ist die Zuweisung jedoch erwünscht und eine Compiler-Warnung lästig, dann wählt man eine Schreibweise wie &amp;lt;tt&amp;gt;if ((a &amp;amp;#61; b))&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;if (a &amp;amp;#61; b, a)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist zu schreiben &amp;lt;tt&amp;gt;if (Bedingung);&amp;lt;/tt&amp;gt; Richtig muss es heissen &amp;quot;&amp;lt;tt&amp;gt;if(Bedingung)&amp;lt;/tt&amp;gt;&amp;quot; Das Semikolon im ersten Fall ist eine leere Anweisung, die im if-Falle ausgeführt wird &amp;amp;ndash; sie bleibt also ohne Resultet. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt; ein auf das Semikolon folgende Anweisung die eigentlich zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören soll wird immer ausgeführt, die sie nicht mehr zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; dazu gehört.&lt;br /&gt;
}}&lt;br /&gt;
Bei verschachtelten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Konstrukten gehört ein &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zu letzten &amp;quot;freien&amp;quot; &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;. Soll in einer &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Folge das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zum ersten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören, dann ist das so zu hinzuschreiben:&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Ohne die geschweiften Klammern um das zweite &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehörte das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; dort hinzu.&lt;br /&gt;
&lt;br /&gt;
==switch-Anweisung==&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
&lt;br /&gt;
 switch ({{Ausdruck|}}) &lt;br /&gt;
 {&lt;br /&gt;
     case konstante1:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
    &lt;br /&gt;
     case konstante2:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 &lt;br /&gt;
     {{comment|weitere case-Marken}}&lt;br /&gt;
 &lt;br /&gt;
     default:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 } {{comment|Ende von switch}} &lt;br /&gt;
&lt;br /&gt;
Der Ausdruck muss ein skalarer Typ sein, er wird in die nächste ganze Zahl gewandelt und mit den Werten hinter den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Marken verglichen. Bei einer Übereinstimmung werden alle Befehle ab dem zutreffenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; ausgeführt. Stimmt der Ausdruck mit keinem der Werte überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt falls vorhanden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der nachfolgenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;- und des &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitts werden ausgeführt, wenn die Anweisungen des &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitts nicht mit dem Befehl &amp;lt;tt&amp;gt;break;&amp;lt;/tt&amp;gt; beendet werden!&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es dürfen beliebig viele &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitte angegeben werden, pro Vergleichswert jedoch nur einer.&lt;br /&gt;
Der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ist optional. Die Reihenfolge, in der &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt; angegeben werden, ist unerheblich.&lt;br /&gt;
&lt;br /&gt;
==Schleifen==&lt;br /&gt;
Um Anweisungen mehrmals hintereinander auszuführen, benötigt man Schleifen. Diese führen Anweisungen aus, bis oder solange Bedingungen erfüllt sind.&amp;lt;br&amp;gt; &lt;br /&gt;
Wichtig ist also, ob die Bedingung '''vor''' oder '''nach''' den Schleifen-Anweisungen geprüft wird. &lt;br /&gt;
&lt;br /&gt;
===while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 while ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Die while-Schleife wird solange durchlaufen, wie die Bedingung erfüllt ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Die Anweisung kann natürlich auch ein Block sein, der aus mehreren Deklarationen und Anweisungen besteht. &lt;br /&gt;
&lt;br /&gt;
 int zahl1 = 0;&lt;br /&gt;
 int zahl2 = 1;&lt;br /&gt;
 &lt;br /&gt;
 while (zahl1 &amp;lt; 3)&lt;br /&gt;
 {&lt;br /&gt;
    zahl1 = zahl1 + 1;&lt;br /&gt;
    zahl2 = zahl2 * 2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife drei mal durchlaufen. Zu Beginn des vierten Durchlaufs ist die Bedingung nicht mehr erfüllt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
&lt;br /&gt;
===do-while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
Die do-while-Schleife wird auf jeden Fall einmal durchlaufen und dann solange wiederholt, wie die Bedingung erfüllt ist.&lt;br /&gt;
 int i = 2;&lt;br /&gt;
 &lt;br /&gt;
 do &lt;br /&gt;
 {&lt;br /&gt;
     i = i*i;   {{comment|i quadrieren}}&lt;br /&gt;
     printf (&amp;quot;i = %d\n&amp;quot;, i);&lt;br /&gt;
 }&lt;br /&gt;
 while (i &amp;lt; 20);&lt;br /&gt;
&lt;br /&gt;
Die Schleife wird durchlaufen und wiederholt, solange &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; kleiner als 20 ist. Es werden also nacheinander die Werte 2, 4 und 16 ausgegeben. Nach der Schleife hat&amp;amp;nbsp;&amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; den Wert 256.&lt;br /&gt;
&lt;br /&gt;
===for-Schleife===&lt;br /&gt;
'''Syntax:''' &lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Bei den Ausdrücken wird es sich um einen Ausdrücke mit Nebeneffekt handeln wie etwa &amp;lt;tt&amp;gt;i=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;i=i+2&amp;lt;/tt&amp;gt;. Es werden folgende Aktionen ausgeführt:&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# falls die Bedingung wahr ist, dann führe &amp;lt;tt&amp;gt;Anweisung&amp;lt;/tt&amp;gt; aus.&lt;br /&gt;
# falls die Bedingung unwahr ist, dann sprinte zu 7 (Ende).&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# gehe zu 2&lt;br /&gt;
# nächste Anweisung nach der for-Schleife&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int lauf, summe;&lt;br /&gt;
 &lt;br /&gt;
 for (lauf=1, summe=0; lauf &amp;lt;= 10; lauf += 2) &lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel ist &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; ein [[#Komma-Operator|Komma-Ausdruck]], der zwei Anweisungen kombiniert und daher sogar zwei Nebeneffente hat: er setzt &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;1 und &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;0.&lt;br /&gt;
&lt;br /&gt;
Das Äquivalent als while-Schleife:&lt;br /&gt;
&lt;br /&gt;
 int lauf  = 1;                 {{comment|Anfangswerte}}&lt;br /&gt;
 int summe = 0;&lt;br /&gt;
 &lt;br /&gt;
 while (lauf &amp;lt;= 10)             {{comment|Bedingung}}&lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
    lauf  += 2;                 {{comment|Inkrement}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; in jedem Schleifendurchlauf um die Laufvariable &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; erhöht. Da &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nacheinander die ungeraden Werte von&amp;amp;nbsp;1 bis&amp;amp;nbsp;10 annimmt, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von&amp;amp;nbsp;1 bis kleinergleich 10 gespeichert, also der Wert&amp;amp;nbsp;25. &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; hat nach der Schleife den Wert&amp;amp;nbsp;11.&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf = 1&amp;lt;/tt&amp;gt; bedeutet, dass der Variablen &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; vor dem ersten Schleifendurchlauf der Wert&amp;amp;nbsp;1 zugewiesen wird. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf &amp;lt;= 10&amp;lt;/tt&amp;gt; ist die Schleifenbedingung; ist sie nicht erfüllt, wird die Schleife beendet. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf += 2&amp;lt;/tt&amp;gt; bedeutet, dass &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nach jedem Durchlauf um&amp;amp;nbsp;2 erhöht wird.&lt;br /&gt;
&lt;br /&gt;
===continue-Anweisung===&lt;br /&gt;
Innerhalb einer Schleife darf die &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die nachfolgenden Anweisungen übersprungen werden und mit dem nächsten Schleifendurchlauf fortgesetzt wird &amp;amp;ndash; vorausgesetzt die Schleifenbedingung ist noch erfüllt. Ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; etc. stehen, wenn dieses innerhalb einer Schleife steht.&lt;br /&gt;
&lt;br /&gt;
==break-Anweisung==&lt;br /&gt;
Innerhalb einer Schleife oder eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; darf die &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die Schleifen-/Switch-Anweisung sofort verlassen wird und das Programm dahinter weiter macht. Bei mehrfach geschachtelten Schleifen wird nur die innere verlassen. Ein &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; stehen, wenn dieses innerhalb einer Schleife/Switch-Anweisung steht.&lt;br /&gt;
&lt;br /&gt;
==goto-Anweisung==&lt;br /&gt;
&lt;br /&gt;
Innerhalb ein und derselben Funktion kann mit &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; an eine andere Stelle gesprungen werden. Dazu gibt man hinter dem &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einen Bezeichner an, der dadurch als Label fungiert:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 goto {{Bezeichner}};&lt;br /&gt;
Die Bezeichner selbst steht irgendwo in der Funktion und wird dadurch zur Sprungmarke (Label), daß er von einem Doppelpunkt (und mindestens einer C-Anweisung, die auch leer sein darf) gefolgt wird.&lt;br /&gt;
&lt;br /&gt;
Das Beispiel durchsucht das 2-dimensionale &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array &amp;lt;tt&amp;gt;feld&amp;lt;/tt&amp;gt; mit den &amp;lt;tt&amp;gt;SIZE_X &amp;amp;times; SIZE_Y&amp;lt;/tt&amp;gt; Werten nach dem Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;. Wird er gefunden, dann wird die 2-fach geschachtelte Suchschleife verlassen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int x, y;&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y; y++)&lt;br /&gt;
       if (feld[x][y] == 0)&lt;br /&gt;
          goto done;&lt;br /&gt;
 {{Label|done:}};&lt;br /&gt;
&lt;br /&gt;
Der folgende Code hat die gleiche Funktion, arbeitet jedoch ohne &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int x, y;&lt;br /&gt;
 int found = 0; {{comment|FALSE}}&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X &amp;amp;&amp;amp; !found; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y &amp;amp;&amp;amp; !found; y++)&lt;br /&gt;
       found = (0 == feld[x][y]);&lt;br /&gt;
Der Nachteil der &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-losen Variante ist, daß man eine Variable, die merkt, ob das Suchziel gefunden wurde, mitschleppen und in ''jedem'' Schleifendurchlauf abtesten muss. Dies bedeutet einen höheren Programmier- und Laufzeitaufwand und ist nicht so klar formuliert wie das &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-Beispiel.&lt;br /&gt;
&lt;br /&gt;
Gleichwohl sei angemerkt, daß die Verwendung von &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einem gewissen Dogmatismus unterliegt, der sich wie folgt subsummieren liesse:&lt;br /&gt;
:''goto ist böse und sollte keinesfalls verwendet werden! Wer es dennoch tut, offenbart dadurch seinen schlechten Geschmach sowie mangelhafte C-Kenntnis.'' &amp;lt;div align=&amp;quot;right&amp;quot;&amp;gt;http://www.roboternetz.de/phpBB2/images/smiles/icon_wink.gif&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Funktionen=&lt;br /&gt;
Stellen Dir vor, Du hast eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben &amp;amp;ndash; was Dich Zeit beim Erstellen des Programms und Speicherplatz im ausführbaren Programm kostet &amp;amp;ndash; kannst Du den Code-Abschnitt in eine Funktion schreiben und diese von jeder Stelle des Programms aus verwenden. Die Hauptgründe, um Funktionen zu verwenden, sind:&lt;br /&gt;
;Wiederverwendung von Code: Mehrfach verwendete Codestücke müssen nicht mehrfach implementiert werden. Oft unterscheiden sich die Codesequenzen nur in Kleinigkeiten, die man der Funktion über Parameter mitteilen kann.&lt;br /&gt;
;Übersichtlichkeit: Ein gut gegliedertes C-Programm implementiert klar umrissene Aufgaben in einer Funktion, auch wenn diese Funktion nur einmal im Code aufgerufen wird! Dadurch bleibt der Code um die Aufrufstelle besser verständlich, und man kann auf verschiedenen &amp;quot;Ebenen&amp;quot; denken. Eine Funktion wie &amp;quot;Datei öffnen&amp;quot; kann recht komplex sein. Auf höherer Ebene interessieren die Innereien nicht mehr, man möchte sich um andere Dinge kümmern und will den Code an der Stelle garnicht sehen...&lt;br /&gt;
;Rekursive Funktionen: Eine Funktion kann sich auch selbst aufrufen. In dem Falle nennt man die Funktion ''rekursiv''. Zwar lässt sich das, was eine rekursive Funktion tut, auch mit anderen Mitteln formulieren, die keine rekursiven Funktionen brauchen, aber oft ist der rekursive Weg knackiger und klarer formulierbar als eine nicht-rekursiven Ansatz, auch wenn es etwas mehr Resourcen verbraucht.&lt;br /&gt;
;Modulare Programmierung: Funktionen können anhand ihres Aufgabenbereichs auf verschiedene C-Quellen &amp;amp;ndash; sogenannte ''Module'' &amp;amp;ndash; verteilt werden. Funktionen, die etwas mit dem USB-Bus anstellen, werden in einem anderen Modul sein als mathematische Funktionen. Dies erhöht die Übersichtlichkeit und vereinfacht die Entwicklung im Team.&lt;br /&gt;
;Bibliotheken: Standard-Funktionen wie das hier oft auftauchende &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; sind in Bibliotheken gespeichert. Wenn das eigene Programm übersetzt wird, dann müssen nicht mehr alle Standard-Funktionen übersetzt werden, sondern werden nur noch aus der Bibliothek gelesen und ihr Code zum Programm dazugelinkt. Die Bibliotheks-Funktionen wurden schon zu einem früheren Zeitpunkt compiliert und liegen in dieser compilerten Form in der Bibliothek. Das spart mächtig Entwicklungszeit. Man kann auch selbst solche Bibliotheken erstellen und in diversen Projekten wiederverwenden.&lt;br /&gt;
;Generische Programmierung: In C ist es möglich, einer Funktion eine andere Funktion zu übergeben. (Damit ist nicht gemeint, ihr deren ''Rückgabewert'' zu übergeben (was auch ginge), sondern ''die Funktion selbst'' wird als Parameter übergeben und kann aufgerufen werden.) Ein typisches Beispiel dafür sind Sortieralgorithmen. Einem Sortieralgorithmus kann es egal sein, ''was'' er sortiert. Er muss lediglich wissen, ''wie'' er das Zeug zu sortieren hat: aufsteigend, absteigend, als Zahl, in lexikographischer Ordnung, nach der Quersumme, Körper nach Oberfläche, Durchmesser, Gewicht oder Volumen... Diese Vergleichsfunktion, die für zwei Objekte entscheidet, welches davon &amp;quot;kleiner&amp;quot; ist, kann man dem Sortierer übergeben. Will er zwei Werte vergleichen, dann muss er nur die Vergleichsfunktion aufrufen, ohne zu wissen, was diese tut. Damit kann der Sortieralgorithmus unanhängig von den Objekten gehalten werden, mit denen er hantieren soll.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Definition==&lt;br /&gt;
&lt;br /&gt;
In der ''Definition'' der Funktion wird gesagt, welche Werte sie liefern kann, wie sie heisst (Bezeichner) und wieviele und welche Parameter sie hat. Danach folgt ihre Implementierung:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}} ({{Parameterliste}})&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 &lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
Für Funktionen, die keinen Wert zurückliefern, gibt es den speziellen Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der besagt, daß die Funktion nichts zurückgibt. Die einfachste denkbare Funktion ist eine solch void-Funktion. Sie bekommt keine Parameter, gibt nicht zurück und ihr Body ist leer:&lt;br /&gt;
 void dummy()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==return-Anweisung==&lt;br /&gt;
An jeder Stelle des Programmflusses einer Funktion kann diese mit &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; beendet werden.&lt;br /&gt;
&lt;br /&gt;
'''bei void-Funktionen:'''&lt;br /&gt;
 return;&lt;br /&gt;
'''Funktionen mit Rückgabe-Wert:'''&lt;br /&gt;
 return {{Ausdruck|}};&lt;br /&gt;
Die zweite Variante gibt an, welcher Wert zurückgegeben wird.&lt;br /&gt;
 int main (int argc, char * argv[])&lt;br /&gt;
 {&lt;br /&gt;
    if (argc &amp;lt; 2)&lt;br /&gt;
       return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
Falls die letzte Anweisung einer void-Funktion ein &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; ist, kann es auch weggelassen werden wie oben bei der Funktion &amp;lt;tt&amp;gt;dummy&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Aufruf==&lt;br /&gt;
Um die Funktion aufzurufen gibt man ihren Namen an, gefolgt von den durch Komma getrennten Argumenten in runden Klammern wie im Beispiel unten das&lt;br /&gt;
 quadrat (5) &lt;br /&gt;
Da &amp;lt;tt&amp;gt;quadrat&amp;lt;/tt&amp;gt; einen Wert liefert, kann man damit weiter rechnen wie mit einem normalen Ausdruck:&lt;br /&gt;
 if (quadrat (a) + quadrat (b) == quadrat (c))&lt;br /&gt;
    c = quadrat (quadrat (a)); {{comment|c &amp;amp;#61; a hoch 4}}&lt;br /&gt;
&lt;br /&gt;
==Rekursive Funktionen==&lt;br /&gt;
Eine Funktion die sich selbst &amp;amp;ndash; möglicheweise auch über andere Zwischenfunktionen &amp;amp;ndash; wieder selbst aufruft, wird als ''rekursive Funktion'' bezeichnet. In der Definition ist nichts besonderes zu beachten. Ist die Verschachtelungstiefe im laufenden Programm zu tief, dann gibt das natürlich Probleme, aber das gilt bei tief verschachtelten 'normalen' Funktionen abenso...&lt;br /&gt;
&lt;br /&gt;
Das Beispiel berechnet den Größten Gemeinsamen Teiler zweier Zahlen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int ggT (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
     if (0 == a)&lt;br /&gt;
        return b;&lt;br /&gt;
 &lt;br /&gt;
    return ggT (b % a, a);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Ein komplettes kleines Programm:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int quadrat (int param1)&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  zahl = param1 * param1;&lt;br /&gt;
  return zahl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl, ergebnis;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Bitte Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = quadrat (zahl);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, zahl, ergebnis);&lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, 5, quadrat (5));&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur ausserhalb von Blöcken. Geschachtelte Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen beim Aufruf die Klammern angeben werden:&lt;br /&gt;
 dummy();&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Prototypen==&lt;br /&gt;
Wie oben erwähnt, kann ein Unterprogramm an jeder beliebigen Stelle im Programm stehen. Damit ist jedoch eine Bedingung verknüpft: Das Unterprogramm muß in der Datei oberhalb des ersten Aufrufes definiert worden sein. Wenn Sie ein Unterprogramm in Zeile 10 zum ersten mal aufrufen, müssen Sie die Deklaration davor erledigt haben. Verstanden?&lt;br /&gt;
Um dies zu erreichen, gibt es zwei Möglichkeiten: &lt;br /&gt;
&lt;br /&gt;
Entweder Sie schreiben alle Unterprogramme vor &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; in die Datei. Dies muß jedoch wiederum so geschehen, dass Funktionen zum Zeitpunkt ihres Aufrufes bereits bekannt sind! &lt;br /&gt;
Wo dies nicht möglich ist (z.B. sich gegenseitig aufrufende Unterprogramme), oder wenn Sie das stört, müssen Sie Prototypen verwenden. &lt;br /&gt;
Wie definiert man nun Prototypen? Sie kopieren einfach die erste Zeile des Unterprogrammes (z.B. &amp;quot;&amp;lt;tt&amp;gt;void ausgeben (int zahl)&amp;lt;/tt&amp;gt;&amp;quot;), fügen einen Strichpunkt&amp;amp;nbsp;&amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;an und fügen es an einer geeigneten Stelle ein (so, dass alle Aufrufe später in der Datei kommen). &lt;br /&gt;
Solche Definitionen stehen gewöhnlich am Anfang der Quelldatei oder in einer Header-Datei, die eingebunden wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl);  /* Der Prototyp */&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
   ausgeben (12);&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl)   /* Die eigentliche Prozedur */&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Ausgabe: %d\n&amp;quot;, zahl);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Parameterübergabe==&lt;br /&gt;
&lt;br /&gt;
Alle Werte, die an Prozeduren und Funktionen übergeben werden, werden grundsätzlich '''kopiert'''.&lt;br /&gt;
Das hat folgende Auswirkungen:&lt;br /&gt;
&lt;br /&gt;
# Änderungen an einem Parameter in einer Funktion erscheinen ''nicht'' beim Aufrufer!&lt;br /&gt;
# Möchte man, dass eine Funktion einen Wert trotzdem dauerhaft ändern soll, so muss die Adresse des Wertes via [[#Zeiger|Zeiger]] übergeben werden.&lt;br /&gt;
# Werden [[#Strukturen|Strukturen]] übergeben, so wird von ihnen eine Kopie erstellt, was bei großen Strukturen viel Zeit und Arbeitsspeicher kostet. Deshalb wird häufig nur die Adresse von Strukturen übergeben, da die Adresse viel schneller und platzsparender als die Struktur selbst kopiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele:'''&lt;br /&gt;
 void erhoehe (int x)&lt;br /&gt;
 {&lt;br /&gt;
    x = x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe(a);&lt;br /&gt;
    {{comment|a ist immer noch 0}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Beim Aufruf von &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; wird eine Kopie des Wertes von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; (im Beispiel also 0) erstellt und der Prozedur als Parameter &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; übergeben. Weil dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat dies keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|erhoehe den Wert an der Adresse x um eins}}&lt;br /&gt;
    *x = *x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe (&amp;amp;a);&lt;br /&gt;
    {{comment|a ist jetzt 1}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Jetzt wird im Hauptprogramm mittels [[#Adress-Operator und Dereferenzierung|Adress-Operator]] &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; die Speicheradresse von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; bestimmt. Dann wird eine ''Kopie der Adresse'' an das Unterprogramm &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; übergeben. Jetzt kennt das Unterprogramm die&lt;br /&gt;
Adresse des Originals &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und kann direkt mit dem Inhalts-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&lt;br /&gt;
'''Besonderheit bei Feldern'''&lt;br /&gt;
&lt;br /&gt;
Bei der Übergabe von [[#Felder|Feldern]] gibt es eine Besonderheit. Schreibt man nämlich den Namen eines Feldes, so ist das nichts anderes als die '''Speicheradresse des ersten Elements'''.&lt;br /&gt;
Bei der Übergabe eines Feldes wird also eine Kopie der Startadresse übergeben. Somit kann das Unterprogramm auf den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 void erhoehe (int x[])&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
   int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
   erhoehe (a);&lt;br /&gt;
   {{comment|a hat jetzt folgenden Inhalte: 11, 23, 35}}&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Dass die Übergabe einer Adresse erfolgt, sieht man an folgendem Beispiel, das von der Funktionsweise '''absolut identisch''' mit dem vorhergehenden ist:&lt;br /&gt;
&lt;br /&gt;
 {{comment|Bei Parametern gibt es keinen Unterschied zwischen Zeiger und Feld}}&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
    int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
    erhoehe (a);&lt;br /&gt;
 &lt;br /&gt;
    {{comment|a hat jetzt folgenden Inhalt: 11, 23, 35}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
Die Länge des Feldes wird nicht automatisch übergeben. Dafür ist ggf. ein zusätzlicher Parameter notwendig.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Variable Argumentanzahl==&lt;br /&gt;
== Funktionen indirekt aufrufen ==&lt;br /&gt;
Siehe [[#Zeiger auf Funktionen|Zeiger auf Funktionen]]&lt;br /&gt;
&lt;br /&gt;
=Zeiger II=&lt;br /&gt;
&lt;br /&gt;
Zeiger haben wir bereits weiter oben kennen gelernt. Zeiger sind ein zentrales Konzept in C und sollen hier etwas eingehender behandelt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger-Arithmetik==&lt;br /&gt;
In C kann man den Wert eines Zeigers verändern. Betrachten wir dazu die Funktion &amp;lt;tt&amp;gt;suche_0&amp;lt;/tt&amp;gt;, die einen Zeiger auf einen &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; erhält. Die Funktion soll ab der gegebenen Adresse nach dem ersten long-Wert suchen, der 0 ist, und dessen Adresse zurückgeben:&lt;br /&gt;
 long * suche_0 (long * addr)&lt;br /&gt;
 {&lt;br /&gt;
    while (*addr != 0)&lt;br /&gt;
       addr = addr + 1;&lt;br /&gt;
 &lt;br /&gt;
    return addr;&lt;br /&gt;
 }&lt;br /&gt;
In der Bedingung der while-Schleife wird der Inhalt an der Speicherstelle &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf 0 getestet. Ist der Wert 0, dann wird die Schleife beendet und die Adresse zurückgeliefert. Ist der Wert ungleich 0, dann wird &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf den nächste long gesetzt, &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; also um 4 Bytes weitergezählt. &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ist ja ein Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, und ein &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; ist 4 Bytes lang.&lt;br /&gt;
&lt;br /&gt;
Die Bedeutung von&lt;br /&gt;
 address + n&lt;br /&gt;
ist also, die Adresse um das &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;-fache der Größe des Typs, auf den &amp;lt;tt&amp;gt;address&amp;lt;/tt&amp;gt; zeigt, zu erhöhen. Dabei ist &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; eine ganze Zahl und darf auch negativ sein.&lt;br /&gt;
&lt;br /&gt;
Hier noch ein Beispiel einer Funktion, die nach einer Person mit einer bestimmten ID sucht (für die Definition von &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; siehe [[#Strukturen|Strukturen]]). Der Parameter &amp;lt;tt&amp;gt;person&amp;lt;/tt&amp;gt; ist dabei ein Array von Strukturen. Eine Person mit der gesuchten ID muss existieren, ansonsten hat die Suchfunktion kein definiertes Verhalten.&lt;br /&gt;
 {{comment|Sucht nach einer Person mit der ID person_id}}&lt;br /&gt;
 struct Person * &lt;br /&gt;
 suche_person_id (struct Person * person, int person_id)&lt;br /&gt;
 {&lt;br /&gt;
    while (person-&amp;gt;id != person_id)&lt;br /&gt;
       person++;&lt;br /&gt;
 &lt;br /&gt;
    return person;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:1em; padding:1em; border:solid 2px #FF0040;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- Vorlage:FarbigerRahmen funzt hier net --&amp;gt;&lt;br /&gt;
Beachte, daß es nicht sinnvoll ist, zwei Zeiger zu addieren oder zu multiplizieren. Ausserdem ist das &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt; der Zeiger-Arithmetik nicht kommutativ. Eine Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, der an Adresse 1 im Speicher zeigt, wird man schreiben als&lt;br /&gt;
 (long *) 1&lt;br /&gt;
Addiert man darauf eine ganze Zahl, dann haben die entstehenden Ausdrücke unterschiedliche Werte:&lt;br /&gt;
 (long *) 1 + 2    {{comment|zeigt zu Adresse 9}}&lt;br /&gt;
 (long *) 2 + 1    {{comment|zeigt zu Adresse 6}}&lt;br /&gt;
 (long *) (1 + 2)  {{comment|zeigt zu Adresse 3}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==void-Pointer==&lt;br /&gt;
Eine besondere Art von Zeiger ist der void-Pointer&lt;br /&gt;
 void * addr;&lt;br /&gt;
Ein void-Pointer ist ein &amp;quot;Zeiger auf irgendwas&amp;quot;, dementsprechend kann er nicht dereferenziert werden, Anwenden von &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf einen solchen Zeiger gibt also einen Fehler. Ausserdem ist es nicht möglich, mit einem void-Pointer Zeigerarithmetik zu machen, weil er nicht auf eine definierte Art von Objekt zeigt. Der Vorteil eines void-Pointers ist, daß er jede Art von Zeiger aufnehmen kann.&lt;br /&gt;
&lt;br /&gt;
Dazu betrachten wir die Funktion &amp;lt;tt&amp;gt;send_buf&amp;lt;/tt&amp;gt;, die eine Adresse erhält und ab dieser Adresse &amp;lt;tt&amp;gt;num&amp;lt;/tt&amp;gt; Bytes versenden soll. Wir könnten die Funktion so schreiben:&lt;br /&gt;
 void send_buf (unsigned char * buf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   ...&lt;br /&gt;
Das ist jedoch hässlich, wenn wir damit etwas anderes verschicken wollen als &amp;lt;tt&amp;gt; unsigned char&amp;lt;/tt&amp;gt;, etwa eine Struktur wie &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; (vom Typ &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;):&lt;br /&gt;
 send_buf ((unsigned char*) &amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
Ohne den Cast der Adresse von &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; zu einem Zeiger auf &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt; bekommt man eine Warnung oder gar einen Compilerfehler.&lt;br /&gt;
Dieses Zeiger gecaste ist mühsam und hässlich, es muss bei jedem Aufruf der Funktion explizit hingeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Besser ist es, den ersten Parameter der Funktion als void-Pointer zu definieren und den Cast in der Funktion zu machen:&lt;br /&gt;
 void send_buf (void * vbuf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   unsigned char *buf = (unsigned char*) vbuf;&lt;br /&gt;
   ...&lt;br /&gt;
Durch den Cast in der Funktion kann auf den Inhalt des Zeigers zugegriffen werden. Man muss nur festlegen, ''wie'' man zugreifen will, nämlich als &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Der Aufruf kann jetzt ohne Pointer-Cast erfolgen: &lt;br /&gt;
 send_buf (&amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
&lt;br /&gt;
==Null-Pointer==&lt;br /&gt;
==Zeiger als Parameter==&lt;br /&gt;
Wenn Sie ein Unterprogramm aufrufen, können Sie diesem Parameter übergeben, aber keine Werte zurückgekommen (außer den Funktionswert bei Funktionen). Dies hat einen guten Grund: beim Aufruf werden nicht die aufgerufenen Parameter benutzt, sondern es werden deren Werte in neue Variablen kopiert. Diese Variablen werden am Ende des Unterprogrammes &amp;quot;zerstört&amp;quot;, ohne ihre Werte an die aufrufenden Parameter zu übergeben. Jede Veränderung eines Parameters hat daher keine Auswirkung auf den Parameter.&lt;br /&gt;
&lt;br /&gt;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der C-Compiler legt dann immer noch Kopien an. In dieser Kopie steht aber kein Wert, sondern die Adresse einer Varaiblen. Und auf diese können Sie dann zugreifen. Denken Sie nur an &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; &amp;amp;ndash; da übergeben Sie ja auch die Adresse einer Variablen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void erhoehe (int *zeiger)&lt;br /&gt;
{&lt;br /&gt;
  *zeiger = 1 + *zeiger;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  erhoehe (&amp;amp;zahl);&lt;br /&gt;
  printf (&amp;quot;\nDie erhoehte Zahl lautet: %d\n&amp;quot;, zahl);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Zeiger auf Funktionen==&lt;br /&gt;
&lt;br /&gt;
Stell dir vor, du willst einen Sortieralgorithmus wie Bubble-Sort oder Quick-Sort oder wie sie alle heissen implementieren. Für den Sortieralgorithmus ist eigentlich egal, ''was'' er zu sortieren hat. Ihm ist es egal, ob er Zahlen aufwärts sortieren soll oder Strings in lexikographischer Reihenfolge, ob Objekte nach Größe oder Gewicht, Personen nach Alter oder Adressen nach Postleitzahl. Das einzige, was der Algorithmus wissen muss, ist ''wie'' er zwei Objekte zu vergleichen hat und wann eines davon &amp;quot;kleiner&amp;quot; (im Sinne der Ordnung, nach der sortiert werden soll) ist. &lt;br /&gt;
&lt;br /&gt;
Eine einfache Sortierfunktion, die nur zwei Zahlen sortiert, könnte man also so schreiben: &lt;br /&gt;
 {{comment|Sortiert ein Array von 2 int-Zeigern nach den Inhalten &lt;br /&gt;
  * an den Zeiger-Adressen}}&lt;br /&gt;
 void sort2_a (int * p[])&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Inhalte vergleichen...}}&lt;br /&gt;
    if (*p[0] &amp;gt; *p[1])&lt;br /&gt;
    {&lt;br /&gt;
       {{comment|... und ggf. Dreieckstausch der 2 Zeiger}}&lt;br /&gt;
       int * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Die Funktion bekommt ein Array der Länge&amp;amp;nbsp;2. In diesem Array stehen Zeiger auf die zu sortierenden Zahlen. Ein Array mit Zeigern zu verwenden und nicht ein Array von &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; scheint recht umständlich, und das ist es hier auch. Aber stell dir vor, du willst Strukturen wie &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; sortieren. Das Tauschen zweier Strukturen würde bedeuten, ihre kompletten Inhalte umzukopieren! Das wäre sehr aufwändig. Viel einfacher ist das Kopieren, wenn nur die Adressen zu kopieren sind.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; könnte dann so aussehen:&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void sortiere (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|p[] enthält 2 int-Zeiger: die Adressen von a und b}}&lt;br /&gt;
    int * p[2];&lt;br /&gt;
    p[0] = &amp;amp;a; &lt;br /&gt;
    p[1] = &amp;amp;b; &lt;br /&gt;
 &lt;br /&gt;
    {{comment|Sortiere die Zeiger}} &lt;br /&gt;
    sort2_a (p);&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Sortiert: %d, %d\n&amp;quot;, *p[0], *p[1]);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Für den nächsten Schritt überlegen wir uns, daß das Array in &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; ebensogut void-Pointer enthalten kann. Die einzige Stelle, an der wir auf die endgültigen int-Objekte zugreifen, ist der Vergleich. Diesen Vergleich lagern wir in die Funktion &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; aus:&lt;br /&gt;
 {{comment|Bekommt zwei void-Pointer und vergleicht die Inhalte.&lt;br /&gt;
  * Liefert 0 bei Gleichheit,&lt;br /&gt;
  * -1 wenn der erste Wert kleiner ist als der zweite und&lt;br /&gt;
  * 1  wenn der erste Wert größer ist als der zweite}}&lt;br /&gt;
 int compare_int (void * p0, void * p1)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Um über die Zeiger zugreifen zu können müssen wir diese&lt;br /&gt;
     * erst zu int-Zeigern casten}}&lt;br /&gt;
    int a0 = * (int*) p0;&lt;br /&gt;
    int a1 = * (int*) p1;&lt;br /&gt;
 &lt;br /&gt;
    if (a0 &amp;gt; a1)  return  1;&lt;br /&gt;
    if (a0 &amp;lt; a1)  return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void sort2_b (void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare_int (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Ein Aufruf von &amp;lt;tt&amp;gt;sort2_b&amp;lt;/tt&amp;gt; sieht dann genauso aus wie ein Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt definieren wir uns den neuen Datentyp &amp;lt;tt&amp;gt;comparator_t&amp;lt;/tt&amp;gt;. Dieser ist ein Zeiger auf eine Funktion, die zwei void-Pointer erhält und einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; zurückliefert, also analog arbeitet zu &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; von oben. &lt;br /&gt;
&lt;br /&gt;
Unsere Sortierfunktion bekommt nun neben dem zu sortierenden Zeiger-Array auch eine Vergleichsfunktion &amp;lt;tt&amp;gt;compare&amp;lt;/tt&amp;gt; mitgeliefert, die sie aufruft, wenn sie zwei Objekte vergleichen will&lt;br /&gt;
 {{comment|comparator_t sind Zeiger auf Funktionen, die 2 void-Pointer&lt;br /&gt;
  * erhalten und einen int zurückliefern}}&lt;br /&gt;
 typedef int (*comparator_t) (void*, void*);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Der Sortierer bekommt einen Funktionszeiger auf den Vergleicher.&lt;br /&gt;
  * Der Aufruf vom compare geht so als wäre es eine &amp;quot;normale&amp;quot; Funktion&lt;br /&gt;
  * (ist es im Endeffekt ja auch)}}&lt;br /&gt;
 void sort2_c (comparator_t compare, void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Bei einem Aufruf von &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; muss man dann einen Komparator mit angeben. In einem Beispiel analog zu &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; von oben ist das:&lt;br /&gt;
 sort2_c (compare_int, p);&lt;br /&gt;
Um zwei Strings lexikographisch zu sortieren nehmen wie die Standard-Funktion &amp;lt;tt&amp;gt;strcmp&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void foo()&lt;br /&gt;
 {&lt;br /&gt;
    char * worte[] = { &amp;quot;Wort1&amp;quot;, &amp;quot;Wort2&amp;quot; };&lt;br /&gt;
 &lt;br /&gt;
    sort2_c ((comparator_t) strcmp, (void**) worte);&lt;br /&gt;
 }&lt;br /&gt;
Die Casts sind hier erforderlich. Alternativ könnte man &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; mit reinen void-Pointern versorgen und diese dann dort umcasten.&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
&lt;br /&gt;
Die Syntax zur Definition/Deklaration von Funktionszeigern ist etwas verzwackt. Zur Verdeutlichung ein paar Beispiele. Dabei legt das linke &amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt; jeweils den Return-Typ fest.&lt;br /&gt;
 {{comment|definiert einen neuen Funktionszeiger-Typ}}&lt;br /&gt;
 typedef {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert einen Funktionszeiger}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert ein Array von Funktionszeigern (mit Initializer)}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}[]) ({{type}}, {{type}}, ...) = { wert1, wert2, ... };&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer}}&lt;br /&gt;
 ({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer und ruft die Funktion auf}}&lt;br /&gt;
 (({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}) (arg1, arg2, ...);&lt;br /&gt;
&lt;br /&gt;
=Standard-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==String-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===strcpy===&lt;br /&gt;
Bei vielen Compilern können sie einem String nicht direkt einen Wert (Text) zuweisen. Dazu müssen Sie dann die Prozedur strcpy() benutzen. Diese erwartet als ersten Parameter den Namen einer String-Variablen (ohne eckige Klammern) und als zweiten Parameter den eines (anderen) Strings. Letzterer kann auch ein in doppelten Hochkommas (&amp;quot;) eingeschlossener Text sein. Die Funktion fügt am Ende automatisch ein 0-Zeichen ein. Um diese Funktion nutzen zu können, müssen Sie die Datei string.h includieren! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri1[21], eingabe[21];&lt;br /&gt;
&lt;br /&gt;
  strcpy (stri1, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Der 1. String: %s\n&amp;quot;, stri1);&lt;br /&gt;
  printf (&amp;quot;Bitte geben Sie maximal 20 Zeichen ein: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%s&amp;quot;, eingabe);&lt;br /&gt;
  strcpy (stri1, eingabe);&lt;br /&gt;
  printf (&amp;quot;\n%s = %s&amp;quot;, stri1, eingabe);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis:''' &lt;br /&gt;
Da ein String, wie jedes Feld, eigentlich ein Zeiger ist, dürfen Sie kein &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; bei &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; angeben!&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
Es werden zwei gleich große Strings definiert: &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;eingabe&amp;lt;/tt&amp;gt;, mit je 20 &amp;quot;nutzbaren&amp;quot; Zeichen. &lt;br /&gt;
In &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; wird die Zeichenkette &amp;lt;tt&amp;gt;&amp;quot;hallo&amp;quot;&amp;lt;/tt&amp;gt; hineinkopiert. Das 0-Zeichen am Ende wird automatisch angefügt. &lt;br /&gt;
Der String wird ausgegeben. Als neues &amp;quot;Sonderzeichen&amp;quot; kommt &amp;lt;tt&amp;gt;%s&amp;lt;/tt&amp;gt; ins Spiel. Es hat die gleiche Aufgabe wie &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt;, nur für Strings. &lt;br /&gt;
Sie werden gebeten, eine String einzugeben. &lt;br /&gt;
Dieser String wird danach in die Variable &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; kopiert. &lt;br /&gt;
Beide Strings, die ja nun die gleiche Zeichenkette enthalten, werden ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===strlen===&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;strlen&amp;lt;/tt&amp;gt;, die als Parameter eine String-Variable erwartet, liefert die Länge diese Strings zurück. Sie werden jetzt vermutlich sagen: &amp;quot;Das ist doch klar, wie lang der String ist. Ich habe es ja bei der Deklaratin angegeben&amp;quot;. Das stimmt schon, aber denken Sie noch einmal an die null-terminierten Strings. Das 0-Zeichen steht am Ende des Strings (am Ende der gültigen Zeichenfolge), aber nicht unbedingt am Ende des reservierten Speicherplatzes. Haben Sie eine Variable &amp;quot;char Variable[21];&amp;quot;, und ihr den Wert &amp;quot;hallo&amp;quot; zugewiesen, dann steht das null-Zeichen in Variable[5]. Der &amp;quot;gültige&amp;quot; String ist also 5 Zeichen (0-4) lang. Und genau das (5) würde strlen zurück liefern. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri[21];&lt;br /&gt;
  &lt;br /&gt;
  strcpy (stri, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
  printf (&amp;quot;Der String ist %d Zeichen lang&amp;quot;, strlen (stri));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird vor allem gebraucht, wenn Sie direkt auf den String zugreifen, mittels &amp;lt;tt&amp;gt;stri[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;stri[1]&amp;lt;/tt&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
==Ein- und Ausgabe-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===Bildschirm-Ausgabe===&lt;br /&gt;
Bisher war das Tutorial trotz aller Beispiele reine Theorie. Sie konnten zwar Programme schreiben, aber die Funktion nicht testen. Hier lernen Sie nun, wie Sie etwas am Bildschirm ausgeben.&lt;br /&gt;
&lt;br /&gt;
Die dazu notwendige Funktione heisst &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (das '&amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt;' ist kein Fehler!). Diese Anweisung gibt die ihr übergebenen Parameter auf das Standard-Ausgabegerät aus, in der Regel also auf den Bildschirm. Sie kann beliebig viele Parameter übernehmen. Es müssen jedoch Standard-Datentypen (z.B. &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;...) sein! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
    int zahl1 = 12;&lt;br /&gt;
    char zeichen1 = 'A';&lt;br /&gt;
    &lt;br /&gt;
    printf (&amp;quot;Das ist Text, und er wird als solcher ausgegeben. \n&amp;quot;);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zahl1' ist: %d \n&amp;quot;, zahl1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %c \n&amp;quot;, zeichen1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %d \n&amp;quot;, zeichen1);&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt Text aus. Das Zeichen am Ende (&amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;) bedeutet &amp;quot;New Line&amp;quot;, es bewegt den Cursor an den Anfang der nächsten Zeile. &lt;br /&gt;
&lt;br /&gt;
Der zweite &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt auch Text aus, am Ende befindet sich wieder das &amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;, um einen Zeilenvorschub zu erreichen. Das &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; wird vom Compiler durch den ersten Parameter ersetzt, der nach dem Text angegeben wird. In diesem Fall wird &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; also durch den Wert der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ersetzt. Das &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; im &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; bedeutet &amp;quot;Dezimalzahl&amp;quot;, der Computer gibt also eine ganze Zahl aus. &lt;br /&gt;
&lt;br /&gt;
In der dritten Ausgabe wird ein Zeichen ausgegeben. Diesmal bedeutet &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; &amp;quot;char&amp;quot; (Zeichen). Es wird also &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; durch ein &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt; ersetzt, denn die Variable &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; wird als Character interpretiert. &lt;br /&gt;
&lt;br /&gt;
Die letzte Ausgabe interpretiert den Inhalt von &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; als Zahl, und gibt dager den ASCII-Wert von &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, also 65 aus. Das ist ein typisches Beispiel für das mögliche unterschiedliche Interpretieren einer  Variablen!&lt;br /&gt;
&lt;br /&gt;
===Tastatur-Eingabe===&lt;br /&gt;
&lt;br /&gt;
Um ein &amp;quot;gscheites&amp;quot; Programm schreiben zu können, muß man wissen, wie der Benutzer über die Tastatur Befehle eingeben kann. Die dafür notwendigen Funktionen stelle ich in diesem Kapitel vor.&lt;br /&gt;
Die wichtigste Funktion ist &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt;. Er liest Daten von der Tastatur. Die Syntax entspricht derer von &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int  zahl1;&lt;br /&gt;
char zeichen1;&lt;br /&gt;
&lt;br /&gt;
printf (&amp;quot;Bitte geben Sie eine Zahl ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl1);&lt;br /&gt;
printf (&amp;quot;Geben Sie einen Zeichen ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%c&amp;quot;, &amp;amp;zeichen1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Programm gibt eine Eingabeaufforderung aus. Dann erwartet es vom Benutzer, daß er eine Zahl eingibt, die mit [ENTER] bestätigt wird. Dieser Wert wird in &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; abgespeichert. Danach erfolgt wiederum eine Aufforderung zur Eingabe, diesmal eines einzelnen Zeichens. Dieses kann man nun eingeben und ebenfalls mit [ENTER] bestätigen.&lt;br /&gt;
&lt;br /&gt;
Macht man keine dem Datentyp der erwarteten Variable entsprechende Eingabe, dann bricht das Programm mit einer Fehlermeldung ab (wenn man z.B. &amp;quot;1_T2&amp;quot; eingibt, wenn eine Zahl erwartet wird)!&lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; vor den Parametern ist notwendig. Warum, das erfahren Sie im Kapitel &amp;quot;Unterprogramme&amp;quot;. Für die Profis eine Kurz-Erklärung: Das Unterprogramm &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; bekommt zwar einen Wert übergeben, kann aber keinen zurückliefern (&amp;quot;call by value&amp;quot;). Daher wird kein Wert, sondern ein Zeiger auf eine Variable übergeben. Mit dem &amp;amp; Zeichen bekommen Sie die Adresse einer Variablen (&amp;quot;call by reference&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=Parameter von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;=&lt;br /&gt;
Das Unterprogramm &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; kann, wie jede andere Funktion, Parameter besitzen. Doch keine selbst gewählten, sondern nur bestimmte. Doch warum braucht main Parameter? Denken Sie einmal an alle Betriebssystembefehle:&lt;br /&gt;
&amp;lt;tt&amp;gt;dir *.exe &amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;copy *.* a:&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;ls -la &amp;lt;/tt&amp;gt;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;&amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen!&lt;br /&gt;
&lt;br /&gt;
=Kurzreferenz=&lt;br /&gt;
==Syntax-Bausteine==&lt;br /&gt;
&lt;br /&gt;
Die Erklärung des Aufbaus von C-Befehlen erfolgt neben einfachen Beispielen auch durch ihren prinzipellen Aufbau. In diesen Syntax-Beschreibungen finden sich immer wieder die gleichen Bausteine, die hier näher erklärt werden sollen. Falls die solch ein Syntax-Baustein begegnet, kannst Du ihn anclicken und kommst dann zu seiner Erläuterung. &lt;br /&gt;
&lt;br /&gt;
In den Beispielen selbst gehören auch die spitzen Klammern zu dem Baustein (was daran zu erkennen ist, daß auch die Klammern eingefärbt sind). Die Klammern dürfen in einem konkreten C-Programm daher nicht eingetippt werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bezeichner&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Bezeichner in C dienen dazu, Variablen zu identifizieren und ihnen sprechende Namen zu geben, um die Quelle lesbarer zu machen. Man braucht Bezeichner auch, um selbstdefinierte Datentypen zu benennen und zum Benennen von Struct- und Union-Komponenten sowie als Namen für Funktionen und Sprungmarken (Labels).&lt;br /&gt;
&lt;br /&gt;
Bezeichner dürfen aus den Kleinbuchstaben &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;z&amp;lt;/tt&amp;gt;, den Großbuchstaben &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;Z&amp;lt;/tt&amp;gt;, dem Unterstrich&amp;amp;nbsp;&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt; und den Ziffern &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;9&amp;lt;/tt&amp;gt; aufgebaut werden, wobei an erster Stelle jedoch keine Ziffer stehen darf.&lt;br /&gt;
&lt;br /&gt;
Es wird zwischen Groß- und Kleinschreibung unterschieden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Ausdruck in C ist ein Konstrukt, das einen Wert hat. Ob dieser Wert eine ganze Zahl ist, eine Kommazahl oder ein Zeiger, etc. ist dabei egal. Die einfachsten Ausdrücke sind Konstanten wie&lt;br /&gt;
 2&lt;br /&gt;
oder Variablen wie&lt;br /&gt;
 ein_zahl&lt;br /&gt;
Mehrere Ausdrücke können durch [[#Liste der Operatoren|Operatoren]] zu komplexeren Ausdrücken kombiniert werden, etwa&lt;br /&gt;
 eine_zahl + andere_zahl == 2&lt;br /&gt;
oder &lt;br /&gt;
 eine_zahl = 2&lt;br /&gt;
Letzterer hat den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; und den Nebeneffekt, daß er diesen Wert an &amp;lt;tt&amp;gt;eine_zahl&amp;lt;/tt&amp;gt; zuweist.&lt;br /&gt;
&lt;br /&gt;
Auch der Aufruf einer Funktion, die einen Rückgabewert liefert, ist ein Ausdruck:&lt;br /&gt;
 sin (1.2)&lt;br /&gt;
und kann zum Aufbau komplexerer Ausdrüche verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bedingung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Bedingung ist ein Ausdruck, bei der nur interessiert, ob dieser zu&amp;amp;nbsp;0 (unwahr) auswertet oder zu ungleich&amp;amp;nbsp;0 (wahr). Solche Ausdrücke findet man in if-Anweisungen, in Schleifenbedingungen und bedingten Zuweisungen&lt;br /&gt;
 (ein_wert &amp;lt; 2) || (ein_wert &amp;gt; 40)&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Lvalue ist ein Ausdruck, dem etwas zugewiesen werden kann. Der Name ''Lvalue'' kommt aus dem Englischen. Das ''L'' steht abkürzend für left. Ein Lvalue ist damit ein Ausdruck, der auf der linken Seite eine Zuweisung in C stehen darf. Das &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; in den folgenden Beispiel-Ausdrücken muss ein Lvalue sein:&lt;br /&gt;
 x = y-1&lt;br /&gt;
&lt;br /&gt;
 x++&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Konstante&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Konstante ist ein Ausdruck, dessen Wert dem Compiler bekannt ist. Beispiele für Konstanten sind etwa&lt;br /&gt;
 7&lt;br /&gt;
 'B'&lt;br /&gt;
 -13.98e12&lt;br /&gt;
 1+(2*3)&lt;br /&gt;
und die Werte von [[#Enum|Enum]]s. &lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; aus dem folgenden Codestück definiert jedoch keine Konstante in diesem Sinne&lt;br /&gt;
 const double Pi = 3.14159256;&lt;br /&gt;
denn in einem anderen Quellmodul könnte durch die Deklaration&lt;br /&gt;
 extern const double Pi;&lt;br /&gt;
das Symbol &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; bekannt sein, ohne daß sein Wert bekannt ist!&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Adresse&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Adresse ist ein Ausdruck, der einen Speicherort (physikalisch oder virtuell) halten kann. Adressen erhält man dadurch, daß man einem Bezeichner den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt;voranstellt, Adressen durch Arithmetik berechnet oder Zahlen zu Adressen castet. Folgende Ausdrücke sind Adressen (eine sinnvolle Deklaration der auftretenden Variablen vorausgesetzt)&lt;br /&gt;
 &amp;amp; eine_zahl&lt;br /&gt;
 &amp;amp; ein_array[10]&lt;br /&gt;
 &amp;amp; ein_struct&lt;br /&gt;
 &amp;amp; ein_struct.komponente&lt;br /&gt;
 (int *) 0x1234&lt;br /&gt;
 (int *) eine_zahl&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Deklaration&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Anweisungen sind gewissermassen die Atome (oder Moleküle?), aus denen ein C-Programm besteht. Jedes C-Programm ist eine Abfolge von Deklarationen und Anweisungen. Einfache Anweisungen erhält man, in dem man einen Ausdruck nimmt und einen Strichpunkt dahinter schreibt:&lt;br /&gt;
 {{Ausdruck|}};&lt;br /&gt;
wie in&lt;br /&gt;
 x = x+1;&lt;br /&gt;
&lt;br /&gt;
Andere Anweisungen sind die unten aufgeführten Schleifen und die if- sowie die switch-Anweisung.&lt;br /&gt;
&lt;br /&gt;
Mehrere Deklarationen und Anweisungen können zu einem Block zusammengefasst werden. Dieser Block stellt dann wieder eine einzelne Anweisung dar und kann genau so gehandhabt werden!&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
In diesem Sinne ist auch z.B. die Syntax der if-Anweisung zu verstehen&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
besagt, daß der abhängig ausgeführte Code eine einzelne Anweisung sein darf oder eben ein kompletter Block oder die Verschachtelung mehrerer Blöcke etc.&lt;br /&gt;
&lt;br /&gt;
Eine Anweisung kann auch &amp;quot;leer&amp;quot; sein, also nichts tun. Diese Anweisungen sind der leere Block&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
und der Strichpunkt&lt;br /&gt;
 ;&lt;br /&gt;
die man gelegentlich in Schleifen findet:&lt;br /&gt;
 while (!timeout())&lt;br /&gt;
    {}&lt;br /&gt;
oder hinter Sprungmarken, die sonst direkt vor einer schliessenden Blockklammer stünden:&lt;br /&gt;
 {&lt;br /&gt;
    ...&lt;br /&gt;
    goto ein_label;&lt;br /&gt;
    ...&lt;br /&gt;
    {{Label|ein_label}}:;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Nicht jede Anweisung ist an jeder Stelle eines C-Programms erlaubt, so darf ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; nut innerhalb einer Schleife stehen. Gleiches gilt für &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;, das aber auch innerhalb eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; vorkommen darf.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Dies steht für einen Datentyp. Es kann ein elementarer Typ sein wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;, ein Zeiger darauf wie &amp;lt;tt&amp;gt;char*&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;void*&amp;lt;/tt&amp;gt;, und auch Qualifier enthalten wie das &amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt; im Typ &amp;lt;tt&amp;gt;unsigned long long&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Zu den Typen gehören auch zusammengesetzte Datentypen wie Strukturen und Unions, mit &amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt; selbst definierte Typen und natürlich Zeiger darauf, wie aus dem Abschnitt [[#Datentypen|Datentypen]]:&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person *&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;data32_t&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;&lt;br /&gt;
und Zeiger auf Funktionen.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Parameterliste&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
Die Parameterliste bei einer Funktionsdefinition gibt an, wieviel Übergabeparameter sie bekommt, wie diese heissen und welchen Typs diese sind. Der prinzipielle Aufbau ist&lt;br /&gt;
 {{Type}} {{Bezeichner}}, {{Type}} {{Bezeichner}}, ...&lt;br /&gt;
Falls die Funktion keine Parameter hat, dann ist die Parameterliste leer.&lt;br /&gt;
&lt;br /&gt;
Hier als Beispiel die zweiparametrige Funktion &amp;lt;tt&amp;gt;produkt&amp;lt;/tt&amp;gt;. Der erste Parameter heisst&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und ist ein &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;. Der zweite namens&amp;amp;nbsp;&amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; ist vom Typ &amp;quot;Zeiger auf double&amp;quot;, der Inhalt &amp;lt;tt&amp;gt;*b&amp;lt;/tt&amp;gt; ist also auch ein double.&lt;br /&gt;
&lt;br /&gt;
'''Definition der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b)&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
In älteren C-Quellen findet man noch eine andere Syntax für die Deklaration der Parameter, die aber heute praktisch nicht mehr verwendet wird:&lt;br /&gt;
'''alte Definition der Funktion:'''&lt;br /&gt;
 double produkt (a, b)&lt;br /&gt;
 double a, *b;&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Um die Funktion bekannt zu machen, werdendet man eine Deklaration bzw. den Prototypen, der dem Compiler nur mitteilt, welche Parameter die Funktion bekommt und was sie zurückliefert. Für den Aufruf der Funktion muss der Compiler nur diesen Prototyp kennen, ''was'' die Funktion im Endeffekt macht und wie sie implementiert wurde ist egal, sie wird als BlackBox angesehen.&lt;br /&gt;
&lt;br /&gt;
'''Prototyp der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b);&lt;br /&gt;
Hier dürfen die Bezeichner auch fehlen:&lt;br /&gt;
 double produkt (double, double*);&lt;br /&gt;
&lt;br /&gt;
==if==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==if-else==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==for==&lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Eine for-Schleife entspricht folgendem Konstrukt. Dabei sind die drei Ausdrücke optional. Fehlt die Bedingung, dann wird diese als &amp;quot;wahr&amp;quot; angenommen. Die beiden anderen Ausdrücke wird man als Ausdrücke mit Nebeneffekt wählen wie z.B. &amp;lt;tt&amp;gt;x=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;x=x-2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
 {&lt;br /&gt;
    {{Ausdruck|1}};&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_loop}}:&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
    else&lt;br /&gt;
       goto _break;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_continue}}:&lt;br /&gt;
    {{Ausdruck|2}};&lt;br /&gt;
    goto _loop;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_break}}:;&lt;br /&gt;
 }&lt;br /&gt;
Die Labels &amp;lt;tt&amp;gt;_break&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_continue&amp;lt;/tt&amp;gt; entsprechen den Sprungzielen einer &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Anweisung innerhalb von &amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==do-while==&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while  ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
==while==&lt;br /&gt;
 while  ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==switch==&lt;br /&gt;
 switch  ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    ...&lt;br /&gt;
  &lt;br /&gt;
    default:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#break-Anweisung|&amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Konstanten|&amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#continue-Anweisung|&amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#do-while-Schleife|&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Enum|&amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#for-Schleife|&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#goto-Anweisung|&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#return-Anweisung|&amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Liste der Operatoren|sizeof]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Strukturen|&amp;lt;tt&amp;gt;struct&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Eigene Datentypen|&amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Unions|&amp;lt;tt&amp;gt;union&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#while-Schleife|&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund2}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Arithmetische Operatoren&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Dies sind die &amp;quot;normalen&amp;quot; arithmetischen Operationen, wie man sie aus der Schule kennt. Man kann damit und allen anderen Operatoren auch komplexere Ausdrücke aufbauen. Die Prioritäten sind so, wie man sie kennt, also &amp;quot;Punktrechnung vor Strichrechnung&amp;quot;. Will man dies ändern, dann mit den runden Klammern:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;1+2*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 7&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(1+2)*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 9&amp;lt;br/&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}}&amp;amp;nbsp;+&amp;amp;nbsp;{{Ausdruck|}}&amp;lt;/tt&amp;gt; || Addition&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} - {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Subtraktion&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} * {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Multiplikation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} / {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Division&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} % {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Rest der Division (modulo)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;- {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Vorzeichenumkehr, Zweier-Komplement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Logische Operatoren und Vergleiche&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die logischen und die vergleichenden Operatoren liefern als Ergebnis den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (wahr) oder einen Wert ungleich&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (falsch, um genau zu sein den Wert &amp;lt;tt&amp;gt;!0&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Man kann das Ergebnis zwar einer Variablen zuweisen, in aller Regel wird man solche Ausdrücke jedoch in Bedingungen zu &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder in Abbruch-Bedingungen von Schleifen finden.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;&amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches AND: beides wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124;&amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches OR: mind. eines ist wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;! {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches NOT (0 &amp;amp;harr; ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} == {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} != {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist nicht gleich&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bitweise Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~ {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise NOT (Einser-Komplement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise AND&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise ODER&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} ^ {{Ausdruck|}}&amp;lt;/tt&amp;gt; ||bitweise XOR&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Shift-Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;lt;&amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Bits nach links schieben&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;gt;&amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Schieben nach rechts schieben&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Typen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Ein Cast in C kann dazu verwendet werden, den Typ eines Ausdruckes zu ändern oder den Ausdruck mit einer bestimmten Genauigkeit zu berechnen. Wird z.B. eine Berechnung standardmässig in 16 Bit ausgeführt, dann kann man mit einem Cast &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(long) &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
ausdrücken, daß die Berechnung in 32 Bit erfolgen soll. Des weiteren kann man Zeiger und ganze Zahlen und Gleitkommazahlen ineinander umwandeln.&lt;br /&gt;
&lt;br /&gt;
Casts können ''nicht'' dazu verwendet werden, um z.B. eine Zahl in einen String zu konvertieren, der diese Zahl darstellt! Dafür gibt es spezielle Funktionen wie &amp;lt;tt&amp;gt;itoa&amp;lt;/tt&amp;gt;!&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Type}}) {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Cast, Typwandlung&lt;br /&gt;
|-&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;| &amp;lt;tt&amp;gt;sizeof ({{Type}})&amp;lt;/tt&amp;gt; || Eine Konstante, deren Wert die Größe (in Bytes) des Typs ist. &amp;lt;tt&amp;gt;sizeof&amp;lt;/tt&amp;gt; ist auch auf Objekte anwendbar wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, Arrays bekannter Größe, Strukturen und Unions,  Array-, Struktur- und Union-Komponenten, Pointer, etc. Beispiel:&amp;lt;br/&amp;gt;&lt;br /&gt;
 int i, sum=0, array[] = { 1, -13, 4, 0, sizeof (int*) };&lt;br /&gt;
 &lt;br /&gt;
 for (i=0; i&amp;lt; sizeof (array) / sizeof (array[0]); i++)&lt;br /&gt;
    sum += array[i];&lt;br /&gt;
Alle Elemente des Arrays werden aufaddiert, ohne daß deren Anzahl explizit in der Schleife genannt ist.&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zeiger und Adressen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;* {{Adresse}}&amp;lt;/tt&amp;gt; || der Inhalt an Adresse&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp; {{Lvalue}}&amp;lt;/tt&amp;gt; || Adresse von&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Strukturen, Unions, Arrays&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Struct&amp;gt;}}.{{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Zeiger-auf-Struct&amp;gt;}} -&amp;gt; {{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union, deren Adresse man hat&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Adresse}}&amp;amp;#91;{{Ausdruck|}}&amp;amp;#93;&amp;lt;/tt&amp;gt; || Array-Element&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bedingte Auswertung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Bedingung}}) ? {{Ausdruck|}} : {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Auswahl des Wertes abhängig von der Bedingung&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zuweisung und Operatoren mit Nebeneffekt&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die Unterschiede der post- und pre-Varianten der Increment/Decrement kommen in Konstrukten wie &amp;lt;tt&amp;gt;x = *p++&amp;lt;/tt&amp;gt; zum tragen:&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *p++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; p = p+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *++p;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; p = p+1; x = *p;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = (*p)++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; *p = (*p)+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = ++(*p);&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; *p = (*p)+1; x = *p;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} = {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Zuweisung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++ {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-- {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Decrement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ++&amp;lt;/tt&amp;gt; || Post-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} --&amp;lt;/tt&amp;gt; || Post-Decrement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Kurzschreibweisen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Für ganz Faule gibt es anstatt&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a = a @ b&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
für viele Operatoren (hier dargestellt durch ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;@&amp;lt;/tt&amp;gt;) die abkürzende Schreibweise&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a @= b&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} += {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} -= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} *= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} /= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} %= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ^= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;lt;&amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;gt;&amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Autoren'''&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
* Kernighan und Ritchie - Buch&lt;br /&gt;
* Christian Wirth , C Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://wwwuser.gwdg.de/~kboehm/ebook/inhalt.html C-Programmieren unter Linux]&lt;br /&gt;
* [http://www.gdv.uni-hannover.de/documentation.php Skripte zum Selbststudium: C, C++, Java, etc]&lt;br /&gt;
* [http://info.baeumle.com/ansic.html Einführung in ANSI-C]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Quellcode C|!]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Inrfb2</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10393</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10393"/>
				<updated>2007-03-13T11:09:53Z</updated>
		
		<summary type="html">&lt;p&gt;Inrfb2: /* Reihenfolge der Auswertung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Programmiersprache C wurde 1971 als Gundlage für das Betriebssystem UNIX in den USA entwickelt (UNIX ist zu über 90% in C geschrieben). 1978 wurde von Brian Kernighan und Dennis Ritchie eine eindeutige Sprachdefinition entwickelt. Mittlerweile ist C von ANSI und ISO standardisiert.&lt;br /&gt;
&lt;br /&gt;
Heute sind C und ihr Nachfolger C++ die dominierenden Programmiersprachen. Sehr viele Anwendungen sind in C geschrieben, was inzwischen auch auf eingebettete Systeme zutrifft, die lange in Assembler programmiert werden mussten, da keine ausreichend leistungsfähigen Compiler zur Verfügung standen. &lt;br /&gt;
&lt;br /&gt;
Leider ist C nicht einfach zu lernen &amp;amp;ndash; es wurde weder von noch für Hobby-Programmierer entwickelt &amp;amp;ndash; und eignet sich daher nur bedingt für den Einsteiger. Mit etwas Übung und einem optimierenden Compiler kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
Vom Design her ist C eine Hardware-unabhängig Sprache. Das bedeutet, daß C-Programme mit vertretbarem Aufwand auf ein anderes System portiert werden können. Dazu benötigt man lediglich einen anderen Compiler, und Inline-Assembler-Anweisungen (Assembleranweisungen innerhalb eines C-Programmes) müssen der neuen Hardware (Prozessor) angepasst werden. &lt;br /&gt;
&lt;br /&gt;
==Geschichte==&lt;br /&gt;
;1971: C wird entwickelt&lt;br /&gt;
;1978: Kernighan und Ritchie definieren die Sprache.&lt;br /&gt;
;1983: ANSI und ISO standardisieren C.&lt;br /&gt;
;1992: Bjarne Stroustrup enwickelt die Nachfolgesprache C++.&lt;br /&gt;
&lt;br /&gt;
=Aufbau eines C-Programmes=&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
   C-Programme haben keinen fixen Aufbau wie z.B. Pascal. Es gibt zwar gewisse Regeln, aber sonst sind dem Programmierer alle Freiheiten überlassen. Der folgende &amp;quot;Beispiel-Aufbau&amp;quot; ist daher nicht zwingend und kann durchaus verändert werden.&lt;br /&gt;
&lt;br /&gt;
   Natürlich haben C-Programme einen fixen Aufbau! Ebenso wie Pascal-Programme auch unterliegen sie einer strikten Grammatik! &lt;br /&gt;
Auskommentiert --[[Benutzer:SprinterSB|SprinterSB]] 10:23, 17. Feb 2006 (CET)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Ein einfaches C-Programm könnte folgendermassen aussehen. Das Programm tut eigentlich nichts, aber das Beispiel zeigt den prinzipiellen Aufbau. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 int Zahl1;&lt;br /&gt;
 char Zeichen1;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int zahl2;&lt;br /&gt;
 &lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Beschreibung:'''&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndash; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
 {{comment|void-Definition von main ist nur beim Controller ueblich}}&lt;br /&gt;
 {{comment|spezielle Compilereinstellungen sind noetig, damit bei dieser Definition von main}}&lt;br /&gt;
 {{comment|kein Fehler/Warnung erzeugt wird.}}&lt;br /&gt;
 void main ()&lt;br /&gt;
 {&lt;br /&gt;
     ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
 int main (void)&lt;br /&gt;
 {  {{comment|der Block &amp;quot;main&amp;quot; beginnt}}&lt;br /&gt;
    int zahl;&lt;br /&gt;
    &lt;br /&gt;
    {   {{comment|ein Block beginnt}}&lt;br /&gt;
        {{comment|hier koennen Deklarationen und Anweisungen stehen}}&lt;br /&gt;
    }   {{comment|der Block endet}}&lt;br /&gt;
   &lt;br /&gt;
    return 0;&lt;br /&gt;
 }  {{comment|&amp;quot;main&amp;quot; endet}}&lt;br /&gt;
&lt;br /&gt;
=Datentypen=&lt;br /&gt;
==Elementare Datentypen==&lt;br /&gt;
Der Datentyp einer Variable gibt an, welche Werte eine Variable enthalten kann, welcher Art diese Daten sind und wie sie verarbeitet werden, etwa in arithmetischen Operationen wie einer Addition. So ist es zum Beispiel möglich, in eine Variable vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ganze Zahlen zwischen ca. -32000 und +32000 einzutragen. In einer char-Variable können ASCII-Zeichen gespeichert werden (alles, was Sie mit der Tastatur erzeugen können) oder ganze Zahlen von -128 bis 127.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da C plattformabhängig ist, hängt die Größe eines Datentypes zum Teil von der genutzten Hardware (z.B. 8, 16 oder 32 Bit-Controller) und dem Compiler und dessen Einstellungen ab!&lt;br /&gt;
&lt;br /&gt;
===int, char, short, long (ganze Zahlen)===&lt;br /&gt;
In Variable dieser Typen können Sie ganze Zahlen abspeichern, also z.B. 1, &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;2, 100, 12345. Jeden dieser Typen gibt es in zwei Ausprägungen: als &amp;quot;&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;quot;, also als vorzeichenbehafteten Typ, und als &amp;quot;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&amp;quot;, also ohne Vorzeichen, d.h. das Vorzeichen wird als 0 oder +1 genommen. &lt;br /&gt;
&lt;br /&gt;
Vorzeichenbehaftete Ganzzahl-Typen werden intern im &amp;lt;tt&amp;gt;n-1&amp;lt;/tt&amp;gt;-Komplement dargestellt, das Vorzeichen selbst findet sich also im höchstwertigen Bit. Werden zur Speicherung ''b'' Bits verwendet, dann reicht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;z.B. *zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==Enum==&lt;br /&gt;
&lt;br /&gt;
Über &amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt; können Aufzählungen definiert werden. Die Werte sind &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Werte und beginnen mit&amp;amp;nbsp;0. Der folgende enum hat einen um&amp;amp;nbsp;1 grösseren Wert. Mit einer Zuweisung können auch andere Werte zugeordnet werden. Klarer wird's im Beispiel:&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 enum Farben&lt;br /&gt;
 {&lt;br /&gt;
    ROT,&lt;br /&gt;
    GRUEN,&lt;br /&gt;
    BLAU,&lt;br /&gt;
    BRAUN = 5,&lt;br /&gt;
    SCHWARZ&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
Dies definiert die Konstanten &amp;lt;tt&amp;gt;ROT=0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;GRUEN=1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BLAU=2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BRAUN=5&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;SCHWARZ=6&amp;lt;/tt&amp;gt; und den Typ &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void foo (enum Farben farbe)&lt;br /&gt;
{&lt;br /&gt;
   switch (farbe)&lt;br /&gt;
   {&lt;br /&gt;
      case ROT:&lt;br /&gt;
         ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit kann man anstatt &amp;quot;magischer&amp;quot; Zahlen sprechende Namen im Code verwenden, etwa in Berechnungen und Zuweisungen, Vergleichen oder als Konstante hinter einem &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zusammengesetzte Datentypen==&lt;br /&gt;
===Arrays===&lt;br /&gt;
Oft muß man sehr viele Werte gleichzeitig abspeichern und betrachten, die alle der selben Aufgabe dienen. Man schreibt z.B. ein Programm, das 10 Zahlen einlesen und anschließend wieder ausgeben soll. Man könnte das natürlich mit 10 einzelnen Variablen bewerkstelligen, aber es ist sinnvoller, dabei Arrays &amp;amp;ndash; teilweise auch als ''Felder'' bezeichnet &amp;amp;ndash; zu verwenden.&lt;br /&gt;
&lt;br /&gt;
In einem Array werden mehrere Variablen gleichen Typs zusammengefasst und hintereinander im Speicher abgelegt. So kann man viele tausend Variablen anlegen mit nur einer Zeile Code. Doch es gibt noch größere Vorteile: Sie können das Array mit einer Schleife ganz einfach nach Werten durchsuchen. Stellen Sie sich vor, Sie müssten mit 100 verschiedenen Variablen &amp;lt;tt&amp;gt;Zahl_00&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;Zahl_99&amp;lt;/tt&amp;gt; arbeiten!&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}}&amp;amp;#91;{{Konstante}}&amp;amp;#93;;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 unsigned int werte[100];&lt;br /&gt;
&lt;br /&gt;
Der Name muß natürlich ein gültiger Bezeichner sein, als Datentyp kann jeder Typ genommen werden &amp;amp;ndash; sowohl elementare Datentypen als auch Zeiger, Strukturen, Unions oder selbst definierte Datentypen. In der eckigen Klammer wird die Anzahl der Elemente bekanntgegeben. Ein mit [3] definiertes Array hat Platz für drei Variablen. Da der Index immer bei 0 beginnt, greift man also mit &amp;lt;tt&amp;gt;[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;[1]&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;[2]&amp;lt;/tt&amp;gt; auf den jeweilige Inhalt zu. Um auf eine der im Array enthaltenen Variablen zugreifen zu können, müssen Sie den Variablennamen und in eckigen Klammern den Index (die &amp;quot;Nummer&amp;quot;) der Variablen angeben. Diese Variable verhält sich dann wie eine ganz normale Variable des jeweiligen Datentypes. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #define NZAHLEN 10&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int i;&lt;br /&gt;
    int zahlen[NZAHLEN];  {{comment|zahlen[0] ... zahlen[9]}}&lt;br /&gt;
  &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++)&lt;br /&gt;
    {&lt;br /&gt;
       printf (&amp;quot;Bitte Zahl %d eingeben: &amp;quot;, i);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; zahlen[i]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++) &lt;br /&gt;
       printf (&amp;quot;Zahl %d ist: %d\n&amp;quot;, i, zahlen[i]);&lt;br /&gt;
      &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 10 int-Variablen großes Array angelegt. &lt;br /&gt;
In dieses wird nun der Reihe nach 10 Zahlen eingelesen. &lt;br /&gt;
Anschließend werden alle 10 Zahlen ausgegeben. &lt;br /&gt;
&lt;br /&gt;
Dabei wird die Größe der Arrays und das Schleifenende über das Define &amp;quot;&amp;lt;tt&amp;gt;NZAHLEN&amp;lt;/tt&amp;gt;&amp;quot; angegeben. Dadurch muss nur ''eine Stelle'' im Code geändert werden, wenn die Größe des Arrays einmal einen anderer Wert als 10 haben soll &amp;amp;ndash; dies vermeidet Fehler die dadurch entstehen, wenn man beim Anpassen der Array-Größe eine Codestelle vergisst, zudem wird der Code lesbarer als wenn irgendwo die Zahl &amp;quot;10&amp;quot; auftaucht.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
:Wird ein ungültiger Index angeben (einer, der in der Deklaration nicht enthalten ist) können  undefinierte Dinge passieren, wenn dadurch andere Variableninhalte oder Programmcode überschrieben wird, der hinter oder vor dem Array im Speicher liegt. Schlimmstenfalls kann sogar der Computer/Controller abstürzen. Also darauf achten, daß keine ungültigen Werte als Index auftreten!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Strings (Zeichenketten)===&lt;br /&gt;
Ein String ist nichts anderes als ein Array, das aus einzelnen Zeichen (&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;) gebildet wird. Die Ausgabe auf dem Bildschirm funktioniert am einfachsten mittels Strings.&lt;br /&gt;
&lt;br /&gt;
Die Definition eines Strings erfolgt also genauso wie bei Arrays:&lt;br /&gt;
 char string[21];&lt;br /&gt;
&lt;br /&gt;
Nun haben Sie eine String, in dem Sie 21 Zeichen speichern können. Ganz richtig ist das jedoch nicht. C arbeitet mit &amp;quot;null-terminierten Strings&amp;quot;. Das beudeutet, dass die Länge des Strings nicht abgespeichert wird, sondern das Zeichen mit dem ASCII-Wert 0 das Stringende kennzeichnet. Daher auch die Bezeichnung  &amp;quot;null terminiert&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Das letzte Zeichen eines Strings muß daher immer das ASCII-Zeichen Nr. 0 sein. Ist es das nicht, hat der String kein definiertes Ende, und wenn Sie versuchen, ihn durch eine Standard-Funktion auszugeben zu lassen, könnte es eine Weile dauern, bis sich im Speicher zufällig irgendwo eine 0 befindet. Es stehen ihnen daher bei dem Beispiel nur 20 Zeichen zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
===Mehrdimensionale Arrays===&lt;br /&gt;
Manchmal benötigt man mehr als nur ein eindimensionales Array, wie Sie es bisher kennengelernt haben. Auch dies ist kein Problem. In der Deklaration geben Sie einfach mehrere eckige Klammern hintereinander an. Aber Vorsicht: der Speicherplatz ist begrenzt, ein &amp;quot;&amp;lt;tt&amp;gt;char feld[1024][1024]&amp;lt;/tt&amp;gt;&amp;quot; hat die Speicherplatzgrenzen vermutlich bereits weit überschritten, und der Compiler wird einen (bei gewissen Einstellung auch keinen) Fehler liefern.&lt;br /&gt;
Beim Zugriff auf mehrdimensionale Felder müssen auch mehrere Indizes angeben werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  int x,y;&lt;br /&gt;
  int feld[3][5];&lt;br /&gt;
 &lt;br /&gt;
  for (x=0; x&amp;lt;3; x++) &lt;br /&gt;
  {&lt;br /&gt;
     for (y=0; y&amp;lt;5; y++)&lt;br /&gt;
     {&lt;br /&gt;
       printf (&amp;quot;Feldwert x: %d,  y: %d &amp;quot;, x, y);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; feld[x][y]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  for(x=0; x&amp;lt;3; x++) &lt;br /&gt;
     for (y=0; y&amp;lt;5; y++) &lt;br /&gt;
        printf (&amp;quot;Wert: feld[%d][%d] = %d\n&amp;quot;, x, y, feld[x][y]);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 3 mal 5 &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array angelegt. &lt;br /&gt;
Dann werden die Werte eingegeben: zuerst &amp;lt;tt&amp;gt;feld[0][0]&amp;lt;/tt&amp;gt;, dann &amp;lt;tt&amp;gt;feld[0][1]&amp;lt;/tt&amp;gt;, usw. bis &amp;lt;tt&amp;gt;feld[2][4]&amp;lt;/tt&amp;gt;. &lt;br /&gt;
Zum Schluß werden alle Werte noch einmal ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===Strukturen===&lt;br /&gt;
In C können Sie sogenannte &amp;quot;Strukturen&amp;quot; definieren. Dabei handelt es sich um eine Zusammenfassung mehrerer Datentypen zu einem größeren. Im Unterschied zu Feldern können in Strukturen unterschiedliche Datentypen zusammengestellt und gespeichert werden: &lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 struct {{Bezeichner}}&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur 'Person'}}&lt;br /&gt;
 struct Person &lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;lt;tt&amp;gt;struct Person {&amp;lt;/tt&amp;gt;&amp;quot; leitet die Definition der Struktur mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;Person&amp;lt;/tt&amp;gt;&amp;quot; ein. &lt;br /&gt;
Dann werden in dieser Struktur fünf Komponenten definiert: drei Strings und zwei &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. &lt;br /&gt;
mit &amp;lt;tt&amp;gt;}&amp;lt;/tt&amp;gt; wird die Definition abgeschlossen. Sie haben damit einen Datentyp erstellt. Um eine Variable des Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach an&lt;br /&gt;
 struct Person {{Bezeichner}};&lt;br /&gt;
&lt;br /&gt;
Zum Zugriff auf eine Komponente der Struktur gibt man den Namen der Struktur-Variablen an (im folgenden Beispiel also &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;klaus&amp;lt;/tt&amp;gt;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
 {{comment|Definition zweier Struktur-Variablen}}&lt;br /&gt;
 struct Person hubert, klaus;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Zugriff auf Struktur-Komponenten}}&lt;br /&gt;
 hubert.alter = 32;&lt;br /&gt;
 klaus.alter = hubert.alter + 1;&lt;br /&gt;
&lt;br /&gt;
===Unions===&lt;br /&gt;
Eine Union wird ganz analog zu einer Struktur deklariert und verwendet. Sie unterscheidet sich von einer Struktur jedoch dadurch, daß ihre Elemente nicht nacheinander im Speicher abgelegt werden, sondern sich überlagern. Auf die in einer Union enthaltenen Daten gibt es also verschiedene Sichten: je nachdem, welche Sicht bzw. Interpretation der Daten man gerne hätte, wählt man den gewünschten Zugriff.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
union Daten &lt;br /&gt;
{&lt;br /&gt;
   int id;&lt;br /&gt;
&lt;br /&gt;
   struct Person u_person;&lt;br /&gt;
&lt;br /&gt;
   struct u_double&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      double wert;&lt;br /&gt;
   };&lt;br /&gt;
&lt;br /&gt;
   struct u_pointer&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      union Daten * p1;&lt;br /&gt;
      union Daten * p2;&lt;br /&gt;
   };&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
union Daten data;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies definiert eine Union mit den vier Zugriffsmöglichkeiten &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_double&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Größe der Union richtet sich dabei nach der grössten Komponente. In diesem Beispiel sind alle Komponenten so angelegt worden, daß sie an erster Stelle ein &amp;lt;tt&amp;gt;int id&amp;lt;/tt&amp;gt; enthalten. In &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; könnte man sich also merken, wie die Daten in der Union zu interpretieren sind. Würde &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; nicht dieses &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; enthalten, so würde sich &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; mit &amp;lt;tt&amp;gt;data.u_person.vname&amp;lt;/tt&amp;gt; überlagern. Ein Ändern der ersten Buchstaben von &amp;lt;tt&amp;gt;vname&amp;lt;/tt&amp;gt; hätte also ein Ändern von &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; zur Folge, und man könnte es nicht mehr als Merker verwenden. Mit diesem Feld überlagert das &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; die &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;-Felder der anderen Sichten, z.B. ist &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; der selbe Zugriff wie auf &amp;lt;tt&amp;gt;data.u_person.id&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein anderes Beispiel ist eine Union, die es ermöglicht, auf die einzelnen Bytes eines &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; zuzugreifen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef union&lt;br /&gt;
{&lt;br /&gt;
   unsigned long  as_long;&lt;br /&gt;
   unsignen short as_short[2];&lt;br /&gt;
   unsignen char  as_byte[4];&lt;br /&gt;
} data32_t;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies überlagert einen &amp;lt;tt&amp;gt;unsigned long&amp;lt;/tt&amp;gt; &amp;amp;ndash; also eine 32-Bit-Zahl &amp;amp;ndash; mit vier Bytes bzw. zwei Shorts.&lt;br /&gt;
 data32_t wert;&lt;br /&gt;
 &lt;br /&gt;
 wert.as_long = 0x12345678;&lt;br /&gt;
 wert.as_byte[0] = 0xab;&lt;br /&gt;
 {{comment|nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform)}}&lt;br /&gt;
&lt;br /&gt;
==Eigene Datentypen==&lt;br /&gt;
&lt;br /&gt;
=Variablen=&lt;br /&gt;
Eine Variable ist ein Synonym (=anderer Name) für eine Speicherstelle in einem Computer. Einfacher gesagt, eine Variable bietet Raum, um Daten wie Zahlen oder Zeichen zu speichern und wieder zu lesen.&lt;br /&gt;
&lt;br /&gt;
==Variablennamen==&lt;br /&gt;
Ein Variablenname kann zusammengesetzt werden aus den Buchstaben &amp;lt;tt&amp;gt;'''A'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''Z'''&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;'''a'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''z'''&amp;lt;/tt&amp;gt;, den Ziffern &amp;lt;tt&amp;gt;'''0'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''9'''&amp;lt;/tt&amp;gt;, sowie dem Sonderzeichen &amp;quot;Unterstrich&amp;quot; (underscore) &amp;lt;tt&amp;gt;'''_'''&amp;lt;/tt&amp;gt;. Dabei darf an erster Stelle keine Ziffer stehen. Die Bezeichner &amp;lt;tt&amp;gt;hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALLO&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALL0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;_123&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_HALLO&amp;lt;/tt&amp;gt; sind also alle gültige und unterschiedliche Variablennamen.&lt;br /&gt;
&lt;br /&gt;
==Anlegen von Variablen==&lt;br /&gt;
Um eine Variable verwenden zu können, muss sie zuerst vereinbart (&amp;quot;erzeugt&amp;quot;) werden. Dies wird auch als &amp;quot;''Definition der Variablen''&amp;quot; bezeichnet und geht so: Schreiben Sie zuerst den Datentyp, dann den Namen der Variablen. Zum Schluß kommt noch der Strichpunkt, wie nach jeder C-Anweisung oder Deklaration. Und nicht vergessen: C unterscheidet zwischen  Groß- und Kleinschreibung! &lt;br /&gt;
 int Zahl1, Zahl2;&lt;br /&gt;
 char Zeichen;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    float gleitZahl;&lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:'''&lt;br /&gt;
In einer Zeile können auch mehrere Variablen gleichen Types vereinbart werden, wenn man ein Komma dazwischen setzt. Variablen können in jedem Block vereinbart werden. Siehe [[#Gültigkeitsbereich|Gültigkeitsbereich]].&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen==&lt;br /&gt;
Man kann einer vereinbarten Variable Werte [[#Zuweisungen|zuweisen]]. Dazu schreibt man zuerst den Variablennamen, ein Gleichheitszeichen &amp;quot;&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;&amp;quot; und anschliessend den zuzuweisenden [[#Ausdrücke|Ausdruck]]. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, zahl2 = 12;&lt;br /&gt;
  char zeichen1 = 'A';&lt;br /&gt;
&lt;br /&gt;
  zahl1 = 52;&lt;br /&gt;
  zeichen1 = zeichen1 + 1; &lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Zuerst werden drei Variablen angelegt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;: wird gleich bei der Vereinbarung der Wert 12 zugewiesen. &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl1 = 52&amp;lt;/tt&amp;gt;: Hier wird der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; der Wert 52 zugewiesen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;: wird um 1 erhöht. Da in der Variablen &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; gespeichert ist, gibt sich ihr neuer Wert aus &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt;. Weil &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; dem Wert 65 entspricht, ist &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt; gleich 66, was dem Wert für &amp;lt;tt&amp;gt;'B'&amp;lt;/tt&amp;gt; entspricht.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei float==&lt;br /&gt;
Das funktioniert genau wie bei normale Zuweisungen. Nachkommastellen werden durch einen Punkt abgegrenzt: &lt;br /&gt;
 floatVariable = 3.14;&lt;br /&gt;
Zusätzlich kann eine Zehnerpotenz angegeben werden:&lt;br /&gt;
 floatVariable2 = -1.234E-6;&lt;br /&gt;
Dadurch wird der erst Wert mit 10&amp;lt;sup&amp;gt;&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;6&amp;lt;/sup&amp;gt; multipliziert, der Wert der Variablen ist also &lt;br /&gt;
:&amp;lt;math&amp;gt;-1{,}234\cdot10^{-6} = -0.000001234&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei logischen Variablen==&lt;br /&gt;
Wie bereits erwähnt, besitzt C keinen logischen Datentyp. Es müssen also &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; dafür genutzt werden. Die Zuweisung entpricht der Standard-Zuweisung. Wird der Wert 0 zugewiesen, dann ist die Variable &amp;quot;unwahr&amp;quot;, ansonsten ist sie &amp;quot;wahr&amp;quot;. &lt;br /&gt;
 intVariable = !0;   /* entspricht &amp;quot;wahr&amp;quot;   */&lt;br /&gt;
 intVariable = 0;    /* entspricht &amp;quot;unwahr&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
==Konstanten==&lt;br /&gt;
Konstanten können als Variable angesehen werden, die nicht beschrieben, sondern nur gelesen werden können. Ein typisches Beispiel dafür ist die Zahl &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; (rund 3,141592654). Niemand würde in der realen Welt versuchen, ihr einen anderen Wert zuzuweisen. Würde man &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; jedoch wie eine normale Variable anlegen, wäre dies ohne weiteres möglich. Um dies zu verhindern, gibt es das Schlüsselwort &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in C:&lt;br /&gt;
 const {{Type}} {{Bezeichner}} = {{Konstante}};  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Wichtig dabei ist, dass man Konstanten nur bei der Vereinbarung einen Wert zuweisen kann. &lt;br /&gt;
Da Konstanten gewöhnlich im gesamten Programm, zumindest einer Quelldatei genutzt werden, definiert man diese allerdings gewöhnlich außerhalb des main-Blockes entweder am Anfang eines Programmes, oder in einer sogenannten Header-Datei, die per &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; eingebunden wird.&lt;br /&gt;
 const float PI = 3.141592;  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Es sei jedoch erwähnt, daß auch einer Konstanten nachträglich ein anderer Wert zugewieden werden kann. Im obigen Beispiel könnte mit&lt;br /&gt;
 * ((float*) &amp;amp;PI) = 2;&lt;br /&gt;
der Wert von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; im Nachhinein verändert werden. Es wird die Adresse von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; genommen und diese Adresse durch den Cast in eine ganz normale &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;-Adresse umgewandelt, über welche der Wert geändert wird. Die sei der Vollständigkeit halber erwähnt.&lt;br /&gt;
&lt;br /&gt;
Je nachdem, an welcher Stelle sich das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; bei einer Pointer-Deklaration befindet, markiert es den Pointer als konstant oder das Objekt, auf das dieser Pointer zeigt. Eine häufige Parameterdeklaration in Ausgabe-Funktionen, die einen String erhalten, ist&lt;br /&gt;
 void foo (const char * str, ...);&lt;br /&gt;
Dadurch ist &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; der Zeiger auf eine Zeichenkette, die innerhalt der Funktion nicht verändert wird bzw. verändert werden darf. Eine Zuweisung wie &amp;lt;tt&amp;gt;*str = 'a'&amp;lt;/tt&amp;gt; ergibt also einen Fehler. &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; selbst kann aber sehr wohl verändert werden, etwa mit &amp;lt;tt&amp;gt;str++&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Soll ausgedrückt werden, daß &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; unveränderlich ist, dann so:&lt;br /&gt;
 void foo (char * const str, ...);&lt;br /&gt;
Jetzt wäre eine Änderung des Strings in Ordnung, etwa durch &amp;lt;tt&amp;gt;str[10] = 'a'&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Um sich zu merken, worauf das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; wirkt, trennt man die Deklaration in Gedanken beim&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf: Steht das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; links vom&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, dann gehört es zum &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, steht es rechts davon, dann gehört es zum Pointer. Natürlich ist es auch denkbar, beides &amp;amp;ndash; also den Zeiger und sein Ziel &amp;amp;ndash; als konstant zu markieren.&lt;br /&gt;
&lt;br /&gt;
==Gültigkeitsbereich==&lt;br /&gt;
In C können mehrere Variablen den gleichen Namen haben, solange eindeutig ist, welche in welchen Block gültig ist. Dabei gelten folgende Regeln: &lt;br /&gt;
&lt;br /&gt;
;Lokale Variablen: sind Variablen, die innerhalb eines Blockes definiert werden. Jede Variable ist nur in dem Block gültig, in dem sie vereinbart wurde, sowie in allen darin enthaltenen Blöcken; es sei denn, in einem Unter-Block wird eine Variable gleichen Namens definiert. Dann bezieht sich in diesem Unter-Block der Bezeichner auf die im Unter-Block angelegte Variable.&lt;br /&gt;
;Globale Variablen: werden ausserhalb jedes Blockes definiert und gelten ab der Stelle, an der sie deklariert werden, siehe auch [[#Deklaration und Definition|Deklaration und Definition]]. Wird jedoch in einem Block eine Variable gleichen Namens angelegt, gilt ab hier bis zum Ende des Blocks nicht mehr die globale Variable, sondern die im Block deklarierte. Das Spiel kann man weiterspielen: wird in einem Unter-Block wieder eine namensgleiche Variable angelegt, gilt diese in dem Unterblock.&lt;br /&gt;
&lt;br /&gt;
==Speicherklassen==&lt;br /&gt;
Jede Variable in C gehört zu einer bestimmten Speicherklasse&lt;br /&gt;
;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;: Lokale Variablen sind in aller Regal sogenannte ''automatische Variablen''. Das bedeutet, sie werden automatisch angelegt, wenn ein Block bzw. eine Funktion betreten wird und danach wieder entfernt. Das Schlüsselwort &amp;quot;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;&amp;quot; wird praktisch nie hingeschrieben, denn lokale Variablen ohne die ausdrückliche Angabe einer Speicherklasse, sind automatisch automatische Variablen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;: Eine externes Symbol ist im ganzen Programm bekannt bzw. in dem Block, in der die Deklaration steht. In unterschiedlichen Blöcken stehende Deklarationen beziehen sich auf das gleiche Symbol! Obgleich das Datum global zugreifbar ist, ist der Gültigkeitsbereich auf den deklarierenden Block begrenzt bzw. auf das deklarierende Quell-Modul, sofern das Symbol ausserhalb jedes Blocks des Moduls deklariert wird. Siehe auch [[#Deklaration und Definition|Deklaration und Definition]].&lt;br /&gt;
;&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;: Die Variable ist im Block gültig bzw. im Quell-Modul (also in der C-Datei, in der die angelegt wurde), wenn sie nicht innerhalb eines Blockes angelegt wurde. Statische Variablen werden nicht in Registern oder im Frame der Funktion angelegt, sondern im selben Speicherbereich, in dem auch die globalen Variablen liegen; Konstanten evtl. auch im Flash. Eine lokale Variable, die als &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; angelegt wird, &amp;quot;überlebt&amp;quot; also das Verlassen des Blocks und hat beim neuerlichen Betreten des Blockes ihren bisherigen Wert. In unterschiedlichen Blöcken angelegte lokale statische Variablen beziehen sich auf unterschiedliche Speicherstellen, genau wie bei lokalen Variablen auch.&lt;br /&gt;
;&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;: Durch diese Speicherklasse wird eine Variable &amp;amp;ndash; falls möglich &amp;amp;ndash; als Registervariable angelegt, also in einem Maschinenregister des Computer/Controllers gehalten. Dadurch kann auf solche Variablen besonders schnell zugegriffen werden. Dieses Schlüsselwort ist bei modernen Compilern weitgehend überflüssig, da die entsprechenden Optimierungen selbständig vorgenommen werden, wenn ausreichend Register vorhanden sind. Auch globale Variablen können als Register angelegt werden, davon ist dem Anfänger aber dringend abzuraten, weil leicht schwerauffindbare Fehler und Abstürze auftreten, wenn man nicht genau weiss, welche Implikationen in einer solchen Definition stecken!&lt;br /&gt;
;&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;: (FIXME: volatile ist ein Qualifier und keine Speicherklasse) Dies ist das genaue Gegenteil von &amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt; und bewirkt, dass die Variable auf keinen Fall in einem Register zwischengespeichert werden darf, sondern immer aus dem RAM gelesen und ins RAM geschrieben werden soll. &amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt; müssen alle ''globalen'' Variablen markiert werden, die in [[ISR | Interrupt-Handlern]] verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Ausdrücke=&lt;br /&gt;
Eine Variable oder eine Konstante in C stellen einfache Ausdrücke dar.&lt;br /&gt;
Diese elementaren Ausdrücke können durch Operatoren miteinander verknüpft werden und so zu neuen, komplexeren Ausdrücken zusammen gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Einfache Beispiele für Ausdrücke sind also z.B.:&lt;br /&gt;
 1&lt;br /&gt;
 a&lt;br /&gt;
 'a'&lt;br /&gt;
 1 + a&lt;br /&gt;
 a == 1&lt;br /&gt;
&lt;br /&gt;
Auch Funktionen können einen Wert zurückliefern und in Ausdrücken weiter benutzt werden.&lt;br /&gt;
In den folgenden Abschnitten wird gezeigt, welche Operatoren in C vorhanden sind,&lt;br /&gt;
und wei man damit neue Ausdrücke aufbauen kann.&lt;br /&gt;
&lt;br /&gt;
==Lvalues==&lt;br /&gt;
&lt;br /&gt;
Ein Lvalue in C ist ein Ausdruck, dem ein anderer Ausdruck zugewiesen werden kann, dessen Wert also durch eine Zuweisung verändert werden kann.&lt;br /&gt;
das 'L' leitet sich ab von 'left' bwz. 'links' und das 'value' bedeutet Wert: Ein Lvalue ist ein Ausdruck, der auf der linken Seite einer Zuweisung stehen darf. Ein Lvalue ist also immer auch ein gültiger Ausdruck, aber die Umkehrung gilt in alles Regel nicht.&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für einen Lvalue ist eine &amp;quot;normale&amp;quot; Variable, die nicht mit &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; als Konstante markiert ist:&lt;br /&gt;
 a = 1;&lt;br /&gt;
Hingegen ist der Ausdruck &amp;lt;tt&amp;gt;a+1&amp;lt;/tt&amp;gt; kein Lvalue, denn eine Zuweisung wie&lt;br /&gt;
 a+1 = 2;&lt;br /&gt;
die mathematisch durchaus sinnvoll ist, erzeugt einen Compilerfehler, der etwa lauten könnte &amp;quot;illegal lvalue in assignment&amp;quot;:&lt;br /&gt;
&amp;quot;ungültiger Wert in Zuweisung&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Andere Beipiele für Lvalues sind die Komponenten von (nicht-konstanten) [[#Strukturen|Strukturen]] und [[#Unions|Unions]], [[#Arrays|Array]]-Elemente und die Dereferenzierungen von Pointern: Die Konstante&amp;amp;nbsp;4 wird durch den Cast in eine Adresse umgewandelt. Über die Dereferenzierung&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; wird an die Adresse&amp;amp;nbsp;4 im Speicher eine&amp;amp;nbsp;3 geschrieben. Ob das erlaubt bzw. sinnvoll ist, ist abhängig von der jeweiligen Architektur.&lt;br /&gt;
 * ((unsigned int *) 4) = 3;&lt;br /&gt;
Hier ist der gesamte &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;-Ausdruck ein Lvalue&lt;br /&gt;
&lt;br /&gt;
==Logische (boolsche) Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp;amp;&amp;amp;amp; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr oder &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; || gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; || ungleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;= b&amp;lt;/tt&amp;gt; || kleiner oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt; b&amp;lt;/tt&amp;gt; || kleiner als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt;= b&amp;lt;/tt&amp;gt; || glösser oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt; b&amp;lt;/tt&amp;gt; || grösser als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; nicht wahr und vice versa&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine interessante Eigenschaft der Operatoren &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;amp;amp;&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; ist, dass&lt;br /&gt;
sie die Auswertung abbrechen, sobald das Ergebnis feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet. Ein oft anzutreffendes Codestück sieht so aus, dabei sei &amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
  if (p &amp;amp;&amp;amp; *p == 5)&lt;br /&gt;
  {&lt;br /&gt;
     {{comment|mach was}}&lt;br /&gt;
  }&lt;br /&gt;
Zuerst wird in der Bedinung geprüft, ob Zeiger&amp;amp;nbsp;&amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; einen Wert ungleich Null hat, also ob er überhaupt einen gültigen Wert enthält. Es ist weit verbreitete Konvention in C, daß Zeiger, die keinen gültigen Wert haben, die Adresse&amp;amp;nbsp;0 enthalten. '''Nur dann, wenn ein Zeiger nicht ein Null-Pointer ist, darf überhaupt ein Zugriff über ihn erfolgen!'''&lt;br /&gt;
&lt;br /&gt;
==Vergleich von Variablen==&lt;br /&gt;
Skalare Variablen (also ganze Zahlen, Gleitkommazahlen, Zeiger) können miteinander verglichen werden. Dazu gibt es die folgenden Operatoren in C: &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; || ist nicht gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;=&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;=&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das Ergebnis der Auswertung ist eine ganze Zahl. Ist die Bedingung erfüllt, dann ist der Wert ungleich&amp;amp;nbsp;0. Ist die Bedingung nicht erfüllt, dann ist ihr Wert gleich&amp;amp;nbsp;0.&lt;br /&gt;
Meistens wird man diese Operatoren in &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Konstrukten finden wie zum Beispiel&lt;br /&gt;
 if (x &amp;gt;= 10)&lt;br /&gt;
    x = 10;&lt;br /&gt;
oder in Abbruchbedingungen von Schleifen, wie sie weiter unten erklärt werden.&lt;br /&gt;
&lt;br /&gt;
Es ist auch möglich, das Ergebnis der Auswertung in einer &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Variablen zu speichern:&lt;br /&gt;
 int i;&lt;br /&gt;
 int z1, z2;&lt;br /&gt;
 &lt;br /&gt;
 z1 = 5;&lt;br /&gt;
 z2 = 100;&lt;br /&gt;
 i = z1 &amp;lt;= z2;  {{comment|Ein Vergleich. i wird &amp;quot;wahr&amp;quot;, da z1 kleinergleich z2 ist}}&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich&amp;amp;nbsp;0 (&amp;quot;wahr&amp;quot;), wenn &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; kleiner oder gleich &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt; ist. Ist &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; jedoch größer als &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt;, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich&amp;amp;nbsp;0 (&amp;quot;unwahr&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
==Arithmetische Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a + b&amp;lt;/tt&amp;gt; || Summe (Addition)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a - b&amp;lt;/tt&amp;gt; || Differenz (Subtraktion)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a * b&amp;lt;/tt&amp;gt; || Produkt (Multiplikation)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a / b&amp;lt;/tt&amp;gt; || Quotient (Division, evtl. mit Rest)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a % b&amp;lt;/tt&amp;gt; || Rest bei Division (Modulo)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;-a&amp;lt;/tt&amp;gt; || Vorzeichenumkehr (Zweierkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Bit-Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp; b&amp;lt;/tt&amp;gt; || bitweise und (and)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || bitweise oder (or)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a ^ b&amp;lt;/tt&amp;gt; || bitweise exclusiv-oder (xor, exor)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;~a&amp;lt;/tt&amp;gt; || jedes Bit in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; invertieren (not, Einerkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Index-Operator bei Arrays==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a[b]&amp;lt;/tt&amp;gt; || das (b+1)ste Element des Feldes a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Folgendes gilt es bei der Verwendung des Indexoperators zu beachten:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; muss ein [[C-Tutorial#Felder | Feld]] oder [[C-Tutorial#Zeiger | Zeiger]] sein&lt;br /&gt;
# &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; muss ein Integer sein oder ein Datentyp, der sich in einen int umwandeln läßt (z.B. char)&lt;br /&gt;
# Es wird nicht geprüft, ob der Index &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; im Feld &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gültig ist!&lt;br /&gt;
# Der erste Index eines Feldes ist immer 0. Daher ''(b+1)stes Element'' in der Beschreibung&lt;br /&gt;
&lt;br /&gt;
==Komponenten-Auswahl bei Structs und Unions==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a.b&amp;lt;/tt&amp;gt; || Element b der [[C-Tutorial#Strukturen | Struktur]] oder des Unions a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adress-Operator und Dereferenzierung==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&amp;amp;amp;a&amp;lt;/tt&amp;gt; || Speicheradresse der Variablen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;*a&amp;lt;/tt&amp;gt; || Wert, der an der Adresse &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a-&amp;amp;gt;b&amp;lt;/tt&amp;gt; || Wert des Elements &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; der Struktur, deren Adresse in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Adressoperator &amp;amp; kann auf Variablen angewendet werden und&lt;br /&gt;
gibt die Startadresse der Variablen im Speicher zurück.&lt;br /&gt;
&lt;br /&gt;
Handelt es sich bei einer Variable um einen [[C-Tutorial#Zeiger | Zeiger]], so enthält&lt;br /&gt;
sie eine Speicheradresse. Um an den '''Wert''' zu gelangen, der&lt;br /&gt;
an dieser Adresse steht, wird der Operator * vorangestellt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
&lt;br /&gt;
 {{comment|x ist eine Integervariable und hat den Wert 5}}&lt;br /&gt;
 int x = 5;&lt;br /&gt;
     &lt;br /&gt;
 {{comment|z ist ein Zeiger auf eine Integer-Variable und enthaelt somit}}&lt;br /&gt;
 {{comment|die Speicheradresse einer Integer-Variablen}}&lt;br /&gt;
 int *z;       &lt;br /&gt;
  &lt;br /&gt;
 {{comment|Verwendung des Adress-Operators: weist an z die Adresse von x zu}}&lt;br /&gt;
 z = &amp;amp;x;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Verwendung der Dereferenzierung}}&lt;br /&gt;
 {{comment|erhoehe den Wert, der bei Adresse z steht, um eins}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|da z auf x zeigt, hat x jetzt den Wert 6}}&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff auf Struktir- und Union-Elemente eine abkürzende Schreibweise möglich:&lt;br /&gt;
&lt;br /&gt;
Statt &lt;br /&gt;
  (*strukturZeiger).element&lt;br /&gt;
kann geschrieben werden&lt;br /&gt;
  strukturZeiger-&amp;gt;element&lt;br /&gt;
Beide Schreibweisen sind absolut gleichbedeutend, die Klammern bei der ersteren sind notwendig.&lt;br /&gt;
&lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
:Bei der Dereferenzierung durch &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; findet keine Prüfung statt, ob der Zeiger auch auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu einer Änderung '''irgendeiner''' Speicherstelle!&lt;br /&gt;
&lt;br /&gt;
 int *z; {{comment|z ist ein Zeiger auf einen int}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.}}&lt;br /&gt;
 {{comment|z enthaelt irgendeine ungueltige Adresse!!}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|&amp;quot;Erhoehe einen Integer _irgendwo_ im Speicher um 1&amp;quot; -&amp;gt; CRASH !!!}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
&lt;br /&gt;
==Cast-Operator==&lt;br /&gt;
&lt;br /&gt;
Der Cast Operator dient dazu, den Datentyp eines Wertes zu ändern. Dafür wird einfach der neue Datentyp in Klammern vor den Wert geschrieben.&lt;br /&gt;
&lt;br /&gt;
Um zum Beispiel aus einem Float ein Integer zu machen:&lt;br /&gt;
 var  = (int) 5.60;&lt;br /&gt;
Dabei wird der Wert aber auch gerundet, und es findet somit ein Informationsverlust statt.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Umwandeln einer ganzen Zahl in eine Adresse:&lt;br /&gt;
 int * addr;&lt;br /&gt;
 addr = (int*) 0x1234;&lt;br /&gt;
Damit ist &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; an Adresse 0x1234.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
Der Cast-Operator selbst führt ''keine Konvertierung'' von Darstellungen durch, etwa die Umwandlung der ganzen Zahl 123 ein den String &amp;lt;tt&amp;gt;&amp;quot;123&amp;quot;&amp;lt;/tt&amp;gt;, der diese Zahl darstellt! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
  int main(int argc, char ** argv)&lt;br /&gt;
  {&lt;br /&gt;
        char text[] = &amp;quot;5.6&amp;quot;;&lt;br /&gt;
        int zahl = (int) text;&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, zahl);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Anfangsadresse des Strings &amp;lt;tt&amp;gt;&amp;quot;5.6&amp;quot;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Komma-Operator==&lt;br /&gt;
Mit einem &amp;lt;tt&amp;gt;,&amp;lt;/tt&amp;gt; können mehrere Ausdrücke nacheinander ausgewertet werden.&lt;br /&gt;
Die Auswertung erfolgt von links nach rechts.&lt;br /&gt;
&lt;br /&gt;
Solche Konstrukte sieht man manchmal in Abfragen wie&lt;br /&gt;
 FILE  *file;&lt;br /&gt;
 if (file = fopen (&amp;quot;foo.exe&amp;quot;, &amp;quot;r&amp;quot;), file != NULL)&lt;br /&gt;
was erst an &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; einen Wert zuweist und den &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Block nur betritt,&lt;br /&gt;
wenn &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; nicht der Nullpointer ist.&lt;br /&gt;
&lt;br /&gt;
Bequem kann das auch in einer [[#for-Schleife|for-Schleife]] sein, wenn man zwei (oder mehr) Laufvariablen hat oder so:&lt;br /&gt;
 for (i=0, j=0; i &amp;lt; 10; i++, j += 2)&lt;br /&gt;
    &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Zuweisung===&lt;br /&gt;
=== ++ und -- ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; stellen einfachere Schreibweisen dar zum Addieren bzw. Subtrahieren von&amp;amp;nbsp;1.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; (Inkrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo++; &lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo + 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; 3}}&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; (Dekrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo--;&lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo - 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; -1}}&lt;br /&gt;
&lt;br /&gt;
Die beiden Operatoren können sowohl in der Präfix-Schreibweise (vor der Variablen) als auch als Postfix-Schreibweise (hinter der Variablen) notiert werden. &lt;br /&gt;
Der Unterschied liegt darin, dass beim Präfix der Wert zuerst neu berechnet wird und die Variable dann verwendet wird. Beim Postfix wird die Variable zuerst verwendet und erst nach Auswertung des Ausdrucks, in dem sie enthalten ist, neu berechnet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 int ausgabe1, ausgabe2, var1 = 10, var2 = 10;&lt;br /&gt;
 ausgabe1 = 3 * ++var1; {{comment|ausgabe1 &amp;amp;#61; 33; var1 &amp;amp;#61; 11;}}&lt;br /&gt;
 ausgabe2 = 3 * var2++; {{comment|ausgabe2 &amp;amp;#61; 30; var2 &amp;amp;#61; 11;}}&lt;br /&gt;
&lt;br /&gt;
Für Zeiger arbeiten diese Operatoren etwas anders, siehe dazu [[#Zeiger-Arithmetik|Zeiger-Arithmetik]].&lt;br /&gt;
&lt;br /&gt;
===Bedingter Ausdruck===&lt;br /&gt;
 ({{Bedingung}}) ? {{Ausdruck|1}} : {{Ausdruck|2}}&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; erfüllt ist, dann wertet dieser Ausdruck aus zu &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt;. Ist er nicht erfüllt, dann wertet er aus zu &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 x = (x &amp;gt;= 3) ? 0 : x+1;&lt;br /&gt;
Startet man &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; mit dem Wert 0, dann nimmt es bei mehrfacher Anwendung dieser Zeile (z.B. in einer Schleife) nacheinander die folgende Werte an:&lt;br /&gt;
:&amp;lt;tt&amp;gt;1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, ...&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Priorität ||Operator||Assoziativität&lt;br /&gt;
|-&lt;br /&gt;
  &lt;br /&gt;
|&amp;lt;tt&amp;gt;15&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ( ) [ ] -&amp;gt; . &amp;lt;/tt&amp;gt;                      ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;14&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ! ~ ++ -- + - (TYP) * &amp;amp; sizeof &amp;lt;/tt&amp;gt;    ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;13&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; * / % (Rechenoperationen) &amp;lt;/tt&amp;gt;         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;12&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; + - (binär) &amp;lt;/tt&amp;gt;                       ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;11&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;&amp;lt; &amp;gt;&amp;gt; &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;10&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt; &amp;lt;= &amp;gt; &amp;gt;= &amp;lt;/tt&amp;gt;                         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 9&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; == != &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 8&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp; (bit-AND-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 7&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ^ (bit-XOR-Operator)&amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 6&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; (bit-OR-Operator)&amp;lt;/tt&amp;gt;   ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 5&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp;&amp;amp; &amp;lt;/tt&amp;gt;                                ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 4&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; &amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 3&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ? : &amp;lt;/tt&amp;gt;                               ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 2&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; = += -= /= *= %= &amp;gt;&amp;gt;= &amp;lt;&amp;lt;= &amp;amp;= |= ^= &amp;lt;/tt&amp;gt; ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 1&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; , (Sequenz-Operator) &amp;lt;/tt&amp;gt;              ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
Eine Kontrollanweisung ist eine Anweisung, die Einfluss auf den Programmfluss hat. Normalerweise werden Anweisungen so ausgeführt, wie sie in der Quelldatei stehen: Von links nach rechts (falls mehrere Anweisungen in einer Zeile stehen sollten, wovon i.A. abzuraten ist) und von oben nach unten. Mit einer Kontrollanweisung kann dieser lineare Programmfluss durchbrochen werden: Die Codeausführung kann kann abhängig von einer Bedingung gemacht werden (&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;), kann wiederholt werden (Schleife) oder an einer anderen Stelle der Funktion fortgesetzt werden (&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==if-Anweisung==&lt;br /&gt;
Mit Hilfe des if-Befehls kann man Codeteile abhängig davon einer Bedingung ausführen lassen:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
oder mit else-Teil&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 if (x &amp;gt; 100)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;gt; 100 ist: Fehlerausgabe}}&lt;br /&gt;
    printf (&amp;quot;x = %d ist zu gross fuer die Berechnung!\n&amp;quot;, x);&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;lt;&amp;amp;#61; 100 ist: Berechne Summe der Zahlen 1...x}}&lt;br /&gt;
    {{comment|Die lokale Variable x2 lebt nur innerhalb dieses alse-Blocks}}&lt;br /&gt;
    int x2 = x;&lt;br /&gt;
 &lt;br /&gt;
    for (x = 0; x2 &amp;gt; 0; x2--)&lt;br /&gt;
       x += x2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Wenn die Bedingung wahr ist (&amp;lt;tt&amp;gt;x &amp;gt; 100&amp;lt;/tt&amp;gt;), dann wird eine Meldung ausgegeben; danach ist die if-Anweisung beendet. Der else-Block wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung nicht erfüllt (&amp;lt;tt&amp;gt;x &amp;amp;le; 100&amp;lt;/tt&amp;gt;), dann wird gleich zum else-Teil gesprungen, und nach dessen Ausführung der if-Befehl beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Ein häufiger Fehler ist es, statt &amp;lt;tt&amp;gt;if (a &amp;amp;#61;&amp;amp;#61; 23)&amp;lt;/tt&amp;gt; etwas wie &amp;lt;tt&amp;gt;if (a &amp;amp;#61; 23)&amp;lt;/tt&amp;gt; zu schreiben. &lt;br /&gt;
Dann wird allerdings nicht geprüft, ob die Variable&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gleich 23 ist, sondern der Variablen&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wird der Wert 23 zugewiesen. Der Ausdruck &amp;lt;tt&amp;gt;a &amp;amp;#61; 23&amp;lt;/tt&amp;gt; hat den Wert&amp;amp;nbsp;23 und ist damit immer &amp;quot;wahr&amp;quot;! Daher ist diese if-Bedingung immer erfüllt!&lt;br /&gt;
&lt;br /&gt;
Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken sondern bestenfalls eine Warnung. Damit ist dieser Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise &amp;lt;tt&amp;gt;if (23 &amp;amp;#61;&amp;amp;#61; a)&amp;lt;/tt&amp;gt;. Wenn man dort anstatt des Vergleichsoperators '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;amp;#61;&amp;lt;/tt&amp;gt;' den Zuweisungsoperator '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;lt;/tt&amp;gt;' verwendet, spuckt der Compiler sehr wohl einen Fehler aus! Ist die Zuweisung jedoch erwünscht und eine Compiler-Warnung lästig, dann wählt man eine Schreibweise wie &amp;lt;tt&amp;gt;if ((a &amp;amp;#61; b))&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;if (a &amp;amp;#61; b, a)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist zu schreiben &amp;lt;tt&amp;gt;if (Bedingung);&amp;lt;/tt&amp;gt; Richtig muss es heissen &amp;quot;&amp;lt;tt&amp;gt;if(Bedingung)&amp;lt;/tt&amp;gt;&amp;quot; Das Semikolon im ersten Fall ist eine leere Anweisung, die im if-Falle ausgeführt wird &amp;amp;ndash; sie bleibt also ohne Resultet. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt; ein auf das Semikolon folgende Anweisung die eigentlich zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören soll wird immer ausgeführt, die sie nicht mehr zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; dazu gehört.&lt;br /&gt;
}}&lt;br /&gt;
Bei verschachtelten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Konstrukten gehört ein &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zu letzten &amp;quot;freien&amp;quot; &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;. Soll in einer &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Folge das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zum ersten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören, dann ist das so zu hinzuschreiben:&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Ohne die geschweiften Klammern um das zweite &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehörte das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; dort hinzu.&lt;br /&gt;
&lt;br /&gt;
==switch-Anweisung==&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
&lt;br /&gt;
 switch ({{Ausdruck|}}) &lt;br /&gt;
 {&lt;br /&gt;
     case konstante1:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
    &lt;br /&gt;
     case konstante2:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 &lt;br /&gt;
     {{comment|weitere case-Marken}}&lt;br /&gt;
 &lt;br /&gt;
     default:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 } {{comment|Ende von switch}} &lt;br /&gt;
&lt;br /&gt;
Der Ausdruck muss ein skalarer Typ sein, er wird in die nächste ganze Zahl gewandelt und mit den Werten hinter den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Marken verglichen. Bei einer Übereinstimmung werden alle Befehle ab dem zutreffenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; ausgeführt. Stimmt der Ausdruck mit keinem der Werte überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt falls vorhanden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der nachfolgenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;- und des &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitts werden ausgeführt, wenn die Anweisungen des &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitts nicht mit dem Befehl &amp;lt;tt&amp;gt;break;&amp;lt;/tt&amp;gt; beendet werden!&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es dürfen beliebig viele &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitte angegeben werden, pro Vergleichswert jedoch nur einer.&lt;br /&gt;
Der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ist optional. Die Reihenfolge, in der &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt; angegeben werden, ist unerheblich.&lt;br /&gt;
&lt;br /&gt;
==Schleifen==&lt;br /&gt;
Um Anweisungen mehrmals hintereinander auszuführen, benötigt man Schleifen. Diese führen Anweisungen aus, bis oder solange Bedingungen erfüllt sind.&amp;lt;br&amp;gt; &lt;br /&gt;
Wichtig ist also, ob die Bedingung '''vor''' oder '''nach''' den Schleifen-Anweisungen geprüft wird. &lt;br /&gt;
&lt;br /&gt;
===while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 while ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Die while-Schleife wird solange durchlaufen, wie die Bedingung erfüllt ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Die Anweisung kann natürlich auch ein Block sein, der aus mehreren Deklarationen und Anweisungen besteht. &lt;br /&gt;
&lt;br /&gt;
 int zahl1 = 0;&lt;br /&gt;
 int zahl2 = 1;&lt;br /&gt;
 &lt;br /&gt;
 while (zahl1 &amp;lt; 3)&lt;br /&gt;
 {&lt;br /&gt;
    zahl1 = zahl1 + 1;&lt;br /&gt;
    zahl2 = zahl2 * 2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife drei mal durchlaufen. Zu Beginn des vierten Durchlaufs ist die Bedingung nicht mehr erfüllt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
&lt;br /&gt;
===do-while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
Die do-while-Schleife wird auf jeden Fall einmal durchlaufen und dann solange wiederholt, wie die Bedingung erfüllt ist.&lt;br /&gt;
 int i = 2;&lt;br /&gt;
 &lt;br /&gt;
 do &lt;br /&gt;
 {&lt;br /&gt;
     i = i*i;   {{comment|i quadrieren}}&lt;br /&gt;
     printf (&amp;quot;i = %d\n&amp;quot;, i);&lt;br /&gt;
 }&lt;br /&gt;
 while (i &amp;lt; 20);&lt;br /&gt;
&lt;br /&gt;
Die Schleife wird durchlaufen und wiederholt, solange &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; kleiner als 20 ist. Es werden also nacheinander die Werte 2, 4 und 16 ausgegeben. Nach der Schleife hat&amp;amp;nbsp;&amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; den Wert 256.&lt;br /&gt;
&lt;br /&gt;
===for-Schleife===&lt;br /&gt;
'''Syntax:''' &lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Bei den Ausdrücken wird es sich um einen Ausdrücke mit Nebeneffekt handeln wie etwa &amp;lt;tt&amp;gt;i=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;i=i+2&amp;lt;/tt&amp;gt;. Es werden folgende Aktionen ausgeführt:&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# falls die Bedingung wahr ist, dann führe &amp;lt;tt&amp;gt;Anweisung&amp;lt;/tt&amp;gt; aus.&lt;br /&gt;
# falls die Bedingung unwahr ist, dann sprinte zu 7 (Ende).&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# gehe zu 2&lt;br /&gt;
# nächste Anweisung nach der for-Schleife&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int lauf, summe;&lt;br /&gt;
 &lt;br /&gt;
 for (lauf=1, summe=0; lauf &amp;lt;= 10; lauf += 2) &lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel ist &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; ein [[#Komma-Operator|Komma-Ausdruck]], der zwei Anweisungen kombiniert und daher sogar zwei Nebeneffente hat: er setzt &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;1 und &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;0.&lt;br /&gt;
&lt;br /&gt;
Das Äquivalent als while-Schleife:&lt;br /&gt;
&lt;br /&gt;
 int lauf  = 1;                 {{comment|Anfangswerte}}&lt;br /&gt;
 int summe = 0;&lt;br /&gt;
 &lt;br /&gt;
 while (lauf &amp;lt;= 10)             {{comment|Bedingung}}&lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
    lauf  += 2;                 {{comment|Inkrement}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; in jedem Schleifendurchlauf um die Laufvariable &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; erhöht. Da &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nacheinander die ungeraden Werte von&amp;amp;nbsp;1 bis&amp;amp;nbsp;10 annimmt, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von&amp;amp;nbsp;1 bis kleinergleich 10 gespeichert, also der Wert&amp;amp;nbsp;25. &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; hat nach der Schleife den Wert&amp;amp;nbsp;11.&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf = 1&amp;lt;/tt&amp;gt; bedeutet, dass der Variablen &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; vor dem ersten Schleifendurchlauf der Wert&amp;amp;nbsp;1 zugewiesen wird. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf &amp;lt;= 10&amp;lt;/tt&amp;gt; ist die Schleifenbedingung; ist sie nicht erfüllt, wird die Schleife beendet. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf += 2&amp;lt;/tt&amp;gt; bedeutet, dass &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nach jedem Durchlauf um&amp;amp;nbsp;2 erhöht wird.&lt;br /&gt;
&lt;br /&gt;
===continue-Anweisung===&lt;br /&gt;
Innerhalb einer Schleife darf die &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die nachfolgenden Anweisungen übersprungen werden und mit dem nächsten Schleifendurchlauf fortgesetzt wird &amp;amp;ndash; vorausgesetzt die Schleifenbedingung ist noch erfüllt. Ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; etc. stehen, wenn dieses innerhalb einer Schleife steht.&lt;br /&gt;
&lt;br /&gt;
==break-Anweisung==&lt;br /&gt;
Innerhalb einer Schleife oder eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; darf die &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die Schleifen-/Switch-Anweisung sofort verlassen wird und das Programm dahinter weiter macht. Bei mehrfach geschachtelten Schleifen wird nur die innere verlassen. Ein &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; stehen, wenn dieses innerhalb einer Schleife/Switch-Anweisung steht.&lt;br /&gt;
&lt;br /&gt;
==goto-Anweisung==&lt;br /&gt;
&lt;br /&gt;
Innerhalb ein und derselben Funktion kann mit &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; an eine andere Stelle gesprungen werden. Dazu gibt man hinter dem &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einen Bezeichner an, der dadurch als Label fungiert:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 goto {{Bezeichner}};&lt;br /&gt;
Die Bezeichner selbst steht irgendwo in der Funktion und wird dadurch zur Sprungmarke (Label), daß er von einem Doppelpunkt (und mindestens einer C-Anweisung, die auch leer sein darf) gefolgt wird.&lt;br /&gt;
&lt;br /&gt;
Das Beispiel durchsucht das 2-dimensionale &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array &amp;lt;tt&amp;gt;feld&amp;lt;/tt&amp;gt; mit den &amp;lt;tt&amp;gt;SIZE_X &amp;amp;times; SIZE_Y&amp;lt;/tt&amp;gt; Werten nach dem Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;. Wird er gefunden, dann wird die 2-fach geschachtelte Suchschleife verlassen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int x, y;&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y; y++)&lt;br /&gt;
       if (feld[x][y] == 0)&lt;br /&gt;
          goto done;&lt;br /&gt;
 {{Label|done:}};&lt;br /&gt;
&lt;br /&gt;
Der folgende Code hat die gleiche Funktion, arbeitet jedoch ohne &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int x, y;&lt;br /&gt;
 int found = 0; {{comment|FALSE}}&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X &amp;amp;&amp;amp; !found; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y &amp;amp;&amp;amp; !found; y++)&lt;br /&gt;
       found = (0 == feld[x][y]);&lt;br /&gt;
Der Nachteil der &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-losen Variante ist, daß man eine Variable, die merkt, ob das Suchziel gefunden wurde, mitschleppen und in ''jedem'' Schleifendurchlauf abtesten muss. Dies bedeutet einen höheren Programmier- und Laufzeitaufwand und ist nicht so klar formuliert wie das &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-Beispiel.&lt;br /&gt;
&lt;br /&gt;
Gleichwohl sei angemerkt, daß die Verwendung von &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einem gewissen Dogmatismus unterliegt, der sich wie folgt subsummieren liesse:&lt;br /&gt;
:''goto ist böse und sollte keinesfalls verwendet werden! Wer es dennoch tut, offenbart dadurch seinen schlechten Geschmach sowie mangelhafte C-Kenntnis.'' &amp;lt;div align=&amp;quot;right&amp;quot;&amp;gt;http://www.roboternetz.de/phpBB2/images/smiles/icon_wink.gif&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Funktionen=&lt;br /&gt;
Stellen Dir vor, Du hast eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben &amp;amp;ndash; was Dich Zeit beim Erstellen des Programms und Speicherplatz im ausführbaren Programm kostet &amp;amp;ndash; kannst Du den Code-Abschnitt in eine Funktion schreiben und diese von jeder Stelle des Programms aus verwenden. Die Hauptgründe, um Funktionen zu verwenden, sind:&lt;br /&gt;
;Wiederverwendung von Code: Mehrfach verwendete Codestücke müssen nicht mehrfach implementiert werden. Oft unterscheiden sich die Codesequenzen nur in Kleinigkeiten, die man der Funktion über Parameter mitteilen kann.&lt;br /&gt;
;Übersichtlichkeit: Ein gut gegliedertes C-Programm implementiert klar umrissene Aufgaben in einer Funktion, auch wenn diese Funktion nur einmal im Code aufgerufen wird! Dadurch bleibt der Code um die Aufrufstelle besser verständlich, und man kann auf verschiedenen &amp;quot;Ebenen&amp;quot; denken. Eine Funktion wie &amp;quot;Datei öffnen&amp;quot; kann recht komplex sein. Auf höherer Ebene interessieren die Innereien nicht mehr, man möchte sich um andere Dinge kümmern und will den Code an der Stelle garnicht sehen...&lt;br /&gt;
;Rekursive Funktionen: Eine Funktion kann sich auch selbst aufrufen. In dem Falle nennt man die Funktion ''rekursiv''. Zwar lässt sich das, was eine rekursive Funktion tut, auch mit anderen Mitteln formulieren, die keine rekursiven Funktionen brauchen, aber oft ist der rekursive Weg knackiger und klarer formulierbar als eine nicht-rekursiven Ansatz, auch wenn es etwas mehr Resourcen verbraucht.&lt;br /&gt;
;Modulare Programmierung: Funktionen können anhand ihres Aufgabenbereichs auf verschiedene C-Quellen &amp;amp;ndash; sogenannte ''Module'' &amp;amp;ndash; verteilt werden. Funktionen, die etwas mit dem USB-Bus anstellen, werden in einem anderen Modul sein als mathematische Funktionen. Dies erhöht die Übersichtlichkeit und vereinfacht die Entwicklung im Team.&lt;br /&gt;
;Bibliotheken: Standard-Funktionen wie das hier oft auftauchende &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; sind in Bibliotheken gespeichert. Wenn das eigene Programm übersetzt wird, dann müssen nicht mehr alle Standard-Funktionen übersetzt werden, sondern werden nur noch aus der Bibliothek gelesen und ihr Code zum Programm dazugelinkt. Die Bibliotheks-Funktionen wurden schon zu einem früheren Zeitpunkt compiliert und liegen in dieser compilerten Form in der Bibliothek. Das spart mächtig Entwicklungszeit. Man kann auch selbst solche Bibliotheken erstellen und in diversen Projekten wiederverwenden.&lt;br /&gt;
;Generische Programmierung: In C ist es möglich, einer Funktion eine andere Funktion zu übergeben. (Damit ist nicht gemeint, ihr deren ''Rückgabewert'' zu übergeben (was auch ginge), sondern ''die Funktion selbst'' wird als Parameter übergeben und kann aufgerufen werden.) Ein typisches Beispiel dafür sind Sortieralgorithmen. Einem Sortieralgorithmus kann es egal sein, ''was'' er sortiert. Er muss lediglich wissen, ''wie'' er das Zeug zu sortieren hat: aufsteigend, absteigend, als Zahl, in lexikographischer Ordnung, nach der Quersumme, Körper nach Oberfläche, Durchmesser, Gewicht oder Volumen... Diese Vergleichsfunktion, die für zwei Objekte entscheidet, welches davon &amp;quot;kleiner&amp;quot; ist, kann man dem Sortierer übergeben. Will er zwei Werte vergleichen, dann muss er nur die Vergleichsfunktion aufrufen, ohne zu wissen, was diese tut. Damit kann der Sortieralgorithmus unanhängig von den Objekten gehalten werden, mit denen er hantieren soll.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Definition==&lt;br /&gt;
&lt;br /&gt;
In der ''Definition'' der Funktion wird gesagt, welche Werte sie liefern kann, wie sie heisst (Bezeichner) und wieviele und welche Parameter sie hat. Danach folgt ihre Implementierung:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}} ({{Parameterliste}})&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 &lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
Für Funktionen, die keinen Wert zurückliefern, gibt es den speziellen Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der besagt, daß die Funktion nichts zurückgibt. Die einfachste denkbare Funktion ist eine solch void-Funktion. Sie bekommt keine Parameter, gibt nicht zurück und ihr Body ist leer:&lt;br /&gt;
 void dummy()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==return-Anweisung==&lt;br /&gt;
An jeder Stelle des Programmflusses einer Funktion kann diese mit &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; beendet werden.&lt;br /&gt;
&lt;br /&gt;
'''bei void-Funktionen:'''&lt;br /&gt;
 return;&lt;br /&gt;
'''Funktionen mit Rückgabe-Wert:'''&lt;br /&gt;
 return {{Ausdruck|}};&lt;br /&gt;
Die zweite Variante gibt an, welcher Wert zurückgegeben wird.&lt;br /&gt;
 int main (int argc, char * argv[])&lt;br /&gt;
 {&lt;br /&gt;
    if (argc &amp;lt; 2)&lt;br /&gt;
       return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
Falls die letzte Anweisung einer void-Funktion ein &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; ist, kann es auch weggelassen werden wie oben bei der Funktion &amp;lt;tt&amp;gt;dummy&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Aufruf==&lt;br /&gt;
Um die Funktion aufzurufen gibt man ihren Namen an, gefolgt von den durch Komma getrennten Argumenten in runden Klammern wie im Beispiel unten das&lt;br /&gt;
 quadrat (5) &lt;br /&gt;
Da &amp;lt;tt&amp;gt;quadrat&amp;lt;/tt&amp;gt; einen Wert liefert, kann man damit weiter rechnen wie mit einem normalen Ausdruck:&lt;br /&gt;
 if (quadrat (a) + quadrat (b) == quadrat (c))&lt;br /&gt;
    c = quadrat (quadrat (a)); {{comment|c &amp;amp;#61; a hoch 4}}&lt;br /&gt;
&lt;br /&gt;
==Rekursive Funktionen==&lt;br /&gt;
Eine Funktion die sich selbst &amp;amp;ndash; möglicheweise auch über andere Zwischenfunktionen &amp;amp;ndash; wieder selbst aufruft, wird als ''rekursive Funktion'' bezeichnet. In der Definition ist nichts besonderes zu beachten. Ist die Verschachtelungstiefe im laufenden Programm zu tief, dann gibt das natürlich Probleme, aber das gilt bei tief verschachtelten 'normalen' Funktionen abenso...&lt;br /&gt;
&lt;br /&gt;
Das Beispiel berechnet den Größten Gemeinsamen Teiler zweier Zahlen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int ggT (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
     if (0 == a)&lt;br /&gt;
        return b;&lt;br /&gt;
 &lt;br /&gt;
    return ggT (b % a, a);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Ein komplettes kleines Programm:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int quadrat (int param1)&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  zahl = param1 * param1;&lt;br /&gt;
  return zahl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl, ergebnis;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Bitte Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = quadrat (zahl);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, zahl, ergebnis);&lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, 5, quadrat (5));&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur ausserhalb von Blöcken. Geschachtelte Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen beim Aufruf die Klammern angeben werden:&lt;br /&gt;
 dummy();&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Prototypen==&lt;br /&gt;
Wie oben erwähnt, kann ein Unterprogramm an jeder beliebigen Stelle im Programm stehen. Damit ist jedoch eine Bedingung verknüpft: Das Unterprogramm muß in der Datei oberhalb des ersten Aufrufes definiert worden sein. Wenn Sie ein Unterprogramm in Zeile 10 zum ersten mal aufrufen, müssen Sie die Deklaration davor erledigt haben. Verstanden?&lt;br /&gt;
Um dies zu erreichen, gibt es zwei Möglichkeiten: &lt;br /&gt;
&lt;br /&gt;
Entweder Sie schreiben alle Unterprogramme vor &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; in die Datei. Dies muß jedoch wiederum so geschehen, dass Funktionen zum Zeitpunkt ihres Aufrufes bereits bekannt sind! &lt;br /&gt;
Wo dies nicht möglich ist (z.B. sich gegenseitig aufrufende Unterprogramme), oder wenn Sie das stört, müssen Sie Prototypen verwenden. &lt;br /&gt;
Wie definiert man nun Prototypen? Sie kopieren einfach die erste Zeile des Unterprogrammes (z.B. &amp;quot;&amp;lt;tt&amp;gt;void ausgeben (int zahl)&amp;lt;/tt&amp;gt;&amp;quot;), fügen einen Strichpunkt&amp;amp;nbsp;&amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;an und fügen es an einer geeigneten Stelle ein (so, dass alle Aufrufe später in der Datei kommen). &lt;br /&gt;
Solche Definitionen stehen gewöhnlich am Anfang der Quelldatei oder in einer Header-Datei, die eingebunden wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl);  /* Der Prototyp */&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
   ausgeben (12);&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl)   /* Die eigentliche Prozedur */&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Ausgabe: %d\n&amp;quot;, zahl);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Parameterübergabe==&lt;br /&gt;
&lt;br /&gt;
Alle Werte, die an Prozeduren und Funktionen übergeben werden, werden grundsätzlich '''kopiert'''.&lt;br /&gt;
Das hat folgende Auswirkungen:&lt;br /&gt;
&lt;br /&gt;
# Änderungen an einem Parameter in einer Funktion erscheinen ''nicht'' beim Aufrufer!&lt;br /&gt;
# Möchte man, dass eine Funktion einen Wert trotzdem dauerhaft ändern soll, so muss die Adresse des Wertes via [[#Zeiger|Zeiger]] übergeben werden.&lt;br /&gt;
# Werden [[#Strukturen|Strukturen]] übergeben, so wird von ihnen eine Kopie erstellt, was bei großen Strukturen viel Zeit und Arbeitsspeicher kostet. Deshalb wird häufig nur die Adresse von Strukturen übergeben, da die Adresse viel schneller und platzsparender als die Struktur selbst kopiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele:'''&lt;br /&gt;
 void erhoehe (int x)&lt;br /&gt;
 {&lt;br /&gt;
    x = x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe(a);&lt;br /&gt;
    {{comment|a ist immer noch 0}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Beim Aufruf von &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; wird eine Kopie des Wertes von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; (im Beispiel also 0) erstellt und der Prozedur als Parameter &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; übergeben. Weil dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat dies keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|erhoehe den Wert an der Adresse x um eins}}&lt;br /&gt;
    *x = *x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe (&amp;amp;a);&lt;br /&gt;
    {{comment|a ist jetzt 1}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Jetzt wird im Hauptprogramm mittels [[#Adress-Operator und Dereferenzierung|Adress-Operator]] &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; die Speicheradresse von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; bestimmt. Dann wird eine ''Kopie der Adresse'' an das Unterprogramm &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; übergeben. Jetzt kennt das Unterprogramm die&lt;br /&gt;
Adresse des Originals &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und kann direkt mit dem Inhalts-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&lt;br /&gt;
'''Besonderheit bei Feldern'''&lt;br /&gt;
&lt;br /&gt;
Bei der Übergabe von [[#Felder|Feldern]] gibt es eine Besonderheit. Schreibt man nämlich den Namen eines Feldes, so ist das nichts anderes als die '''Speicheradresse des ersten Elements'''.&lt;br /&gt;
Bei der Übergabe eines Feldes wird also eine Kopie der Startadresse übergeben. Somit kann das Unterprogramm auf den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 void erhoehe (int x[])&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
   int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
   erhoehe (a);&lt;br /&gt;
   {{comment|a hat jetzt folgenden Inhalte: 11, 23, 35}}&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Dass die Übergabe einer Adresse erfolgt, sieht man an folgendem Beispiel, das von der Funktionsweise '''absolut identisch''' mit dem vorhergehenden ist:&lt;br /&gt;
&lt;br /&gt;
 {{comment|Bei Parametern gibt es keinen Unterschied zwischen Zeiger und Feld}}&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
    int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
    erhoehe (a);&lt;br /&gt;
 &lt;br /&gt;
    {{comment|a hat jetzt folgenden Inhalt: 11, 23, 35}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
Die Länge des Feldes wird nicht automatisch übergeben. Dafür ist ggf. ein zusätzlicher Parameter notwendig.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Variable Argumentanzahl==&lt;br /&gt;
== Funktionen indirekt aufrufen ==&lt;br /&gt;
Siehe [[#Zeiger auf Funktionen|Zeiger auf Funktionen]]&lt;br /&gt;
&lt;br /&gt;
=Zeiger II=&lt;br /&gt;
&lt;br /&gt;
Zeiger haben wir bereits weiter oben kennen gelernt. Zeiger sind ein zentrales Konzept in C und sollen hier etwas eingehender behandelt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger-Arithmetik==&lt;br /&gt;
In C kann man den Wert eines Zeigers verändern. Betrachten wir dazu die Funktion &amp;lt;tt&amp;gt;suche_0&amp;lt;/tt&amp;gt;, die einen Zeiger auf einen &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; erhält. Die Funktion soll ab der gegebenen Adresse nach dem ersten long-Wert suchen, der 0 ist, und dessen Adresse zurückgeben:&lt;br /&gt;
 long * suche_0 (long * addr)&lt;br /&gt;
 {&lt;br /&gt;
    while (*addr != 0)&lt;br /&gt;
       addr = addr + 1;&lt;br /&gt;
 &lt;br /&gt;
    return addr;&lt;br /&gt;
 }&lt;br /&gt;
In der Bedingung der while-Schleife wird der Inhalt an der Speicherstelle &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf 0 getestet. Ist der Wert 0, dann wird die Schleife beendet und die Adresse zurückgeliefert. Ist der Wert ungleich 0, dann wird &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf den nächste long gesetzt, &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; also um 4 Bytes weitergezählt. &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ist ja ein Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, und ein &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; ist 4 Bytes lang.&lt;br /&gt;
&lt;br /&gt;
Die Bedeutung von&lt;br /&gt;
 address + n&lt;br /&gt;
ist also, die Adresse um das &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;-fache der Größe des Typs, auf den &amp;lt;tt&amp;gt;address&amp;lt;/tt&amp;gt; zeigt, zu erhöhen. Dabei ist &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; eine ganze Zahl und darf auch negativ sein.&lt;br /&gt;
&lt;br /&gt;
Hier noch ein Beispiel einer Funktion, die nach einer Person mit einer bestimmten ID sucht (für die Definition von &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; siehe [[#Strukturen|Strukturen]]). Der Parameter &amp;lt;tt&amp;gt;person&amp;lt;/tt&amp;gt; ist dabei ein Array von Strukturen. Eine Person mit der gesuchten ID muss existieren, ansonsten hat die Suchfunktion kein definiertes Verhalten.&lt;br /&gt;
 {{comment|Sucht nach einer Person mit der ID person_id}}&lt;br /&gt;
 struct Person * &lt;br /&gt;
 suche_person_id (struct Person * person, int person_id)&lt;br /&gt;
 {&lt;br /&gt;
    while (person-&amp;gt;id != person_id)&lt;br /&gt;
       person++;&lt;br /&gt;
 &lt;br /&gt;
    return person;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:1em; padding:1em; border:solid 2px #FF0040;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- Vorlage:FarbigerRahmen funzt hier net --&amp;gt;&lt;br /&gt;
Beachte, daß es nicht sinnvoll ist, zwei Zeiger zu addieren oder zu multiplizieren. Ausserdem ist das &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt; der Zeiger-Arithmetik nicht kommutativ. Eine Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, der an Adresse 1 im Speicher zeigt, wird man schreiben als&lt;br /&gt;
 (long *) 1&lt;br /&gt;
Addiert man darauf eine ganze Zahl, dann haben die entstehenden Ausdrücke unterschiedliche Werte:&lt;br /&gt;
 (long *) 1 + 2    {{comment|zeigt zu Adresse 9}}&lt;br /&gt;
 (long *) 2 + 1    {{comment|zeigt zu Adresse 6}}&lt;br /&gt;
 (long *) (1 + 2)  {{comment|zeigt zu Adresse 3}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==void-Pointer==&lt;br /&gt;
Eine besondere Art von Zeiger ist der void-Pointer&lt;br /&gt;
 void * addr;&lt;br /&gt;
Ein void-Pointer ist ein &amp;quot;Zeiger auf irgendwas&amp;quot;, dementsprechend kann er nicht dereferenziert werden, Anwenden von &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf einen solchen Zeiger gibt also einen Fehler. Ausserdem ist es nicht möglich, mit einem void-Pointer Zeigerarithmetik zu machen, weil er nicht auf eine definierte Art von Objekt zeigt. Der Vorteil eines void-Pointers ist, daß er jede Art von Zeiger aufnehmen kann.&lt;br /&gt;
&lt;br /&gt;
Dazu betrachten wir die Funktion &amp;lt;tt&amp;gt;send_buf&amp;lt;/tt&amp;gt;, die eine Adresse erhält und ab dieser Adresse &amp;lt;tt&amp;gt;num&amp;lt;/tt&amp;gt; Bytes versenden soll. Wir könnten die Funktion so schreiben:&lt;br /&gt;
 void send_buf (unsigned char * buf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   ...&lt;br /&gt;
Das ist jedoch hässlich, wenn wir damit etwas anderes verschicken wollen als &amp;lt;tt&amp;gt; unsigned char&amp;lt;/tt&amp;gt;, etwa eine Struktur wie &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; (vom Typ &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;):&lt;br /&gt;
 send_buf ((unsigned char*) &amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
Ohne den Cast der Adresse von &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; zu einem Zeiger auf &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt; bekommt man eine Warnung oder gar einen Compilerfehler.&lt;br /&gt;
Dieses Zeiger gecaste ist mühsam und hässlich, es muss bei jedem Aufruf der Funktion explizit hingeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Besser ist es, den ersten Parameter der Funktion als void-Pointer zu definieren und den Cast in der Funktion zu machen:&lt;br /&gt;
 void send_buf (void * vbuf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   unsigned char *buf = (unsigned char*) vbuf;&lt;br /&gt;
   ...&lt;br /&gt;
Durch den Cast in der Funktion kann auf den Inhalt des Zeigers zugegriffen werden. Man muss nur festlegen, ''wie'' man zugreifen will, nämlich als &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Der Aufruf kann jetzt ohne Pointer-Cast erfolgen: &lt;br /&gt;
 send_buf (&amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
&lt;br /&gt;
==Null-Pointer==&lt;br /&gt;
==Zeiger als Parameter==&lt;br /&gt;
Wenn Sie ein Unterprogramm aufrufen, können Sie diesem Parameter übergeben, aber keine Werte zurückgekommen (außer den Funktionswert bei Funktionen). Dies hat einen guten Grund: beim Aufruf werden nicht die aufgerufenen Parameter benutzt, sondern es werden deren Werte in neue Variablen kopiert. Diese Variablen werden am Ende des Unterprogrammes &amp;quot;zerstört&amp;quot;, ohne ihre Werte an die aufrufenden Parameter zu übergeben. Jede Veränderung eines Parameters hat daher keine Auswirkung auf den Parameter.&lt;br /&gt;
&lt;br /&gt;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der C-Compiler legt dann immer noch Kopien an. In dieser Kopie steht aber kein Wert, sondern die Adresse einer Varaiblen. Und auf diese können Sie dann zugreifen. Denken Sie nur an &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; &amp;amp;ndash; da übergeben Sie ja auch die Adresse einer Variablen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void erhoehe (int *zeiger)&lt;br /&gt;
{&lt;br /&gt;
  *zeiger = 1 + *zeiger;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  erhoehe (&amp;amp;zahl);&lt;br /&gt;
  printf (&amp;quot;\nDie erhoehte Zahl lautet: %d\n&amp;quot;, zahl);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Zeiger auf Funktionen==&lt;br /&gt;
&lt;br /&gt;
Stell dir vor, du willst einen Sortieralgorithmus wie Bubble-Sort oder Quick-Sort oder wie sie alle heissen implementieren. Für den Sortieralgorithmus ist eigentlich egal, ''was'' er zu sortieren hat. Ihm ist es egal, ob er Zahlen aufwärts sortieren soll oder Strings in lexikographischer Reihenfolge, ob Objekte nach Größe oder Gewicht, Personen nach Alter oder Adressen nach Postleitzahl. Das einzige, was der Algorithmus wissen muss, ist ''wie'' er zwei Objekte zu vergleichen hat und wann eines davon &amp;quot;kleiner&amp;quot; (im Sinne der Ordnung, nach der sortiert werden soll) ist. &lt;br /&gt;
&lt;br /&gt;
Eine einfache Sortierfunktion, die nur zwei Zahlen sortiert, könnte man also so schreiben: &lt;br /&gt;
 {{comment|Sortiert ein Array von 2 int-Zeigern nach den Inhalten &lt;br /&gt;
  * an den Zeiger-Adressen}}&lt;br /&gt;
 void sort2_a (int * p[])&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Inhalte vergleichen...}}&lt;br /&gt;
    if (*p[0] &amp;gt; *p[1])&lt;br /&gt;
    {&lt;br /&gt;
       {{comment|... und ggf. Dreieckstausch der 2 Zeiger}}&lt;br /&gt;
       int * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Die Funktion bekommt ein Array der Länge&amp;amp;nbsp;2. In diesem Array stehen Zeiger auf die zu sortierenden Zahlen. Ein Array mit Zeigern zu verwenden und nicht ein Array von &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; scheint recht umständlich, und das ist es hier auch. Aber stell dir vor, du willst Strukturen wie &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; sortieren. Das Tauschen zweier Strukturen würde bedeuten, ihre kompletten Inhalte umzukopieren! Das wäre sehr aufwändig. Viel einfacher ist das Kopieren, wenn nur die Adressen zu kopieren sind.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; könnte dann so aussehen:&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void sortiere (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|p[] enthält 2 int-Zeiger: die Adressen von a und b}}&lt;br /&gt;
    int * p[2];&lt;br /&gt;
    p[0] = &amp;amp;a; &lt;br /&gt;
    p[1] = &amp;amp;b; &lt;br /&gt;
 &lt;br /&gt;
    {{comment|Sortiere die Zeiger}} &lt;br /&gt;
    sort2_a (p);&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Sortiert: %d, %d\n&amp;quot;, *p[0], *p[1]);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Für den nächsten Schritt überlegen wir uns, daß das Array in &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; ebensogut void-Pointer enthalten kann. Die einzige Stelle, an der wir auf die endgültigen int-Objekte zugreifen, ist der Vergleich. Diesen Vergleich lagern wir in die Funktion &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; aus:&lt;br /&gt;
 {{comment|Bekommt zwei void-Pointer und vergleicht die Inhalte.&lt;br /&gt;
  * Liefert 0 bei Gleichheit,&lt;br /&gt;
  * -1 wenn der erste Wert kleiner ist als der zweite und&lt;br /&gt;
  * 1  wenn der erste Wert größer ist als der zweite}}&lt;br /&gt;
 int compare_int (void * p0, void * p1)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Um über die Zeiger zugreifen zu können müssen wir diese&lt;br /&gt;
     * erst zu int-Zeigern casten}}&lt;br /&gt;
    int a0 = * (int*) p0;&lt;br /&gt;
    int a1 = * (int*) p1;&lt;br /&gt;
 &lt;br /&gt;
    if (a0 &amp;gt; a1)  return  1;&lt;br /&gt;
    if (a0 &amp;lt; a1)  return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void sort2_b (void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare_int (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Ein Aufruf von &amp;lt;tt&amp;gt;sort2_b&amp;lt;/tt&amp;gt; sieht dann genauso aus wie ein Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt definieren wir uns den neuen Datentyp &amp;lt;tt&amp;gt;comparator_t&amp;lt;/tt&amp;gt;. Dieser ist ein Zeiger auf eine Funktion, die zwei void-Pointer erhält und einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; zurückliefert, also analog arbeitet zu &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; von oben. &lt;br /&gt;
&lt;br /&gt;
Unsere Sortierfunktion bekommt nun neben dem zu sortierenden Zeiger-Array auch eine Vergleichsfunktion &amp;lt;tt&amp;gt;compare&amp;lt;/tt&amp;gt; mitgeliefert, die sie aufruft, wenn sie zwei Objekte vergleichen will&lt;br /&gt;
 {{comment|comparator_t sind Zeiger auf Funktionen, die 2 void-Pointer&lt;br /&gt;
  * erhalten und einen int zurückliefern}}&lt;br /&gt;
 typedef int (*comparator_t) (void*, void*);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Der Sortierer bekommt einen Funktionszeiger auf den Vergleicher.&lt;br /&gt;
  * Der Aufruf vom compare geht so als wäre es eine &amp;quot;normale&amp;quot; Funktion&lt;br /&gt;
  * (ist es im Endeffekt ja auch)}}&lt;br /&gt;
 void sort2_c (comparator_t compare, void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Bei einem Aufruf von &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; muss man dann einen Komparator mit angeben. In einem Beispiel analog zu &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; von oben ist das:&lt;br /&gt;
 sort2_c (compare_int, p);&lt;br /&gt;
Um zwei Strings lexikographisch zu sortieren nehmen wie die Standard-Funktion &amp;lt;tt&amp;gt;strcmp&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void foo()&lt;br /&gt;
 {&lt;br /&gt;
    char * worte[] = { &amp;quot;Wort1&amp;quot;, &amp;quot;Wort2&amp;quot; };&lt;br /&gt;
 &lt;br /&gt;
    sort2_c ((comparator_t) strcmp, (void**) worte);&lt;br /&gt;
 }&lt;br /&gt;
Die Casts sind hier erforderlich. Alternativ könnte man &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; mit reinen void-Pointern versorgen und diese dann dort umcasten.&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
&lt;br /&gt;
Die Syntax zur Definition/Deklaration von Funktionszeigern ist etwas verzwackt. Zur Verdeutlichung ein paar Beispiele. Dabei legt das linke &amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt; jeweils den Return-Typ fest.&lt;br /&gt;
 {{comment|definiert einen neuen Funktionszeiger-Typ}}&lt;br /&gt;
 typedef {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert einen Funktionszeiger}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert ein Array von Funktionszeigern (mit Initializer)}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}[]) ({{type}}, {{type}}, ...) = { wert1, wert2, ... };&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer}}&lt;br /&gt;
 ({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer und ruft die Funktion auf}}&lt;br /&gt;
 (({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}) (arg1, arg2, ...);&lt;br /&gt;
&lt;br /&gt;
=Standard-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==String-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===strcpy===&lt;br /&gt;
Bei vielen Compilern können sie einem String nicht direkt einen Wert (Text) zuweisen. Dazu müssen Sie dann die Prozedur strcpy() benutzen. Diese erwartet als ersten Parameter den Namen einer String-Variablen (ohne eckige Klammern) und als zweiten Parameter den eines (anderen) Strings. Letzterer kann auch ein in doppelten Hochkommas (&amp;quot;) eingeschlossener Text sein. Die Funktion fügt am Ende automatisch ein 0-Zeichen ein. Um diese Funktion nutzen zu können, müssen Sie die Datei string.h includieren! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri1[21], eingabe[21];&lt;br /&gt;
&lt;br /&gt;
  strcpy (stri1, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Der 1. String: %s\n&amp;quot;, stri1);&lt;br /&gt;
  printf (&amp;quot;Bitte geben Sie maximal 20 Zeichen ein: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%s&amp;quot;, eingabe);&lt;br /&gt;
  strcpy (stri1, eingabe);&lt;br /&gt;
  printf (&amp;quot;\n%s = %s&amp;quot;, stri1, eingabe);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis:''' &lt;br /&gt;
Da ein String, wie jedes Feld, eigentlich ein Zeiger ist, dürfen Sie kein &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; bei &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; angeben!&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
Es werden zwei gleich große Strings definiert: &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;eingabe&amp;lt;/tt&amp;gt;, mit je 20 &amp;quot;nutzbaren&amp;quot; Zeichen. &lt;br /&gt;
In &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; wird die Zeichenkette &amp;lt;tt&amp;gt;&amp;quot;hallo&amp;quot;&amp;lt;/tt&amp;gt; hineinkopiert. Das 0-Zeichen am Ende wird automatisch angefügt. &lt;br /&gt;
Der String wird ausgegeben. Als neues &amp;quot;Sonderzeichen&amp;quot; kommt &amp;lt;tt&amp;gt;%s&amp;lt;/tt&amp;gt; ins Spiel. Es hat die gleiche Aufgabe wie &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt;, nur für Strings. &lt;br /&gt;
Sie werden gebeten, eine String einzugeben. &lt;br /&gt;
Dieser String wird danach in die Variable &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; kopiert. &lt;br /&gt;
Beide Strings, die ja nun die gleiche Zeichenkette enthalten, werden ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===strlen===&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;strlen&amp;lt;/tt&amp;gt;, die als Parameter eine String-Variable erwartet, liefert die Länge diese Strings zurück. Sie werden jetzt vermutlich sagen: &amp;quot;Das ist doch klar, wie lang der String ist. Ich habe es ja bei der Deklaratin angegeben&amp;quot;. Das stimmt schon, aber denken Sie noch einmal an die null-terminierten Strings. Das 0-Zeichen steht am Ende des Strings (am Ende der gültigen Zeichenfolge), aber nicht unbedingt am Ende des reservierten Speicherplatzes. Haben Sie eine Variable &amp;quot;char Variable[21];&amp;quot;, und ihr den Wert &amp;quot;hallo&amp;quot; zugewiesen, dann steht das null-Zeichen in Variable[5]. Der &amp;quot;gültige&amp;quot; String ist also 5 Zeichen (0-4) lang. Und genau das (5) würde strlen zurück liefern. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri[21];&lt;br /&gt;
  &lt;br /&gt;
  strcpy (stri, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
  printf (&amp;quot;Der String ist %d Zeichen lang&amp;quot;, strlen (stri));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird vor allem gebraucht, wenn Sie direkt auf den String zugreifen, mittels &amp;lt;tt&amp;gt;stri[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;stri[1]&amp;lt;/tt&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
==Ein- und Ausgabe-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===Bildschirm-Ausgabe===&lt;br /&gt;
Bisher war das Tutorial trotz aller Beispiele reine Theorie. Sie konnten zwar Programme schreiben, aber die Funktion nicht testen. Hier lernen Sie nun, wie Sie etwas am Bildschirm ausgeben.&lt;br /&gt;
&lt;br /&gt;
Die dazu notwendige Funktione heisst &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (das '&amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt;' ist kein Fehler!). Diese Anweisung gibt die ihr übergebenen Parameter auf das Standard-Ausgabegerät aus, in der Regel also auf den Bildschirm. Sie kann beliebig viele Parameter übernehmen. Es müssen jedoch Standard-Datentypen (z.B. &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;...) sein! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
    int zahl1 = 12;&lt;br /&gt;
    char zeichen1 = 'A';&lt;br /&gt;
    &lt;br /&gt;
    printf (&amp;quot;Das ist Text, und er wird als solcher ausgegeben. \n&amp;quot;);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zahl1' ist: %d \n&amp;quot;, zahl1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %c \n&amp;quot;, zeichen1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %d \n&amp;quot;, zeichen1);&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt Text aus. Das Zeichen am Ende (&amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;) bedeutet &amp;quot;New Line&amp;quot;, es bewegt den Cursor an den Anfang der nächsten Zeile. &lt;br /&gt;
&lt;br /&gt;
Der zweite &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt auch Text aus, am Ende befindet sich wieder das &amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;, um einen Zeilenvorschub zu erreichen. Das &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; wird vom Compiler durch den ersten Parameter ersetzt, der nach dem Text angegeben wird. In diesem Fall wird &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; also durch den Wert der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ersetzt. Das &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; im &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; bedeutet &amp;quot;Dezimalzahl&amp;quot;, der Computer gibt also eine ganze Zahl aus. &lt;br /&gt;
&lt;br /&gt;
In der dritten Ausgabe wird ein Zeichen ausgegeben. Diesmal bedeutet &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; &amp;quot;char&amp;quot; (Zeichen). Es wird also &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; durch ein &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt; ersetzt, denn die Variable &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; wird als Character interpretiert. &lt;br /&gt;
&lt;br /&gt;
Die letzte Ausgabe interpretiert den Inhalt von &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; als Zahl, und gibt dager den ASCII-Wert von &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, also 65 aus. Das ist ein typisches Beispiel für das mögliche unterschiedliche Interpretieren einer  Variablen!&lt;br /&gt;
&lt;br /&gt;
===Tastatur-Eingabe===&lt;br /&gt;
&lt;br /&gt;
Um ein &amp;quot;gscheites&amp;quot; Programm schreiben zu können, muß man wissen, wie der Benutzer über die Tastatur Befehle eingeben kann. Die dafür notwendigen Funktionen stelle ich in diesem Kapitel vor.&lt;br /&gt;
Die wichtigste Funktion ist &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt;. Er liest Daten von der Tastatur. Die Syntax entspricht derer von &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int  zahl1;&lt;br /&gt;
char zeichen1;&lt;br /&gt;
&lt;br /&gt;
printf (&amp;quot;Bitte geben Sie eine Zahl ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl1);&lt;br /&gt;
printf (&amp;quot;Geben Sie einen Zeichen ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%c&amp;quot;, &amp;amp;zeichen1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Programm gibt eine Eingabeaufforderung aus. Dann erwartet es vom Benutzer, daß er eine Zahl eingibt, die mit [ENTER] bestätigt wird. Dieser Wert wird in &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; abgespeichert. Danach erfolgt wiederum eine Aufforderung zur Eingabe, diesmal eines einzelnen Zeichens. Dieses kann man nun eingeben und ebenfalls mit [ENTER] bestätigen.&lt;br /&gt;
&lt;br /&gt;
Macht man keine dem Datentyp der erwarteten Variable entsprechende Eingabe, dann bricht das Programm mit einer Fehlermeldung ab (wenn man z.B. &amp;quot;1_T2&amp;quot; eingibt, wenn eine Zahl erwartet wird)!&lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; vor den Parametern ist notwendig. Warum, das erfahren Sie im Kapitel &amp;quot;Unterprogramme&amp;quot;. Für die Profis eine Kurz-Erklärung: Das Unterprogramm &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; bekommt zwar einen Wert übergeben, kann aber keinen zurückliefern (&amp;quot;call by value&amp;quot;). Daher wird kein Wert, sondern ein Zeiger auf eine Variable übergeben. Mit dem &amp;amp; Zeichen bekommen Sie die Adresse einer Variablen (&amp;quot;call by reference&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=Parameter von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;=&lt;br /&gt;
Das Unterprogramm &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; kann, wie jede andere Funktion, Parameter besitzen. Doch keine selbst gewählten, sondern nur bestimmte. Doch warum braucht main Parameter? Denken Sie einmal an alle Betriebssystembefehle:&lt;br /&gt;
&amp;lt;tt&amp;gt;dir *.exe &amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;copy *.* a:&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;ls -la &amp;lt;/tt&amp;gt;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;&amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen!&lt;br /&gt;
&lt;br /&gt;
=Kurzreferenz=&lt;br /&gt;
==Syntax-Bausteine==&lt;br /&gt;
&lt;br /&gt;
Die Erklärung des Aufbaus von C-Befehlen erfolgt neben einfachen Beispielen auch durch ihren prinzipellen Aufbau. In diesen Syntax-Beschreibungen finden sich immer wieder die gleichen Bausteine, die hier näher erklärt werden sollen. Falls die solch ein Syntax-Baustein begegnet, kannst Du ihn anclicken und kommst dann zu seiner Erläuterung. &lt;br /&gt;
&lt;br /&gt;
In den Beispielen selbst gehören auch die spitzen Klammern zu dem Baustein (was daran zu erkennen ist, daß auch die Klammern eingefärbt sind). Die Klammern dürfen in einem konkreten C-Programm daher nicht eingetippt werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bezeichner&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Bezeichner in C dienen dazu, Variablen zu identifizieren und ihnen sprechende Namen zu geben, um die Quelle lesbarer zu machen. Man braucht Bezeichner auch, um selbstdefinierte Datentypen zu benennen und zum Benennen von Struct- und Union-Komponenten sowie als Namen für Funktionen und Sprungmarken (Labels).&lt;br /&gt;
&lt;br /&gt;
Bezeichner dürfen aus den Kleinbuchstaben &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;z&amp;lt;/tt&amp;gt;, den Großbuchstaben &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;Z&amp;lt;/tt&amp;gt;, dem Unterstrich&amp;amp;nbsp;&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt; und den Ziffern &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;9&amp;lt;/tt&amp;gt; aufgebaut werden, wobei an erster Stelle jedoch keine Ziffer stehen darf.&lt;br /&gt;
&lt;br /&gt;
Es wird zwischen Groß- und Kleinschreibung unterschieden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Ausdruck in C ist ein Konstrukt, das einen Wert hat. Ob dieser Wert eine ganze Zahl ist, eine Kommazahl oder ein Zeiger, etc. ist dabei egal. Die einfachsten Ausdrücke sind Konstanten wie&lt;br /&gt;
 2&lt;br /&gt;
oder Variablen wie&lt;br /&gt;
 ein_zahl&lt;br /&gt;
Mehrere Ausdrücke können durch [[#Liste der Operatoren|Operatoren]] zu komplexeren Ausdrücken kombiniert werden, etwa&lt;br /&gt;
 eine_zahl + andere_zahl == 2&lt;br /&gt;
oder &lt;br /&gt;
 eine_zahl = 2&lt;br /&gt;
Letzterer hat den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; und den Nebeneffekt, daß er diesen Wert an &amp;lt;tt&amp;gt;eine_zahl&amp;lt;/tt&amp;gt; zuweist.&lt;br /&gt;
&lt;br /&gt;
Auch der Aufruf einer Funktion, die einen Rückgabewert liefert, ist ein Ausdruck:&lt;br /&gt;
 sin (1.2)&lt;br /&gt;
und kann zum Aufbau komplexerer Ausdrüche verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bedingung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Bedingung ist ein Ausdruck, bei der nur interessiert, ob dieser zu&amp;amp;nbsp;0 (unwahr) auswertet oder zu ungleich&amp;amp;nbsp;0 (wahr). Solche Ausdrücke findet man in if-Anweisungen, in Schleifenbedingungen und bedingten Zuweisungen&lt;br /&gt;
 (ein_wert &amp;lt; 2) || (ein_wert &amp;gt; 40)&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Lvalue ist ein Ausdruck, dem etwas zugewiesen werden kann. Der Name ''Lvalue'' kommt aus dem Englischen. Das ''L'' steht abkürzend für left. Ein Lvalue ist damit ein Ausdruck, der auf der linken Seite eine Zuweisung in C stehen darf. Das &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; in den folgenden Beispiel-Ausdrücken muss ein Lvalue sein:&lt;br /&gt;
 x = y-1&lt;br /&gt;
&lt;br /&gt;
 x++&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Konstante&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Konstante ist ein Ausdruck, dessen Wert dem Compiler bekannt ist. Beispiele für Konstanten sind etwa&lt;br /&gt;
 7&lt;br /&gt;
 'B'&lt;br /&gt;
 -13.98e12&lt;br /&gt;
 1+(2*3)&lt;br /&gt;
und die Werte von [[#Enum|Enum]]s. &lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; aus dem folgenden Codestück definiert jedoch keine Konstante in diesem Sinne&lt;br /&gt;
 const double Pi = 3.14159256;&lt;br /&gt;
denn in einem anderen Quellmodul könnte durch die Deklaration&lt;br /&gt;
 extern const double Pi;&lt;br /&gt;
das Symbol &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; bekannt sein, ohne daß sein Wert bekannt ist!&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Adresse&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Adresse ist ein Ausdruck, der einen Speicherort (physikalisch oder virtuell) halten kann. Adressen erhält man dadurch, daß man einem Bezeichner den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt;voranstellt, Adressen durch Arithmetik berechnet oder Zahlen zu Adressen castet. Folgende Ausdrücke sind Adressen (eine sinnvolle Deklaration der auftretenden Variablen vorausgesetzt)&lt;br /&gt;
 &amp;amp; eine_zahl&lt;br /&gt;
 &amp;amp; ein_array[10]&lt;br /&gt;
 &amp;amp; ein_struct&lt;br /&gt;
 &amp;amp; ein_struct.komponente&lt;br /&gt;
 (int *) 0x1234&lt;br /&gt;
 (int *) eine_zahl&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Deklaration&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Anweisungen sind gewissermassen die Atome (oder Moleküle?), aus denen ein C-Programm besteht. Jedes C-Programm ist eine Abfolge von Deklarationen und Anweisungen. Einfache Anweisungen erhält man, in dem man einen Ausdruck nimmt und einen Strichpunkt dahinter schreibt:&lt;br /&gt;
 {{Ausdruck|}};&lt;br /&gt;
wie in&lt;br /&gt;
 x = x+1;&lt;br /&gt;
&lt;br /&gt;
Andere Anweisungen sind die unten aufgeführten Schleifen und die if- sowie die switch-Anweisung.&lt;br /&gt;
&lt;br /&gt;
Mehrere Deklarationen und Anweisungen können zu einem Block zusammengefasst werden. Dieser Block stellt dann wieder eine einzelne Anweisung dar und kann genau so gehandhabt werden!&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
In diesem Sinne ist auch z.B. die Syntax der if-Anweisung zu verstehen&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
besagt, daß der abhängig ausgeführte Code eine einzelne Anweisung sein darf oder eben ein kompletter Block oder die Verschachtelung mehrerer Blöcke etc.&lt;br /&gt;
&lt;br /&gt;
Eine Anweisung kann auch &amp;quot;leer&amp;quot; sein, also nichts tun. Diese Anweisungen sind der leere Block&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
und der Strichpunkt&lt;br /&gt;
 ;&lt;br /&gt;
die man gelegentlich in Schleifen findet:&lt;br /&gt;
 while (!timeout())&lt;br /&gt;
    {}&lt;br /&gt;
oder hinter Sprungmarken, die sonst direkt vor einer schliessenden Blockklammer stünden:&lt;br /&gt;
 {&lt;br /&gt;
    ...&lt;br /&gt;
    goto ein_label;&lt;br /&gt;
    ...&lt;br /&gt;
    {{Label|ein_label}}:;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Nicht jede Anweisung ist an jeder Stelle eines C-Programms erlaubt, so darf ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; nut innerhalb einer Schleife stehen. Gleiches gilt für &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;, das aber auch innerhalb eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; vorkommen darf.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Dies steht für einen Datentyp. Es kann ein elementarer Typ sein wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;, ein Zeiger darauf wie &amp;lt;tt&amp;gt;char*&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;void*&amp;lt;/tt&amp;gt;, und auch Qualifier enthalten wie das &amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt; im Typ &amp;lt;tt&amp;gt;unsigned long long&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Zu den Typen gehören auch zusammengesetzte Datentypen wie Strukturen und Unions, mit &amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt; selbst definierte Typen und natürlich Zeiger darauf, wie aus dem Abschnitt [[#Datentypen|Datentypen]]:&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person *&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;data32_t&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;&lt;br /&gt;
und Zeiger auf Funktionen.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Parameterliste&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
Die Parameterliste bei einer Funktionsdefinition gibt an, wieviel Übergabeparameter sie bekommt, wie diese heissen und welchen Typs diese sind. Der prinzipielle Aufbau ist&lt;br /&gt;
 {{Type}} {{Bezeichner}}, {{Type}} {{Bezeichner}}, ...&lt;br /&gt;
Falls die Funktion keine Parameter hat, dann ist die Parameterliste leer.&lt;br /&gt;
&lt;br /&gt;
Hier als Beispiel die zweiparametrige Funktion &amp;lt;tt&amp;gt;produkt&amp;lt;/tt&amp;gt;. Der erste Parameter heisst&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und ist ein &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;. Der zweite namens&amp;amp;nbsp;&amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; ist vom Typ &amp;quot;Zeiger auf double&amp;quot;, der Inhalt &amp;lt;tt&amp;gt;*b&amp;lt;/tt&amp;gt; ist also auch ein double.&lt;br /&gt;
&lt;br /&gt;
'''Definition der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b)&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
In älteren C-Quellen findet man noch eine andere Syntax für die Deklaration der Parameter, die aber heute praktisch nicht mehr verwendet wird:&lt;br /&gt;
'''alte Definition der Funktion:'''&lt;br /&gt;
 double produkt (a, b)&lt;br /&gt;
 double a, *b;&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Um die Funktion bekannt zu machen, werdendet man eine Deklaration bzw. den Prototypen, der dem Compiler nur mitteilt, welche Parameter die Funktion bekommt und was sie zurückliefert. Für den Aufruf der Funktion muss der Compiler nur diesen Prototyp kennen, ''was'' die Funktion im Endeffekt macht und wie sie implementiert wurde ist egal, sie wird als BlackBox angesehen.&lt;br /&gt;
&lt;br /&gt;
'''Prototyp der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b);&lt;br /&gt;
Hier dürfen die Bezeichner auch fehlen:&lt;br /&gt;
 double produkt (double, double*);&lt;br /&gt;
&lt;br /&gt;
==if==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==if-else==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==for==&lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Eine for-Schleife entspricht folgendem Konstrukt. Dabei sind die drei Ausdrücke optional. Fehlt die Bedingung, dann wird diese als &amp;quot;wahr&amp;quot; angenommen. Die beiden anderen Ausdrücke wird man als Ausdrücke mit Nebeneffekt wählen wie z.B. &amp;lt;tt&amp;gt;x=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;x=x-2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
 {&lt;br /&gt;
    {{Ausdruck|1}};&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_loop}}:&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
    else&lt;br /&gt;
       goto _break;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_continue}}:&lt;br /&gt;
    {{Ausdruck|2}};&lt;br /&gt;
    goto _loop;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_break}}:;&lt;br /&gt;
 }&lt;br /&gt;
Die Labels &amp;lt;tt&amp;gt;_break&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_continue&amp;lt;/tt&amp;gt; entsprechen den Sprungzielen einer &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Anweisung innerhalb von &amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==do-while==&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while  ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
==while==&lt;br /&gt;
 while  ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==switch==&lt;br /&gt;
 switch  ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    ...&lt;br /&gt;
  &lt;br /&gt;
    default:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#break-Anweisung|&amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Konstanten|&amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#continue-Anweisung|&amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#do-while-Schleife|&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Enum|&amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#for-Schleife|&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#goto-Anweisung|&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#return-Anweisung|&amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Liste der Operatoren|sizeof]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Strukturen|&amp;lt;tt&amp;gt;struct&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Eigene Datentypen|&amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Unions|&amp;lt;tt&amp;gt;union&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#while-Schleife|&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund2}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Arithmetische Operatoren&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Dies sind die &amp;quot;normalen&amp;quot; arithmetischen Operationen, wie man sie aus der Schule kennt. Man kann damit und allen anderen Operatoren auch komplexere Ausdrücke aufbauen. Die Prioritäten sind so, wie man sie kennt, also &amp;quot;Punktrechnung vor Strichrechnung&amp;quot;. Will man dies ändern, dann mit den runden Klammern:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;1+2*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 7&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(1+2)*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 9&amp;lt;br/&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}}&amp;amp;nbsp;+&amp;amp;nbsp;{{Ausdruck|}}&amp;lt;/tt&amp;gt; || Addition&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} - {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Subtraktion&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} * {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Multiplikation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} / {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Division&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} % {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Rest der Division (modulo)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;- {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Vorzeichenumkehr, Zweier-Komplement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Logische Operatoren und Vergleiche&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die logischen und die vergleichenden Operatoren liefern als Ergebnis den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (wahr) oder einen Wert ungleich&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (falsch, um genau zu sein den Wert &amp;lt;tt&amp;gt;!0&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Man kann das Ergebnis zwar einer Variablen zuweisen, in aller Regel wird man solche Ausdrücke jedoch in Bedingungen zu &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder in Abbruch-Bedingungen von Schleifen finden.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;&amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches AND: beides wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124;&amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches OR: mind. eines ist wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;! {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches NOT (0 &amp;amp;harr; ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} == {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} != {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist nicht gleich&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bitweise Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~ {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise NOT (Einser-Komplement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise AND&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise ODER&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} ^ {{Ausdruck|}}&amp;lt;/tt&amp;gt; ||bitweise XOR&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Shift-Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;lt;&amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Bits nach links schieben&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;gt;&amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Schieben nach rechts schieben&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Typen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Ein Cast in C kann dazu verwendet werden, den Typ eines Ausdruckes zu ändern oder den Ausdruck mit einer bestimmten Genauigkeit zu berechnen. Wird z.B. eine Berechnung standardmässig in 16 Bit ausgeführt, dann kann man mit einem Cast &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(long) &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
ausdrücken, daß die Berechnung in 32 Bit erfolgen soll. Des weiteren kann man Zeiger und ganze Zahlen und Gleitkommazahlen ineinander umwandeln.&lt;br /&gt;
&lt;br /&gt;
Casts können ''nicht'' dazu verwendet werden, um z.B. eine Zahl in einen String zu konvertieren, der diese Zahl darstellt! Dafür gibt es spezielle Funktionen wie &amp;lt;tt&amp;gt;itoa&amp;lt;/tt&amp;gt;!&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Type}}) {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Cast, Typwandlung&lt;br /&gt;
|-&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;| &amp;lt;tt&amp;gt;sizeof ({{Type}})&amp;lt;/tt&amp;gt; || Eine Konstante, deren Wert die Größe (in Bytes) des Typs ist. &amp;lt;tt&amp;gt;sizeof&amp;lt;/tt&amp;gt; ist auch auf Objekte anwendbar wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, Arrays bekannter Größe, Strukturen und Unions,  Array-, Struktur- und Union-Komponenten, Pointer, etc. Beispiel:&amp;lt;br/&amp;gt;&lt;br /&gt;
 int i, sum=0, array[] = { 1, -13, 4, 0, sizeof (int*) };&lt;br /&gt;
 &lt;br /&gt;
 for (i=0; i&amp;lt; sizeof (array) / sizeof (array[0]); i++)&lt;br /&gt;
    sum += array[i];&lt;br /&gt;
Alle Elemente des Arrays werden aufaddiert, ohne daß deren Anzahl explizit in der Schleife genannt ist.&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zeiger und Adressen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;* {{Adresse}}&amp;lt;/tt&amp;gt; || der Inhalt an Adresse&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp; {{Lvalue}}&amp;lt;/tt&amp;gt; || Adresse von&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Strukturen, Unions, Arrays&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Struct&amp;gt;}}.{{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Zeiger-auf-Struct&amp;gt;}} -&amp;gt; {{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union, deren Adresse man hat&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Adresse}}&amp;amp;#91;{{Ausdruck|}}&amp;amp;#93;&amp;lt;/tt&amp;gt; || Array-Element&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bedingte Auswertung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Bedingung}}) ? {{Ausdruck|}} : {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Auswahl des Wertes abhängig von der Bedingung&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zuweisung und Operatoren mit Nebeneffekt&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die Unterschiede der post- und pre-Varianten der Increment/Decrement kommen in Konstrukten wie &amp;lt;tt&amp;gt;x = *p++&amp;lt;/tt&amp;gt; zum tragen:&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *p++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; p = p+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *++p;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; p = p+1; x = *p;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = (*p)++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; *p = (*p)+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = ++(*p);&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; *p = (*p)+1; x = *p;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} = {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Zuweisung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++ {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-- {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Decrement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ++&amp;lt;/tt&amp;gt; || Post-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} --&amp;lt;/tt&amp;gt; || Post-Decrement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Kurzschreibweisen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Für ganz Faule gibt es anstatt&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a = a @ b&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
für viele Operatoren (hier dargestellt durch ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;@&amp;lt;/tt&amp;gt;) die abkürzende Schreibweise&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a @= b&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} += {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} -= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} *= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} /= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} %= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ^= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;lt;&amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;gt;&amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Autoren'''&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
* Kernighan und Ritchie - Buch&lt;br /&gt;
* Christian Wirth , C Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://wwwuser.gwdg.de/~kboehm/ebook/inhalt.html C-Programmieren unter Linux]&lt;br /&gt;
* [http://www.gdv.uni-hannover.de/documentation.php Skripte zum Selbststudium: C, C++, Java, etc]&lt;br /&gt;
* [http://info.baeumle.com/ansic.html Einführung in ANSI-C]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Quellcode C|!]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Inrfb2</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10392</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10392"/>
				<updated>2007-03-13T11:08:30Z</updated>
		
		<summary type="html">&lt;p&gt;Inrfb2: /* Reihenfolge der Auswertung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Programmiersprache C wurde 1971 als Gundlage für das Betriebssystem UNIX in den USA entwickelt (UNIX ist zu über 90% in C geschrieben). 1978 wurde von Brian Kernighan und Dennis Ritchie eine eindeutige Sprachdefinition entwickelt. Mittlerweile ist C von ANSI und ISO standardisiert.&lt;br /&gt;
&lt;br /&gt;
Heute sind C und ihr Nachfolger C++ die dominierenden Programmiersprachen. Sehr viele Anwendungen sind in C geschrieben, was inzwischen auch auf eingebettete Systeme zutrifft, die lange in Assembler programmiert werden mussten, da keine ausreichend leistungsfähigen Compiler zur Verfügung standen. &lt;br /&gt;
&lt;br /&gt;
Leider ist C nicht einfach zu lernen &amp;amp;ndash; es wurde weder von noch für Hobby-Programmierer entwickelt &amp;amp;ndash; und eignet sich daher nur bedingt für den Einsteiger. Mit etwas Übung und einem optimierenden Compiler kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
Vom Design her ist C eine Hardware-unabhängig Sprache. Das bedeutet, daß C-Programme mit vertretbarem Aufwand auf ein anderes System portiert werden können. Dazu benötigt man lediglich einen anderen Compiler, und Inline-Assembler-Anweisungen (Assembleranweisungen innerhalb eines C-Programmes) müssen der neuen Hardware (Prozessor) angepasst werden. &lt;br /&gt;
&lt;br /&gt;
==Geschichte==&lt;br /&gt;
;1971: C wird entwickelt&lt;br /&gt;
;1978: Kernighan und Ritchie definieren die Sprache.&lt;br /&gt;
;1983: ANSI und ISO standardisieren C.&lt;br /&gt;
;1992: Bjarne Stroustrup enwickelt die Nachfolgesprache C++.&lt;br /&gt;
&lt;br /&gt;
=Aufbau eines C-Programmes=&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
   C-Programme haben keinen fixen Aufbau wie z.B. Pascal. Es gibt zwar gewisse Regeln, aber sonst sind dem Programmierer alle Freiheiten überlassen. Der folgende &amp;quot;Beispiel-Aufbau&amp;quot; ist daher nicht zwingend und kann durchaus verändert werden.&lt;br /&gt;
&lt;br /&gt;
   Natürlich haben C-Programme einen fixen Aufbau! Ebenso wie Pascal-Programme auch unterliegen sie einer strikten Grammatik! &lt;br /&gt;
Auskommentiert --[[Benutzer:SprinterSB|SprinterSB]] 10:23, 17. Feb 2006 (CET)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Ein einfaches C-Programm könnte folgendermassen aussehen. Das Programm tut eigentlich nichts, aber das Beispiel zeigt den prinzipiellen Aufbau. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 int Zahl1;&lt;br /&gt;
 char Zeichen1;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int zahl2;&lt;br /&gt;
 &lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Beschreibung:'''&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndash; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
 {{comment|void-Definition von main ist nur beim Controller ueblich}}&lt;br /&gt;
 {{comment|spezielle Compilereinstellungen sind noetig, damit bei dieser Definition von main}}&lt;br /&gt;
 {{comment|kein Fehler/Warnung erzeugt wird.}}&lt;br /&gt;
 void main ()&lt;br /&gt;
 {&lt;br /&gt;
     ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
 int main (void)&lt;br /&gt;
 {  {{comment|der Block &amp;quot;main&amp;quot; beginnt}}&lt;br /&gt;
    int zahl;&lt;br /&gt;
    &lt;br /&gt;
    {   {{comment|ein Block beginnt}}&lt;br /&gt;
        {{comment|hier koennen Deklarationen und Anweisungen stehen}}&lt;br /&gt;
    }   {{comment|der Block endet}}&lt;br /&gt;
   &lt;br /&gt;
    return 0;&lt;br /&gt;
 }  {{comment|&amp;quot;main&amp;quot; endet}}&lt;br /&gt;
&lt;br /&gt;
=Datentypen=&lt;br /&gt;
==Elementare Datentypen==&lt;br /&gt;
Der Datentyp einer Variable gibt an, welche Werte eine Variable enthalten kann, welcher Art diese Daten sind und wie sie verarbeitet werden, etwa in arithmetischen Operationen wie einer Addition. So ist es zum Beispiel möglich, in eine Variable vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ganze Zahlen zwischen ca. -32000 und +32000 einzutragen. In einer char-Variable können ASCII-Zeichen gespeichert werden (alles, was Sie mit der Tastatur erzeugen können) oder ganze Zahlen von -128 bis 127.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da C plattformabhängig ist, hängt die Größe eines Datentypes zum Teil von der genutzten Hardware (z.B. 8, 16 oder 32 Bit-Controller) und dem Compiler und dessen Einstellungen ab!&lt;br /&gt;
&lt;br /&gt;
===int, char, short, long (ganze Zahlen)===&lt;br /&gt;
In Variable dieser Typen können Sie ganze Zahlen abspeichern, also z.B. 1, &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;2, 100, 12345. Jeden dieser Typen gibt es in zwei Ausprägungen: als &amp;quot;&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;quot;, also als vorzeichenbehafteten Typ, und als &amp;quot;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&amp;quot;, also ohne Vorzeichen, d.h. das Vorzeichen wird als 0 oder +1 genommen. &lt;br /&gt;
&lt;br /&gt;
Vorzeichenbehaftete Ganzzahl-Typen werden intern im &amp;lt;tt&amp;gt;n-1&amp;lt;/tt&amp;gt;-Komplement dargestellt, das Vorzeichen selbst findet sich also im höchstwertigen Bit. Werden zur Speicherung ''b'' Bits verwendet, dann reicht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;z.B. *zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==Enum==&lt;br /&gt;
&lt;br /&gt;
Über &amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt; können Aufzählungen definiert werden. Die Werte sind &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Werte und beginnen mit&amp;amp;nbsp;0. Der folgende enum hat einen um&amp;amp;nbsp;1 grösseren Wert. Mit einer Zuweisung können auch andere Werte zugeordnet werden. Klarer wird's im Beispiel:&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 enum Farben&lt;br /&gt;
 {&lt;br /&gt;
    ROT,&lt;br /&gt;
    GRUEN,&lt;br /&gt;
    BLAU,&lt;br /&gt;
    BRAUN = 5,&lt;br /&gt;
    SCHWARZ&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
Dies definiert die Konstanten &amp;lt;tt&amp;gt;ROT=0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;GRUEN=1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BLAU=2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BRAUN=5&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;SCHWARZ=6&amp;lt;/tt&amp;gt; und den Typ &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void foo (enum Farben farbe)&lt;br /&gt;
{&lt;br /&gt;
   switch (farbe)&lt;br /&gt;
   {&lt;br /&gt;
      case ROT:&lt;br /&gt;
         ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit kann man anstatt &amp;quot;magischer&amp;quot; Zahlen sprechende Namen im Code verwenden, etwa in Berechnungen und Zuweisungen, Vergleichen oder als Konstante hinter einem &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zusammengesetzte Datentypen==&lt;br /&gt;
===Arrays===&lt;br /&gt;
Oft muß man sehr viele Werte gleichzeitig abspeichern und betrachten, die alle der selben Aufgabe dienen. Man schreibt z.B. ein Programm, das 10 Zahlen einlesen und anschließend wieder ausgeben soll. Man könnte das natürlich mit 10 einzelnen Variablen bewerkstelligen, aber es ist sinnvoller, dabei Arrays &amp;amp;ndash; teilweise auch als ''Felder'' bezeichnet &amp;amp;ndash; zu verwenden.&lt;br /&gt;
&lt;br /&gt;
In einem Array werden mehrere Variablen gleichen Typs zusammengefasst und hintereinander im Speicher abgelegt. So kann man viele tausend Variablen anlegen mit nur einer Zeile Code. Doch es gibt noch größere Vorteile: Sie können das Array mit einer Schleife ganz einfach nach Werten durchsuchen. Stellen Sie sich vor, Sie müssten mit 100 verschiedenen Variablen &amp;lt;tt&amp;gt;Zahl_00&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;Zahl_99&amp;lt;/tt&amp;gt; arbeiten!&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}}&amp;amp;#91;{{Konstante}}&amp;amp;#93;;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 unsigned int werte[100];&lt;br /&gt;
&lt;br /&gt;
Der Name muß natürlich ein gültiger Bezeichner sein, als Datentyp kann jeder Typ genommen werden &amp;amp;ndash; sowohl elementare Datentypen als auch Zeiger, Strukturen, Unions oder selbst definierte Datentypen. In der eckigen Klammer wird die Anzahl der Elemente bekanntgegeben. Ein mit [3] definiertes Array hat Platz für drei Variablen. Da der Index immer bei 0 beginnt, greift man also mit &amp;lt;tt&amp;gt;[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;[1]&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;[2]&amp;lt;/tt&amp;gt; auf den jeweilige Inhalt zu. Um auf eine der im Array enthaltenen Variablen zugreifen zu können, müssen Sie den Variablennamen und in eckigen Klammern den Index (die &amp;quot;Nummer&amp;quot;) der Variablen angeben. Diese Variable verhält sich dann wie eine ganz normale Variable des jeweiligen Datentypes. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #define NZAHLEN 10&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int i;&lt;br /&gt;
    int zahlen[NZAHLEN];  {{comment|zahlen[0] ... zahlen[9]}}&lt;br /&gt;
  &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++)&lt;br /&gt;
    {&lt;br /&gt;
       printf (&amp;quot;Bitte Zahl %d eingeben: &amp;quot;, i);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; zahlen[i]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++) &lt;br /&gt;
       printf (&amp;quot;Zahl %d ist: %d\n&amp;quot;, i, zahlen[i]);&lt;br /&gt;
      &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 10 int-Variablen großes Array angelegt. &lt;br /&gt;
In dieses wird nun der Reihe nach 10 Zahlen eingelesen. &lt;br /&gt;
Anschließend werden alle 10 Zahlen ausgegeben. &lt;br /&gt;
&lt;br /&gt;
Dabei wird die Größe der Arrays und das Schleifenende über das Define &amp;quot;&amp;lt;tt&amp;gt;NZAHLEN&amp;lt;/tt&amp;gt;&amp;quot; angegeben. Dadurch muss nur ''eine Stelle'' im Code geändert werden, wenn die Größe des Arrays einmal einen anderer Wert als 10 haben soll &amp;amp;ndash; dies vermeidet Fehler die dadurch entstehen, wenn man beim Anpassen der Array-Größe eine Codestelle vergisst, zudem wird der Code lesbarer als wenn irgendwo die Zahl &amp;quot;10&amp;quot; auftaucht.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
:Wird ein ungültiger Index angeben (einer, der in der Deklaration nicht enthalten ist) können  undefinierte Dinge passieren, wenn dadurch andere Variableninhalte oder Programmcode überschrieben wird, der hinter oder vor dem Array im Speicher liegt. Schlimmstenfalls kann sogar der Computer/Controller abstürzen. Also darauf achten, daß keine ungültigen Werte als Index auftreten!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Strings (Zeichenketten)===&lt;br /&gt;
Ein String ist nichts anderes als ein Array, das aus einzelnen Zeichen (&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;) gebildet wird. Die Ausgabe auf dem Bildschirm funktioniert am einfachsten mittels Strings.&lt;br /&gt;
&lt;br /&gt;
Die Definition eines Strings erfolgt also genauso wie bei Arrays:&lt;br /&gt;
 char string[21];&lt;br /&gt;
&lt;br /&gt;
Nun haben Sie eine String, in dem Sie 21 Zeichen speichern können. Ganz richtig ist das jedoch nicht. C arbeitet mit &amp;quot;null-terminierten Strings&amp;quot;. Das beudeutet, dass die Länge des Strings nicht abgespeichert wird, sondern das Zeichen mit dem ASCII-Wert 0 das Stringende kennzeichnet. Daher auch die Bezeichnung  &amp;quot;null terminiert&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Das letzte Zeichen eines Strings muß daher immer das ASCII-Zeichen Nr. 0 sein. Ist es das nicht, hat der String kein definiertes Ende, und wenn Sie versuchen, ihn durch eine Standard-Funktion auszugeben zu lassen, könnte es eine Weile dauern, bis sich im Speicher zufällig irgendwo eine 0 befindet. Es stehen ihnen daher bei dem Beispiel nur 20 Zeichen zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
===Mehrdimensionale Arrays===&lt;br /&gt;
Manchmal benötigt man mehr als nur ein eindimensionales Array, wie Sie es bisher kennengelernt haben. Auch dies ist kein Problem. In der Deklaration geben Sie einfach mehrere eckige Klammern hintereinander an. Aber Vorsicht: der Speicherplatz ist begrenzt, ein &amp;quot;&amp;lt;tt&amp;gt;char feld[1024][1024]&amp;lt;/tt&amp;gt;&amp;quot; hat die Speicherplatzgrenzen vermutlich bereits weit überschritten, und der Compiler wird einen (bei gewissen Einstellung auch keinen) Fehler liefern.&lt;br /&gt;
Beim Zugriff auf mehrdimensionale Felder müssen auch mehrere Indizes angeben werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  int x,y;&lt;br /&gt;
  int feld[3][5];&lt;br /&gt;
 &lt;br /&gt;
  for (x=0; x&amp;lt;3; x++) &lt;br /&gt;
  {&lt;br /&gt;
     for (y=0; y&amp;lt;5; y++)&lt;br /&gt;
     {&lt;br /&gt;
       printf (&amp;quot;Feldwert x: %d,  y: %d &amp;quot;, x, y);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; feld[x][y]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  for(x=0; x&amp;lt;3; x++) &lt;br /&gt;
     for (y=0; y&amp;lt;5; y++) &lt;br /&gt;
        printf (&amp;quot;Wert: feld[%d][%d] = %d\n&amp;quot;, x, y, feld[x][y]);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 3 mal 5 &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array angelegt. &lt;br /&gt;
Dann werden die Werte eingegeben: zuerst &amp;lt;tt&amp;gt;feld[0][0]&amp;lt;/tt&amp;gt;, dann &amp;lt;tt&amp;gt;feld[0][1]&amp;lt;/tt&amp;gt;, usw. bis &amp;lt;tt&amp;gt;feld[2][4]&amp;lt;/tt&amp;gt;. &lt;br /&gt;
Zum Schluß werden alle Werte noch einmal ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===Strukturen===&lt;br /&gt;
In C können Sie sogenannte &amp;quot;Strukturen&amp;quot; definieren. Dabei handelt es sich um eine Zusammenfassung mehrerer Datentypen zu einem größeren. Im Unterschied zu Feldern können in Strukturen unterschiedliche Datentypen zusammengestellt und gespeichert werden: &lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 struct {{Bezeichner}}&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur 'Person'}}&lt;br /&gt;
 struct Person &lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;lt;tt&amp;gt;struct Person {&amp;lt;/tt&amp;gt;&amp;quot; leitet die Definition der Struktur mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;Person&amp;lt;/tt&amp;gt;&amp;quot; ein. &lt;br /&gt;
Dann werden in dieser Struktur fünf Komponenten definiert: drei Strings und zwei &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. &lt;br /&gt;
mit &amp;lt;tt&amp;gt;}&amp;lt;/tt&amp;gt; wird die Definition abgeschlossen. Sie haben damit einen Datentyp erstellt. Um eine Variable des Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach an&lt;br /&gt;
 struct Person {{Bezeichner}};&lt;br /&gt;
&lt;br /&gt;
Zum Zugriff auf eine Komponente der Struktur gibt man den Namen der Struktur-Variablen an (im folgenden Beispiel also &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;klaus&amp;lt;/tt&amp;gt;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
 {{comment|Definition zweier Struktur-Variablen}}&lt;br /&gt;
 struct Person hubert, klaus;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Zugriff auf Struktur-Komponenten}}&lt;br /&gt;
 hubert.alter = 32;&lt;br /&gt;
 klaus.alter = hubert.alter + 1;&lt;br /&gt;
&lt;br /&gt;
===Unions===&lt;br /&gt;
Eine Union wird ganz analog zu einer Struktur deklariert und verwendet. Sie unterscheidet sich von einer Struktur jedoch dadurch, daß ihre Elemente nicht nacheinander im Speicher abgelegt werden, sondern sich überlagern. Auf die in einer Union enthaltenen Daten gibt es also verschiedene Sichten: je nachdem, welche Sicht bzw. Interpretation der Daten man gerne hätte, wählt man den gewünschten Zugriff.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
union Daten &lt;br /&gt;
{&lt;br /&gt;
   int id;&lt;br /&gt;
&lt;br /&gt;
   struct Person u_person;&lt;br /&gt;
&lt;br /&gt;
   struct u_double&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      double wert;&lt;br /&gt;
   };&lt;br /&gt;
&lt;br /&gt;
   struct u_pointer&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      union Daten * p1;&lt;br /&gt;
      union Daten * p2;&lt;br /&gt;
   };&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
union Daten data;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies definiert eine Union mit den vier Zugriffsmöglichkeiten &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_double&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Größe der Union richtet sich dabei nach der grössten Komponente. In diesem Beispiel sind alle Komponenten so angelegt worden, daß sie an erster Stelle ein &amp;lt;tt&amp;gt;int id&amp;lt;/tt&amp;gt; enthalten. In &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; könnte man sich also merken, wie die Daten in der Union zu interpretieren sind. Würde &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; nicht dieses &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; enthalten, so würde sich &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; mit &amp;lt;tt&amp;gt;data.u_person.vname&amp;lt;/tt&amp;gt; überlagern. Ein Ändern der ersten Buchstaben von &amp;lt;tt&amp;gt;vname&amp;lt;/tt&amp;gt; hätte also ein Ändern von &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; zur Folge, und man könnte es nicht mehr als Merker verwenden. Mit diesem Feld überlagert das &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; die &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;-Felder der anderen Sichten, z.B. ist &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; der selbe Zugriff wie auf &amp;lt;tt&amp;gt;data.u_person.id&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein anderes Beispiel ist eine Union, die es ermöglicht, auf die einzelnen Bytes eines &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; zuzugreifen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef union&lt;br /&gt;
{&lt;br /&gt;
   unsigned long  as_long;&lt;br /&gt;
   unsignen short as_short[2];&lt;br /&gt;
   unsignen char  as_byte[4];&lt;br /&gt;
} data32_t;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies überlagert einen &amp;lt;tt&amp;gt;unsigned long&amp;lt;/tt&amp;gt; &amp;amp;ndash; also eine 32-Bit-Zahl &amp;amp;ndash; mit vier Bytes bzw. zwei Shorts.&lt;br /&gt;
 data32_t wert;&lt;br /&gt;
 &lt;br /&gt;
 wert.as_long = 0x12345678;&lt;br /&gt;
 wert.as_byte[0] = 0xab;&lt;br /&gt;
 {{comment|nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform)}}&lt;br /&gt;
&lt;br /&gt;
==Eigene Datentypen==&lt;br /&gt;
&lt;br /&gt;
=Variablen=&lt;br /&gt;
Eine Variable ist ein Synonym (=anderer Name) für eine Speicherstelle in einem Computer. Einfacher gesagt, eine Variable bietet Raum, um Daten wie Zahlen oder Zeichen zu speichern und wieder zu lesen.&lt;br /&gt;
&lt;br /&gt;
==Variablennamen==&lt;br /&gt;
Ein Variablenname kann zusammengesetzt werden aus den Buchstaben &amp;lt;tt&amp;gt;'''A'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''Z'''&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;'''a'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''z'''&amp;lt;/tt&amp;gt;, den Ziffern &amp;lt;tt&amp;gt;'''0'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''9'''&amp;lt;/tt&amp;gt;, sowie dem Sonderzeichen &amp;quot;Unterstrich&amp;quot; (underscore) &amp;lt;tt&amp;gt;'''_'''&amp;lt;/tt&amp;gt;. Dabei darf an erster Stelle keine Ziffer stehen. Die Bezeichner &amp;lt;tt&amp;gt;hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALLO&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALL0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;_123&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_HALLO&amp;lt;/tt&amp;gt; sind also alle gültige und unterschiedliche Variablennamen.&lt;br /&gt;
&lt;br /&gt;
==Anlegen von Variablen==&lt;br /&gt;
Um eine Variable verwenden zu können, muss sie zuerst vereinbart (&amp;quot;erzeugt&amp;quot;) werden. Dies wird auch als &amp;quot;''Definition der Variablen''&amp;quot; bezeichnet und geht so: Schreiben Sie zuerst den Datentyp, dann den Namen der Variablen. Zum Schluß kommt noch der Strichpunkt, wie nach jeder C-Anweisung oder Deklaration. Und nicht vergessen: C unterscheidet zwischen  Groß- und Kleinschreibung! &lt;br /&gt;
 int Zahl1, Zahl2;&lt;br /&gt;
 char Zeichen;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    float gleitZahl;&lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:'''&lt;br /&gt;
In einer Zeile können auch mehrere Variablen gleichen Types vereinbart werden, wenn man ein Komma dazwischen setzt. Variablen können in jedem Block vereinbart werden. Siehe [[#Gültigkeitsbereich|Gültigkeitsbereich]].&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen==&lt;br /&gt;
Man kann einer vereinbarten Variable Werte [[#Zuweisungen|zuweisen]]. Dazu schreibt man zuerst den Variablennamen, ein Gleichheitszeichen &amp;quot;&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;&amp;quot; und anschliessend den zuzuweisenden [[#Ausdrücke|Ausdruck]]. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, zahl2 = 12;&lt;br /&gt;
  char zeichen1 = 'A';&lt;br /&gt;
&lt;br /&gt;
  zahl1 = 52;&lt;br /&gt;
  zeichen1 = zeichen1 + 1; &lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Zuerst werden drei Variablen angelegt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;: wird gleich bei der Vereinbarung der Wert 12 zugewiesen. &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl1 = 52&amp;lt;/tt&amp;gt;: Hier wird der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; der Wert 52 zugewiesen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;: wird um 1 erhöht. Da in der Variablen &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; gespeichert ist, gibt sich ihr neuer Wert aus &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt;. Weil &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; dem Wert 65 entspricht, ist &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt; gleich 66, was dem Wert für &amp;lt;tt&amp;gt;'B'&amp;lt;/tt&amp;gt; entspricht.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei float==&lt;br /&gt;
Das funktioniert genau wie bei normale Zuweisungen. Nachkommastellen werden durch einen Punkt abgegrenzt: &lt;br /&gt;
 floatVariable = 3.14;&lt;br /&gt;
Zusätzlich kann eine Zehnerpotenz angegeben werden:&lt;br /&gt;
 floatVariable2 = -1.234E-6;&lt;br /&gt;
Dadurch wird der erst Wert mit 10&amp;lt;sup&amp;gt;&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;6&amp;lt;/sup&amp;gt; multipliziert, der Wert der Variablen ist also &lt;br /&gt;
:&amp;lt;math&amp;gt;-1{,}234\cdot10^{-6} = -0.000001234&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei logischen Variablen==&lt;br /&gt;
Wie bereits erwähnt, besitzt C keinen logischen Datentyp. Es müssen also &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; dafür genutzt werden. Die Zuweisung entpricht der Standard-Zuweisung. Wird der Wert 0 zugewiesen, dann ist die Variable &amp;quot;unwahr&amp;quot;, ansonsten ist sie &amp;quot;wahr&amp;quot;. &lt;br /&gt;
 intVariable = !0;   /* entspricht &amp;quot;wahr&amp;quot;   */&lt;br /&gt;
 intVariable = 0;    /* entspricht &amp;quot;unwahr&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
==Konstanten==&lt;br /&gt;
Konstanten können als Variable angesehen werden, die nicht beschrieben, sondern nur gelesen werden können. Ein typisches Beispiel dafür ist die Zahl &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; (rund 3,141592654). Niemand würde in der realen Welt versuchen, ihr einen anderen Wert zuzuweisen. Würde man &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; jedoch wie eine normale Variable anlegen, wäre dies ohne weiteres möglich. Um dies zu verhindern, gibt es das Schlüsselwort &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in C:&lt;br /&gt;
 const {{Type}} {{Bezeichner}} = {{Konstante}};  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Wichtig dabei ist, dass man Konstanten nur bei der Vereinbarung einen Wert zuweisen kann. &lt;br /&gt;
Da Konstanten gewöhnlich im gesamten Programm, zumindest einer Quelldatei genutzt werden, definiert man diese allerdings gewöhnlich außerhalb des main-Blockes entweder am Anfang eines Programmes, oder in einer sogenannten Header-Datei, die per &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; eingebunden wird.&lt;br /&gt;
 const float PI = 3.141592;  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Es sei jedoch erwähnt, daß auch einer Konstanten nachträglich ein anderer Wert zugewieden werden kann. Im obigen Beispiel könnte mit&lt;br /&gt;
 * ((float*) &amp;amp;PI) = 2;&lt;br /&gt;
der Wert von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; im Nachhinein verändert werden. Es wird die Adresse von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; genommen und diese Adresse durch den Cast in eine ganz normale &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;-Adresse umgewandelt, über welche der Wert geändert wird. Die sei der Vollständigkeit halber erwähnt.&lt;br /&gt;
&lt;br /&gt;
Je nachdem, an welcher Stelle sich das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; bei einer Pointer-Deklaration befindet, markiert es den Pointer als konstant oder das Objekt, auf das dieser Pointer zeigt. Eine häufige Parameterdeklaration in Ausgabe-Funktionen, die einen String erhalten, ist&lt;br /&gt;
 void foo (const char * str, ...);&lt;br /&gt;
Dadurch ist &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; der Zeiger auf eine Zeichenkette, die innerhalt der Funktion nicht verändert wird bzw. verändert werden darf. Eine Zuweisung wie &amp;lt;tt&amp;gt;*str = 'a'&amp;lt;/tt&amp;gt; ergibt also einen Fehler. &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; selbst kann aber sehr wohl verändert werden, etwa mit &amp;lt;tt&amp;gt;str++&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Soll ausgedrückt werden, daß &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; unveränderlich ist, dann so:&lt;br /&gt;
 void foo (char * const str, ...);&lt;br /&gt;
Jetzt wäre eine Änderung des Strings in Ordnung, etwa durch &amp;lt;tt&amp;gt;str[10] = 'a'&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Um sich zu merken, worauf das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; wirkt, trennt man die Deklaration in Gedanken beim&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf: Steht das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; links vom&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, dann gehört es zum &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, steht es rechts davon, dann gehört es zum Pointer. Natürlich ist es auch denkbar, beides &amp;amp;ndash; also den Zeiger und sein Ziel &amp;amp;ndash; als konstant zu markieren.&lt;br /&gt;
&lt;br /&gt;
==Gültigkeitsbereich==&lt;br /&gt;
In C können mehrere Variablen den gleichen Namen haben, solange eindeutig ist, welche in welchen Block gültig ist. Dabei gelten folgende Regeln: &lt;br /&gt;
&lt;br /&gt;
;Lokale Variablen: sind Variablen, die innerhalb eines Blockes definiert werden. Jede Variable ist nur in dem Block gültig, in dem sie vereinbart wurde, sowie in allen darin enthaltenen Blöcken; es sei denn, in einem Unter-Block wird eine Variable gleichen Namens definiert. Dann bezieht sich in diesem Unter-Block der Bezeichner auf die im Unter-Block angelegte Variable.&lt;br /&gt;
;Globale Variablen: werden ausserhalb jedes Blockes definiert und gelten ab der Stelle, an der sie deklariert werden, siehe auch [[#Deklaration und Definition|Deklaration und Definition]]. Wird jedoch in einem Block eine Variable gleichen Namens angelegt, gilt ab hier bis zum Ende des Blocks nicht mehr die globale Variable, sondern die im Block deklarierte. Das Spiel kann man weiterspielen: wird in einem Unter-Block wieder eine namensgleiche Variable angelegt, gilt diese in dem Unterblock.&lt;br /&gt;
&lt;br /&gt;
==Speicherklassen==&lt;br /&gt;
Jede Variable in C gehört zu einer bestimmten Speicherklasse&lt;br /&gt;
;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;: Lokale Variablen sind in aller Regal sogenannte ''automatische Variablen''. Das bedeutet, sie werden automatisch angelegt, wenn ein Block bzw. eine Funktion betreten wird und danach wieder entfernt. Das Schlüsselwort &amp;quot;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;&amp;quot; wird praktisch nie hingeschrieben, denn lokale Variablen ohne die ausdrückliche Angabe einer Speicherklasse, sind automatisch automatische Variablen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;: Eine externes Symbol ist im ganzen Programm bekannt bzw. in dem Block, in der die Deklaration steht. In unterschiedlichen Blöcken stehende Deklarationen beziehen sich auf das gleiche Symbol! Obgleich das Datum global zugreifbar ist, ist der Gültigkeitsbereich auf den deklarierenden Block begrenzt bzw. auf das deklarierende Quell-Modul, sofern das Symbol ausserhalb jedes Blocks des Moduls deklariert wird. Siehe auch [[#Deklaration und Definition|Deklaration und Definition]].&lt;br /&gt;
;&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;: Die Variable ist im Block gültig bzw. im Quell-Modul (also in der C-Datei, in der die angelegt wurde), wenn sie nicht innerhalb eines Blockes angelegt wurde. Statische Variablen werden nicht in Registern oder im Frame der Funktion angelegt, sondern im selben Speicherbereich, in dem auch die globalen Variablen liegen; Konstanten evtl. auch im Flash. Eine lokale Variable, die als &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; angelegt wird, &amp;quot;überlebt&amp;quot; also das Verlassen des Blocks und hat beim neuerlichen Betreten des Blockes ihren bisherigen Wert. In unterschiedlichen Blöcken angelegte lokale statische Variablen beziehen sich auf unterschiedliche Speicherstellen, genau wie bei lokalen Variablen auch.&lt;br /&gt;
;&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;: Durch diese Speicherklasse wird eine Variable &amp;amp;ndash; falls möglich &amp;amp;ndash; als Registervariable angelegt, also in einem Maschinenregister des Computer/Controllers gehalten. Dadurch kann auf solche Variablen besonders schnell zugegriffen werden. Dieses Schlüsselwort ist bei modernen Compilern weitgehend überflüssig, da die entsprechenden Optimierungen selbständig vorgenommen werden, wenn ausreichend Register vorhanden sind. Auch globale Variablen können als Register angelegt werden, davon ist dem Anfänger aber dringend abzuraten, weil leicht schwerauffindbare Fehler und Abstürze auftreten, wenn man nicht genau weiss, welche Implikationen in einer solchen Definition stecken!&lt;br /&gt;
;&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;: (FIXME: volatile ist ein Qualifier und keine Speicherklasse) Dies ist das genaue Gegenteil von &amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt; und bewirkt, dass die Variable auf keinen Fall in einem Register zwischengespeichert werden darf, sondern immer aus dem RAM gelesen und ins RAM geschrieben werden soll. &amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt; müssen alle ''globalen'' Variablen markiert werden, die in [[ISR | Interrupt-Handlern]] verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Ausdrücke=&lt;br /&gt;
Eine Variable oder eine Konstante in C stellen einfache Ausdrücke dar.&lt;br /&gt;
Diese elementaren Ausdrücke können durch Operatoren miteinander verknüpft werden und so zu neuen, komplexeren Ausdrücken zusammen gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Einfache Beispiele für Ausdrücke sind also z.B.:&lt;br /&gt;
 1&lt;br /&gt;
 a&lt;br /&gt;
 'a'&lt;br /&gt;
 1 + a&lt;br /&gt;
 a == 1&lt;br /&gt;
&lt;br /&gt;
Auch Funktionen können einen Wert zurückliefern und in Ausdrücken weiter benutzt werden.&lt;br /&gt;
In den folgenden Abschnitten wird gezeigt, welche Operatoren in C vorhanden sind,&lt;br /&gt;
und wei man damit neue Ausdrücke aufbauen kann.&lt;br /&gt;
&lt;br /&gt;
==Lvalues==&lt;br /&gt;
&lt;br /&gt;
Ein Lvalue in C ist ein Ausdruck, dem ein anderer Ausdruck zugewiesen werden kann, dessen Wert also durch eine Zuweisung verändert werden kann.&lt;br /&gt;
das 'L' leitet sich ab von 'left' bwz. 'links' und das 'value' bedeutet Wert: Ein Lvalue ist ein Ausdruck, der auf der linken Seite einer Zuweisung stehen darf. Ein Lvalue ist also immer auch ein gültiger Ausdruck, aber die Umkehrung gilt in alles Regel nicht.&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für einen Lvalue ist eine &amp;quot;normale&amp;quot; Variable, die nicht mit &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; als Konstante markiert ist:&lt;br /&gt;
 a = 1;&lt;br /&gt;
Hingegen ist der Ausdruck &amp;lt;tt&amp;gt;a+1&amp;lt;/tt&amp;gt; kein Lvalue, denn eine Zuweisung wie&lt;br /&gt;
 a+1 = 2;&lt;br /&gt;
die mathematisch durchaus sinnvoll ist, erzeugt einen Compilerfehler, der etwa lauten könnte &amp;quot;illegal lvalue in assignment&amp;quot;:&lt;br /&gt;
&amp;quot;ungültiger Wert in Zuweisung&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Andere Beipiele für Lvalues sind die Komponenten von (nicht-konstanten) [[#Strukturen|Strukturen]] und [[#Unions|Unions]], [[#Arrays|Array]]-Elemente und die Dereferenzierungen von Pointern: Die Konstante&amp;amp;nbsp;4 wird durch den Cast in eine Adresse umgewandelt. Über die Dereferenzierung&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; wird an die Adresse&amp;amp;nbsp;4 im Speicher eine&amp;amp;nbsp;3 geschrieben. Ob das erlaubt bzw. sinnvoll ist, ist abhängig von der jeweiligen Architektur.&lt;br /&gt;
 * ((unsigned int *) 4) = 3;&lt;br /&gt;
Hier ist der gesamte &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;-Ausdruck ein Lvalue&lt;br /&gt;
&lt;br /&gt;
==Logische (boolsche) Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp;amp;&amp;amp;amp; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr oder &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; || gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; || ungleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;= b&amp;lt;/tt&amp;gt; || kleiner oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt; b&amp;lt;/tt&amp;gt; || kleiner als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt;= b&amp;lt;/tt&amp;gt; || glösser oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt; b&amp;lt;/tt&amp;gt; || grösser als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; nicht wahr und vice versa&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine interessante Eigenschaft der Operatoren &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;amp;amp;&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; ist, dass&lt;br /&gt;
sie die Auswertung abbrechen, sobald das Ergebnis feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet. Ein oft anzutreffendes Codestück sieht so aus, dabei sei &amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
  if (p &amp;amp;&amp;amp; *p == 5)&lt;br /&gt;
  {&lt;br /&gt;
     {{comment|mach was}}&lt;br /&gt;
  }&lt;br /&gt;
Zuerst wird in der Bedinung geprüft, ob Zeiger&amp;amp;nbsp;&amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; einen Wert ungleich Null hat, also ob er überhaupt einen gültigen Wert enthält. Es ist weit verbreitete Konvention in C, daß Zeiger, die keinen gültigen Wert haben, die Adresse&amp;amp;nbsp;0 enthalten. '''Nur dann, wenn ein Zeiger nicht ein Null-Pointer ist, darf überhaupt ein Zugriff über ihn erfolgen!'''&lt;br /&gt;
&lt;br /&gt;
==Vergleich von Variablen==&lt;br /&gt;
Skalare Variablen (also ganze Zahlen, Gleitkommazahlen, Zeiger) können miteinander verglichen werden. Dazu gibt es die folgenden Operatoren in C: &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; || ist nicht gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;=&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;=&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das Ergebnis der Auswertung ist eine ganze Zahl. Ist die Bedingung erfüllt, dann ist der Wert ungleich&amp;amp;nbsp;0. Ist die Bedingung nicht erfüllt, dann ist ihr Wert gleich&amp;amp;nbsp;0.&lt;br /&gt;
Meistens wird man diese Operatoren in &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Konstrukten finden wie zum Beispiel&lt;br /&gt;
 if (x &amp;gt;= 10)&lt;br /&gt;
    x = 10;&lt;br /&gt;
oder in Abbruchbedingungen von Schleifen, wie sie weiter unten erklärt werden.&lt;br /&gt;
&lt;br /&gt;
Es ist auch möglich, das Ergebnis der Auswertung in einer &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Variablen zu speichern:&lt;br /&gt;
 int i;&lt;br /&gt;
 int z1, z2;&lt;br /&gt;
 &lt;br /&gt;
 z1 = 5;&lt;br /&gt;
 z2 = 100;&lt;br /&gt;
 i = z1 &amp;lt;= z2;  {{comment|Ein Vergleich. i wird &amp;quot;wahr&amp;quot;, da z1 kleinergleich z2 ist}}&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich&amp;amp;nbsp;0 (&amp;quot;wahr&amp;quot;), wenn &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; kleiner oder gleich &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt; ist. Ist &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; jedoch größer als &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt;, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich&amp;amp;nbsp;0 (&amp;quot;unwahr&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
==Arithmetische Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a + b&amp;lt;/tt&amp;gt; || Summe (Addition)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a - b&amp;lt;/tt&amp;gt; || Differenz (Subtraktion)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a * b&amp;lt;/tt&amp;gt; || Produkt (Multiplikation)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a / b&amp;lt;/tt&amp;gt; || Quotient (Division, evtl. mit Rest)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a % b&amp;lt;/tt&amp;gt; || Rest bei Division (Modulo)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;-a&amp;lt;/tt&amp;gt; || Vorzeichenumkehr (Zweierkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Bit-Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp; b&amp;lt;/tt&amp;gt; || bitweise und (and)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || bitweise oder (or)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a ^ b&amp;lt;/tt&amp;gt; || bitweise exclusiv-oder (xor, exor)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;~a&amp;lt;/tt&amp;gt; || jedes Bit in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; invertieren (not, Einerkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Index-Operator bei Arrays==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a[b]&amp;lt;/tt&amp;gt; || das (b+1)ste Element des Feldes a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Folgendes gilt es bei der Verwendung des Indexoperators zu beachten:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; muss ein [[C-Tutorial#Felder | Feld]] oder [[C-Tutorial#Zeiger | Zeiger]] sein&lt;br /&gt;
# &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; muss ein Integer sein oder ein Datentyp, der sich in einen int umwandeln läßt (z.B. char)&lt;br /&gt;
# Es wird nicht geprüft, ob der Index &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; im Feld &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gültig ist!&lt;br /&gt;
# Der erste Index eines Feldes ist immer 0. Daher ''(b+1)stes Element'' in der Beschreibung&lt;br /&gt;
&lt;br /&gt;
==Komponenten-Auswahl bei Structs und Unions==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a.b&amp;lt;/tt&amp;gt; || Element b der [[C-Tutorial#Strukturen | Struktur]] oder des Unions a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adress-Operator und Dereferenzierung==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&amp;amp;amp;a&amp;lt;/tt&amp;gt; || Speicheradresse der Variablen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;*a&amp;lt;/tt&amp;gt; || Wert, der an der Adresse &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a-&amp;amp;gt;b&amp;lt;/tt&amp;gt; || Wert des Elements &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; der Struktur, deren Adresse in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Adressoperator &amp;amp; kann auf Variablen angewendet werden und&lt;br /&gt;
gibt die Startadresse der Variablen im Speicher zurück.&lt;br /&gt;
&lt;br /&gt;
Handelt es sich bei einer Variable um einen [[C-Tutorial#Zeiger | Zeiger]], so enthält&lt;br /&gt;
sie eine Speicheradresse. Um an den '''Wert''' zu gelangen, der&lt;br /&gt;
an dieser Adresse steht, wird der Operator * vorangestellt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
&lt;br /&gt;
 {{comment|x ist eine Integervariable und hat den Wert 5}}&lt;br /&gt;
 int x = 5;&lt;br /&gt;
     &lt;br /&gt;
 {{comment|z ist ein Zeiger auf eine Integer-Variable und enthaelt somit}}&lt;br /&gt;
 {{comment|die Speicheradresse einer Integer-Variablen}}&lt;br /&gt;
 int *z;       &lt;br /&gt;
  &lt;br /&gt;
 {{comment|Verwendung des Adress-Operators: weist an z die Adresse von x zu}}&lt;br /&gt;
 z = &amp;amp;x;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Verwendung der Dereferenzierung}}&lt;br /&gt;
 {{comment|erhoehe den Wert, der bei Adresse z steht, um eins}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|da z auf x zeigt, hat x jetzt den Wert 6}}&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff auf Struktir- und Union-Elemente eine abkürzende Schreibweise möglich:&lt;br /&gt;
&lt;br /&gt;
Statt &lt;br /&gt;
  (*strukturZeiger).element&lt;br /&gt;
kann geschrieben werden&lt;br /&gt;
  strukturZeiger-&amp;gt;element&lt;br /&gt;
Beide Schreibweisen sind absolut gleichbedeutend, die Klammern bei der ersteren sind notwendig.&lt;br /&gt;
&lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
:Bei der Dereferenzierung durch &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; findet keine Prüfung statt, ob der Zeiger auch auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu einer Änderung '''irgendeiner''' Speicherstelle!&lt;br /&gt;
&lt;br /&gt;
 int *z; {{comment|z ist ein Zeiger auf einen int}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.}}&lt;br /&gt;
 {{comment|z enthaelt irgendeine ungueltige Adresse!!}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|&amp;quot;Erhoehe einen Integer _irgendwo_ im Speicher um 1&amp;quot; -&amp;gt; CRASH !!!}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
&lt;br /&gt;
==Cast-Operator==&lt;br /&gt;
&lt;br /&gt;
Der Cast Operator dient dazu, den Datentyp eines Wertes zu ändern. Dafür wird einfach der neue Datentyp in Klammern vor den Wert geschrieben.&lt;br /&gt;
&lt;br /&gt;
Um zum Beispiel aus einem Float ein Integer zu machen:&lt;br /&gt;
 var  = (int) 5.60;&lt;br /&gt;
Dabei wird der Wert aber auch gerundet, und es findet somit ein Informationsverlust statt.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Umwandeln einer ganzen Zahl in eine Adresse:&lt;br /&gt;
 int * addr;&lt;br /&gt;
 addr = (int*) 0x1234;&lt;br /&gt;
Damit ist &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; an Adresse 0x1234.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
Der Cast-Operator selbst führt ''keine Konvertierung'' von Darstellungen durch, etwa die Umwandlung der ganzen Zahl 123 ein den String &amp;lt;tt&amp;gt;&amp;quot;123&amp;quot;&amp;lt;/tt&amp;gt;, der diese Zahl darstellt! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
  int main(int argc, char ** argv)&lt;br /&gt;
  {&lt;br /&gt;
        char text[] = &amp;quot;5.6&amp;quot;;&lt;br /&gt;
        int zahl = (int) text;&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, zahl);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Anfangsadresse des Strings &amp;lt;tt&amp;gt;&amp;quot;5.6&amp;quot;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Komma-Operator==&lt;br /&gt;
Mit einem &amp;lt;tt&amp;gt;,&amp;lt;/tt&amp;gt; können mehrere Ausdrücke nacheinander ausgewertet werden.&lt;br /&gt;
Die Auswertung erfolgt von links nach rechts.&lt;br /&gt;
&lt;br /&gt;
Solche Konstrukte sieht man manchmal in Abfragen wie&lt;br /&gt;
 FILE  *file;&lt;br /&gt;
 if (file = fopen (&amp;quot;foo.exe&amp;quot;, &amp;quot;r&amp;quot;), file != NULL)&lt;br /&gt;
was erst an &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; einen Wert zuweist und den &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Block nur betritt,&lt;br /&gt;
wenn &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; nicht der Nullpointer ist.&lt;br /&gt;
&lt;br /&gt;
Bequem kann das auch in einer [[#for-Schleife|for-Schleife]] sein, wenn man zwei (oder mehr) Laufvariablen hat oder so:&lt;br /&gt;
 for (i=0, j=0; i &amp;lt; 10; i++, j += 2)&lt;br /&gt;
    &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Zuweisung===&lt;br /&gt;
=== ++ und -- ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; stellen einfachere Schreibweisen dar zum Addieren bzw. Subtrahieren von&amp;amp;nbsp;1.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; (Inkrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo++; &lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo + 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; 3}}&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; (Dekrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo--;&lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo - 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; -1}}&lt;br /&gt;
&lt;br /&gt;
Die beiden Operatoren können sowohl in der Präfix-Schreibweise (vor der Variablen) als auch als Postfix-Schreibweise (hinter der Variablen) notiert werden. &lt;br /&gt;
Der Unterschied liegt darin, dass beim Präfix der Wert zuerst neu berechnet wird und die Variable dann verwendet wird. Beim Postfix wird die Variable zuerst verwendet und erst nach Auswertung des Ausdrucks, in dem sie enthalten ist, neu berechnet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 int ausgabe1, ausgabe2, var1 = 10, var2 = 10;&lt;br /&gt;
 ausgabe1 = 3 * ++var1; {{comment|ausgabe1 &amp;amp;#61; 33; var1 &amp;amp;#61; 11;}}&lt;br /&gt;
 ausgabe2 = 3 * var2++; {{comment|ausgabe2 &amp;amp;#61; 30; var2 &amp;amp;#61; 11;}}&lt;br /&gt;
&lt;br /&gt;
Für Zeiger arbeiten diese Operatoren etwas anders, siehe dazu [[#Zeiger-Arithmetik|Zeiger-Arithmetik]].&lt;br /&gt;
&lt;br /&gt;
===Bedingter Ausdruck===&lt;br /&gt;
 ({{Bedingung}}) ? {{Ausdruck|1}} : {{Ausdruck|2}}&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; erfüllt ist, dann wertet dieser Ausdruck aus zu &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt;. Ist er nicht erfüllt, dann wertet er aus zu &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 x = (x &amp;gt;= 3) ? 0 : x+1;&lt;br /&gt;
Startet man &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; mit dem Wert 0, dann nimmt es bei mehrfacher Anwendung dieser Zeile (z.B. in einer Schleife) nacheinander die folgende Werte an:&lt;br /&gt;
:&amp;lt;tt&amp;gt;1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, ...&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Priorität ||Operator||Assoziativität&lt;br /&gt;
|-&lt;br /&gt;
  &lt;br /&gt;
|&amp;lt;tt&amp;gt;15&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ( ) [ ] -&amp;gt; . &amp;lt;/tt&amp;gt;                      ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;14&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ! ~ ++ -- + - (TYP) * &amp;amp; sizeof &amp;lt;/tt&amp;gt;    ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;13&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; * / % (Rechenoperationen) &amp;lt;/tt&amp;gt;         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;12&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; + - (binär) &amp;lt;/tt&amp;gt;                       ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;11&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;&amp;lt; &amp;gt;&amp;gt; &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;10&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt; &amp;lt;= &amp;gt; &amp;gt;= &amp;lt;/tt&amp;gt;                         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 9&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; == != &amp;lt;/tt&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 8&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp; (AND-Operator)&amp;lt;/tt&amp;gt;                   ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 7&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ^ (XOR-Operator)&amp;lt;/tt&amp;gt;                   ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 6&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; (OR-Operator)&amp;lt;/tt&amp;gt;   ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 5&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;amp;&amp;amp; &amp;lt;/tt&amp;gt;                                ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 4&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; &amp;lt;/tt&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 3&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; ?: &amp;lt;/tt&amp;gt;                                ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 2&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; = += -= /= *= %= &amp;gt;&amp;gt;= &amp;lt;&amp;lt;= &amp;amp;= |= ^= &amp;lt;/tt&amp;gt; ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 1&amp;lt;/tt&amp;gt; ||&amp;lt;tt&amp;gt; , (Sequenz-Operator) &amp;lt;/tt&amp;gt;              ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
Eine Kontrollanweisung ist eine Anweisung, die Einfluss auf den Programmfluss hat. Normalerweise werden Anweisungen so ausgeführt, wie sie in der Quelldatei stehen: Von links nach rechts (falls mehrere Anweisungen in einer Zeile stehen sollten, wovon i.A. abzuraten ist) und von oben nach unten. Mit einer Kontrollanweisung kann dieser lineare Programmfluss durchbrochen werden: Die Codeausführung kann kann abhängig von einer Bedingung gemacht werden (&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;), kann wiederholt werden (Schleife) oder an einer anderen Stelle der Funktion fortgesetzt werden (&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==if-Anweisung==&lt;br /&gt;
Mit Hilfe des if-Befehls kann man Codeteile abhängig davon einer Bedingung ausführen lassen:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
oder mit else-Teil&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 if (x &amp;gt; 100)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;gt; 100 ist: Fehlerausgabe}}&lt;br /&gt;
    printf (&amp;quot;x = %d ist zu gross fuer die Berechnung!\n&amp;quot;, x);&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;lt;&amp;amp;#61; 100 ist: Berechne Summe der Zahlen 1...x}}&lt;br /&gt;
    {{comment|Die lokale Variable x2 lebt nur innerhalb dieses alse-Blocks}}&lt;br /&gt;
    int x2 = x;&lt;br /&gt;
 &lt;br /&gt;
    for (x = 0; x2 &amp;gt; 0; x2--)&lt;br /&gt;
       x += x2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Wenn die Bedingung wahr ist (&amp;lt;tt&amp;gt;x &amp;gt; 100&amp;lt;/tt&amp;gt;), dann wird eine Meldung ausgegeben; danach ist die if-Anweisung beendet. Der else-Block wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung nicht erfüllt (&amp;lt;tt&amp;gt;x &amp;amp;le; 100&amp;lt;/tt&amp;gt;), dann wird gleich zum else-Teil gesprungen, und nach dessen Ausführung der if-Befehl beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Ein häufiger Fehler ist es, statt &amp;lt;tt&amp;gt;if (a &amp;amp;#61;&amp;amp;#61; 23)&amp;lt;/tt&amp;gt; etwas wie &amp;lt;tt&amp;gt;if (a &amp;amp;#61; 23)&amp;lt;/tt&amp;gt; zu schreiben. &lt;br /&gt;
Dann wird allerdings nicht geprüft, ob die Variable&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gleich 23 ist, sondern der Variablen&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wird der Wert 23 zugewiesen. Der Ausdruck &amp;lt;tt&amp;gt;a &amp;amp;#61; 23&amp;lt;/tt&amp;gt; hat den Wert&amp;amp;nbsp;23 und ist damit immer &amp;quot;wahr&amp;quot;! Daher ist diese if-Bedingung immer erfüllt!&lt;br /&gt;
&lt;br /&gt;
Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken sondern bestenfalls eine Warnung. Damit ist dieser Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise &amp;lt;tt&amp;gt;if (23 &amp;amp;#61;&amp;amp;#61; a)&amp;lt;/tt&amp;gt;. Wenn man dort anstatt des Vergleichsoperators '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;amp;#61;&amp;lt;/tt&amp;gt;' den Zuweisungsoperator '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;lt;/tt&amp;gt;' verwendet, spuckt der Compiler sehr wohl einen Fehler aus! Ist die Zuweisung jedoch erwünscht und eine Compiler-Warnung lästig, dann wählt man eine Schreibweise wie &amp;lt;tt&amp;gt;if ((a &amp;amp;#61; b))&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;if (a &amp;amp;#61; b, a)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist zu schreiben &amp;lt;tt&amp;gt;if (Bedingung);&amp;lt;/tt&amp;gt; Richtig muss es heissen &amp;quot;&amp;lt;tt&amp;gt;if(Bedingung)&amp;lt;/tt&amp;gt;&amp;quot; Das Semikolon im ersten Fall ist eine leere Anweisung, die im if-Falle ausgeführt wird &amp;amp;ndash; sie bleibt also ohne Resultet. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt; ein auf das Semikolon folgende Anweisung die eigentlich zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören soll wird immer ausgeführt, die sie nicht mehr zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; dazu gehört.&lt;br /&gt;
}}&lt;br /&gt;
Bei verschachtelten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Konstrukten gehört ein &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zu letzten &amp;quot;freien&amp;quot; &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;. Soll in einer &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Folge das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zum ersten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören, dann ist das so zu hinzuschreiben:&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Ohne die geschweiften Klammern um das zweite &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehörte das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; dort hinzu.&lt;br /&gt;
&lt;br /&gt;
==switch-Anweisung==&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
&lt;br /&gt;
 switch ({{Ausdruck|}}) &lt;br /&gt;
 {&lt;br /&gt;
     case konstante1:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
    &lt;br /&gt;
     case konstante2:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 &lt;br /&gt;
     {{comment|weitere case-Marken}}&lt;br /&gt;
 &lt;br /&gt;
     default:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 } {{comment|Ende von switch}} &lt;br /&gt;
&lt;br /&gt;
Der Ausdruck muss ein skalarer Typ sein, er wird in die nächste ganze Zahl gewandelt und mit den Werten hinter den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Marken verglichen. Bei einer Übereinstimmung werden alle Befehle ab dem zutreffenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; ausgeführt. Stimmt der Ausdruck mit keinem der Werte überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt falls vorhanden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der nachfolgenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;- und des &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitts werden ausgeführt, wenn die Anweisungen des &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitts nicht mit dem Befehl &amp;lt;tt&amp;gt;break;&amp;lt;/tt&amp;gt; beendet werden!&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es dürfen beliebig viele &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitte angegeben werden, pro Vergleichswert jedoch nur einer.&lt;br /&gt;
Der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ist optional. Die Reihenfolge, in der &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt; angegeben werden, ist unerheblich.&lt;br /&gt;
&lt;br /&gt;
==Schleifen==&lt;br /&gt;
Um Anweisungen mehrmals hintereinander auszuführen, benötigt man Schleifen. Diese führen Anweisungen aus, bis oder solange Bedingungen erfüllt sind.&amp;lt;br&amp;gt; &lt;br /&gt;
Wichtig ist also, ob die Bedingung '''vor''' oder '''nach''' den Schleifen-Anweisungen geprüft wird. &lt;br /&gt;
&lt;br /&gt;
===while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 while ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Die while-Schleife wird solange durchlaufen, wie die Bedingung erfüllt ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Die Anweisung kann natürlich auch ein Block sein, der aus mehreren Deklarationen und Anweisungen besteht. &lt;br /&gt;
&lt;br /&gt;
 int zahl1 = 0;&lt;br /&gt;
 int zahl2 = 1;&lt;br /&gt;
 &lt;br /&gt;
 while (zahl1 &amp;lt; 3)&lt;br /&gt;
 {&lt;br /&gt;
    zahl1 = zahl1 + 1;&lt;br /&gt;
    zahl2 = zahl2 * 2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife drei mal durchlaufen. Zu Beginn des vierten Durchlaufs ist die Bedingung nicht mehr erfüllt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
&lt;br /&gt;
===do-while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
Die do-while-Schleife wird auf jeden Fall einmal durchlaufen und dann solange wiederholt, wie die Bedingung erfüllt ist.&lt;br /&gt;
 int i = 2;&lt;br /&gt;
 &lt;br /&gt;
 do &lt;br /&gt;
 {&lt;br /&gt;
     i = i*i;   {{comment|i quadrieren}}&lt;br /&gt;
     printf (&amp;quot;i = %d\n&amp;quot;, i);&lt;br /&gt;
 }&lt;br /&gt;
 while (i &amp;lt; 20);&lt;br /&gt;
&lt;br /&gt;
Die Schleife wird durchlaufen und wiederholt, solange &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; kleiner als 20 ist. Es werden also nacheinander die Werte 2, 4 und 16 ausgegeben. Nach der Schleife hat&amp;amp;nbsp;&amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; den Wert 256.&lt;br /&gt;
&lt;br /&gt;
===for-Schleife===&lt;br /&gt;
'''Syntax:''' &lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Bei den Ausdrücken wird es sich um einen Ausdrücke mit Nebeneffekt handeln wie etwa &amp;lt;tt&amp;gt;i=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;i=i+2&amp;lt;/tt&amp;gt;. Es werden folgende Aktionen ausgeführt:&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# falls die Bedingung wahr ist, dann führe &amp;lt;tt&amp;gt;Anweisung&amp;lt;/tt&amp;gt; aus.&lt;br /&gt;
# falls die Bedingung unwahr ist, dann sprinte zu 7 (Ende).&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# gehe zu 2&lt;br /&gt;
# nächste Anweisung nach der for-Schleife&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int lauf, summe;&lt;br /&gt;
 &lt;br /&gt;
 for (lauf=1, summe=0; lauf &amp;lt;= 10; lauf += 2) &lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel ist &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; ein [[#Komma-Operator|Komma-Ausdruck]], der zwei Anweisungen kombiniert und daher sogar zwei Nebeneffente hat: er setzt &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;1 und &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;0.&lt;br /&gt;
&lt;br /&gt;
Das Äquivalent als while-Schleife:&lt;br /&gt;
&lt;br /&gt;
 int lauf  = 1;                 {{comment|Anfangswerte}}&lt;br /&gt;
 int summe = 0;&lt;br /&gt;
 &lt;br /&gt;
 while (lauf &amp;lt;= 10)             {{comment|Bedingung}}&lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
    lauf  += 2;                 {{comment|Inkrement}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; in jedem Schleifendurchlauf um die Laufvariable &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; erhöht. Da &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nacheinander die ungeraden Werte von&amp;amp;nbsp;1 bis&amp;amp;nbsp;10 annimmt, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von&amp;amp;nbsp;1 bis kleinergleich 10 gespeichert, also der Wert&amp;amp;nbsp;25. &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; hat nach der Schleife den Wert&amp;amp;nbsp;11.&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf = 1&amp;lt;/tt&amp;gt; bedeutet, dass der Variablen &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; vor dem ersten Schleifendurchlauf der Wert&amp;amp;nbsp;1 zugewiesen wird. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf &amp;lt;= 10&amp;lt;/tt&amp;gt; ist die Schleifenbedingung; ist sie nicht erfüllt, wird die Schleife beendet. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf += 2&amp;lt;/tt&amp;gt; bedeutet, dass &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nach jedem Durchlauf um&amp;amp;nbsp;2 erhöht wird.&lt;br /&gt;
&lt;br /&gt;
===continue-Anweisung===&lt;br /&gt;
Innerhalb einer Schleife darf die &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die nachfolgenden Anweisungen übersprungen werden und mit dem nächsten Schleifendurchlauf fortgesetzt wird &amp;amp;ndash; vorausgesetzt die Schleifenbedingung ist noch erfüllt. Ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; etc. stehen, wenn dieses innerhalb einer Schleife steht.&lt;br /&gt;
&lt;br /&gt;
==break-Anweisung==&lt;br /&gt;
Innerhalb einer Schleife oder eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; darf die &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die Schleifen-/Switch-Anweisung sofort verlassen wird und das Programm dahinter weiter macht. Bei mehrfach geschachtelten Schleifen wird nur die innere verlassen. Ein &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; stehen, wenn dieses innerhalb einer Schleife/Switch-Anweisung steht.&lt;br /&gt;
&lt;br /&gt;
==goto-Anweisung==&lt;br /&gt;
&lt;br /&gt;
Innerhalb ein und derselben Funktion kann mit &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; an eine andere Stelle gesprungen werden. Dazu gibt man hinter dem &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einen Bezeichner an, der dadurch als Label fungiert:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 goto {{Bezeichner}};&lt;br /&gt;
Die Bezeichner selbst steht irgendwo in der Funktion und wird dadurch zur Sprungmarke (Label), daß er von einem Doppelpunkt (und mindestens einer C-Anweisung, die auch leer sein darf) gefolgt wird.&lt;br /&gt;
&lt;br /&gt;
Das Beispiel durchsucht das 2-dimensionale &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array &amp;lt;tt&amp;gt;feld&amp;lt;/tt&amp;gt; mit den &amp;lt;tt&amp;gt;SIZE_X &amp;amp;times; SIZE_Y&amp;lt;/tt&amp;gt; Werten nach dem Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;. Wird er gefunden, dann wird die 2-fach geschachtelte Suchschleife verlassen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int x, y;&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y; y++)&lt;br /&gt;
       if (feld[x][y] == 0)&lt;br /&gt;
          goto done;&lt;br /&gt;
 {{Label|done:}};&lt;br /&gt;
&lt;br /&gt;
Der folgende Code hat die gleiche Funktion, arbeitet jedoch ohne &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int x, y;&lt;br /&gt;
 int found = 0; {{comment|FALSE}}&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X &amp;amp;&amp;amp; !found; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y &amp;amp;&amp;amp; !found; y++)&lt;br /&gt;
       found = (0 == feld[x][y]);&lt;br /&gt;
Der Nachteil der &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-losen Variante ist, daß man eine Variable, die merkt, ob das Suchziel gefunden wurde, mitschleppen und in ''jedem'' Schleifendurchlauf abtesten muss. Dies bedeutet einen höheren Programmier- und Laufzeitaufwand und ist nicht so klar formuliert wie das &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-Beispiel.&lt;br /&gt;
&lt;br /&gt;
Gleichwohl sei angemerkt, daß die Verwendung von &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einem gewissen Dogmatismus unterliegt, der sich wie folgt subsummieren liesse:&lt;br /&gt;
:''goto ist böse und sollte keinesfalls verwendet werden! Wer es dennoch tut, offenbart dadurch seinen schlechten Geschmach sowie mangelhafte C-Kenntnis.'' &amp;lt;div align=&amp;quot;right&amp;quot;&amp;gt;http://www.roboternetz.de/phpBB2/images/smiles/icon_wink.gif&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Funktionen=&lt;br /&gt;
Stellen Dir vor, Du hast eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben &amp;amp;ndash; was Dich Zeit beim Erstellen des Programms und Speicherplatz im ausführbaren Programm kostet &amp;amp;ndash; kannst Du den Code-Abschnitt in eine Funktion schreiben und diese von jeder Stelle des Programms aus verwenden. Die Hauptgründe, um Funktionen zu verwenden, sind:&lt;br /&gt;
;Wiederverwendung von Code: Mehrfach verwendete Codestücke müssen nicht mehrfach implementiert werden. Oft unterscheiden sich die Codesequenzen nur in Kleinigkeiten, die man der Funktion über Parameter mitteilen kann.&lt;br /&gt;
;Übersichtlichkeit: Ein gut gegliedertes C-Programm implementiert klar umrissene Aufgaben in einer Funktion, auch wenn diese Funktion nur einmal im Code aufgerufen wird! Dadurch bleibt der Code um die Aufrufstelle besser verständlich, und man kann auf verschiedenen &amp;quot;Ebenen&amp;quot; denken. Eine Funktion wie &amp;quot;Datei öffnen&amp;quot; kann recht komplex sein. Auf höherer Ebene interessieren die Innereien nicht mehr, man möchte sich um andere Dinge kümmern und will den Code an der Stelle garnicht sehen...&lt;br /&gt;
;Rekursive Funktionen: Eine Funktion kann sich auch selbst aufrufen. In dem Falle nennt man die Funktion ''rekursiv''. Zwar lässt sich das, was eine rekursive Funktion tut, auch mit anderen Mitteln formulieren, die keine rekursiven Funktionen brauchen, aber oft ist der rekursive Weg knackiger und klarer formulierbar als eine nicht-rekursiven Ansatz, auch wenn es etwas mehr Resourcen verbraucht.&lt;br /&gt;
;Modulare Programmierung: Funktionen können anhand ihres Aufgabenbereichs auf verschiedene C-Quellen &amp;amp;ndash; sogenannte ''Module'' &amp;amp;ndash; verteilt werden. Funktionen, die etwas mit dem USB-Bus anstellen, werden in einem anderen Modul sein als mathematische Funktionen. Dies erhöht die Übersichtlichkeit und vereinfacht die Entwicklung im Team.&lt;br /&gt;
;Bibliotheken: Standard-Funktionen wie das hier oft auftauchende &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; sind in Bibliotheken gespeichert. Wenn das eigene Programm übersetzt wird, dann müssen nicht mehr alle Standard-Funktionen übersetzt werden, sondern werden nur noch aus der Bibliothek gelesen und ihr Code zum Programm dazugelinkt. Die Bibliotheks-Funktionen wurden schon zu einem früheren Zeitpunkt compiliert und liegen in dieser compilerten Form in der Bibliothek. Das spart mächtig Entwicklungszeit. Man kann auch selbst solche Bibliotheken erstellen und in diversen Projekten wiederverwenden.&lt;br /&gt;
;Generische Programmierung: In C ist es möglich, einer Funktion eine andere Funktion zu übergeben. (Damit ist nicht gemeint, ihr deren ''Rückgabewert'' zu übergeben (was auch ginge), sondern ''die Funktion selbst'' wird als Parameter übergeben und kann aufgerufen werden.) Ein typisches Beispiel dafür sind Sortieralgorithmen. Einem Sortieralgorithmus kann es egal sein, ''was'' er sortiert. Er muss lediglich wissen, ''wie'' er das Zeug zu sortieren hat: aufsteigend, absteigend, als Zahl, in lexikographischer Ordnung, nach der Quersumme, Körper nach Oberfläche, Durchmesser, Gewicht oder Volumen... Diese Vergleichsfunktion, die für zwei Objekte entscheidet, welches davon &amp;quot;kleiner&amp;quot; ist, kann man dem Sortierer übergeben. Will er zwei Werte vergleichen, dann muss er nur die Vergleichsfunktion aufrufen, ohne zu wissen, was diese tut. Damit kann der Sortieralgorithmus unanhängig von den Objekten gehalten werden, mit denen er hantieren soll.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Definition==&lt;br /&gt;
&lt;br /&gt;
In der ''Definition'' der Funktion wird gesagt, welche Werte sie liefern kann, wie sie heisst (Bezeichner) und wieviele und welche Parameter sie hat. Danach folgt ihre Implementierung:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}} ({{Parameterliste}})&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 &lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
Für Funktionen, die keinen Wert zurückliefern, gibt es den speziellen Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der besagt, daß die Funktion nichts zurückgibt. Die einfachste denkbare Funktion ist eine solch void-Funktion. Sie bekommt keine Parameter, gibt nicht zurück und ihr Body ist leer:&lt;br /&gt;
 void dummy()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==return-Anweisung==&lt;br /&gt;
An jeder Stelle des Programmflusses einer Funktion kann diese mit &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; beendet werden.&lt;br /&gt;
&lt;br /&gt;
'''bei void-Funktionen:'''&lt;br /&gt;
 return;&lt;br /&gt;
'''Funktionen mit Rückgabe-Wert:'''&lt;br /&gt;
 return {{Ausdruck|}};&lt;br /&gt;
Die zweite Variante gibt an, welcher Wert zurückgegeben wird.&lt;br /&gt;
 int main (int argc, char * argv[])&lt;br /&gt;
 {&lt;br /&gt;
    if (argc &amp;lt; 2)&lt;br /&gt;
       return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
Falls die letzte Anweisung einer void-Funktion ein &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; ist, kann es auch weggelassen werden wie oben bei der Funktion &amp;lt;tt&amp;gt;dummy&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Aufruf==&lt;br /&gt;
Um die Funktion aufzurufen gibt man ihren Namen an, gefolgt von den durch Komma getrennten Argumenten in runden Klammern wie im Beispiel unten das&lt;br /&gt;
 quadrat (5) &lt;br /&gt;
Da &amp;lt;tt&amp;gt;quadrat&amp;lt;/tt&amp;gt; einen Wert liefert, kann man damit weiter rechnen wie mit einem normalen Ausdruck:&lt;br /&gt;
 if (quadrat (a) + quadrat (b) == quadrat (c))&lt;br /&gt;
    c = quadrat (quadrat (a)); {{comment|c &amp;amp;#61; a hoch 4}}&lt;br /&gt;
&lt;br /&gt;
==Rekursive Funktionen==&lt;br /&gt;
Eine Funktion die sich selbst &amp;amp;ndash; möglicheweise auch über andere Zwischenfunktionen &amp;amp;ndash; wieder selbst aufruft, wird als ''rekursive Funktion'' bezeichnet. In der Definition ist nichts besonderes zu beachten. Ist die Verschachtelungstiefe im laufenden Programm zu tief, dann gibt das natürlich Probleme, aber das gilt bei tief verschachtelten 'normalen' Funktionen abenso...&lt;br /&gt;
&lt;br /&gt;
Das Beispiel berechnet den Größten Gemeinsamen Teiler zweier Zahlen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int ggT (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
     if (0 == a)&lt;br /&gt;
        return b;&lt;br /&gt;
 &lt;br /&gt;
    return ggT (b % a, a);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Ein komplettes kleines Programm:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int quadrat (int param1)&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  zahl = param1 * param1;&lt;br /&gt;
  return zahl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl, ergebnis;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Bitte Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = quadrat (zahl);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, zahl, ergebnis);&lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, 5, quadrat (5));&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur ausserhalb von Blöcken. Geschachtelte Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen beim Aufruf die Klammern angeben werden:&lt;br /&gt;
 dummy();&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Prototypen==&lt;br /&gt;
Wie oben erwähnt, kann ein Unterprogramm an jeder beliebigen Stelle im Programm stehen. Damit ist jedoch eine Bedingung verknüpft: Das Unterprogramm muß in der Datei oberhalb des ersten Aufrufes definiert worden sein. Wenn Sie ein Unterprogramm in Zeile 10 zum ersten mal aufrufen, müssen Sie die Deklaration davor erledigt haben. Verstanden?&lt;br /&gt;
Um dies zu erreichen, gibt es zwei Möglichkeiten: &lt;br /&gt;
&lt;br /&gt;
Entweder Sie schreiben alle Unterprogramme vor &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; in die Datei. Dies muß jedoch wiederum so geschehen, dass Funktionen zum Zeitpunkt ihres Aufrufes bereits bekannt sind! &lt;br /&gt;
Wo dies nicht möglich ist (z.B. sich gegenseitig aufrufende Unterprogramme), oder wenn Sie das stört, müssen Sie Prototypen verwenden. &lt;br /&gt;
Wie definiert man nun Prototypen? Sie kopieren einfach die erste Zeile des Unterprogrammes (z.B. &amp;quot;&amp;lt;tt&amp;gt;void ausgeben (int zahl)&amp;lt;/tt&amp;gt;&amp;quot;), fügen einen Strichpunkt&amp;amp;nbsp;&amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;an und fügen es an einer geeigneten Stelle ein (so, dass alle Aufrufe später in der Datei kommen). &lt;br /&gt;
Solche Definitionen stehen gewöhnlich am Anfang der Quelldatei oder in einer Header-Datei, die eingebunden wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl);  /* Der Prototyp */&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
   ausgeben (12);&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl)   /* Die eigentliche Prozedur */&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Ausgabe: %d\n&amp;quot;, zahl);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Parameterübergabe==&lt;br /&gt;
&lt;br /&gt;
Alle Werte, die an Prozeduren und Funktionen übergeben werden, werden grundsätzlich '''kopiert'''.&lt;br /&gt;
Das hat folgende Auswirkungen:&lt;br /&gt;
&lt;br /&gt;
# Änderungen an einem Parameter in einer Funktion erscheinen ''nicht'' beim Aufrufer!&lt;br /&gt;
# Möchte man, dass eine Funktion einen Wert trotzdem dauerhaft ändern soll, so muss die Adresse des Wertes via [[#Zeiger|Zeiger]] übergeben werden.&lt;br /&gt;
# Werden [[#Strukturen|Strukturen]] übergeben, so wird von ihnen eine Kopie erstellt, was bei großen Strukturen viel Zeit und Arbeitsspeicher kostet. Deshalb wird häufig nur die Adresse von Strukturen übergeben, da die Adresse viel schneller und platzsparender als die Struktur selbst kopiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele:'''&lt;br /&gt;
 void erhoehe (int x)&lt;br /&gt;
 {&lt;br /&gt;
    x = x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe(a);&lt;br /&gt;
    {{comment|a ist immer noch 0}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Beim Aufruf von &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; wird eine Kopie des Wertes von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; (im Beispiel also 0) erstellt und der Prozedur als Parameter &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; übergeben. Weil dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat dies keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|erhoehe den Wert an der Adresse x um eins}}&lt;br /&gt;
    *x = *x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe (&amp;amp;a);&lt;br /&gt;
    {{comment|a ist jetzt 1}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Jetzt wird im Hauptprogramm mittels [[#Adress-Operator und Dereferenzierung|Adress-Operator]] &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; die Speicheradresse von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; bestimmt. Dann wird eine ''Kopie der Adresse'' an das Unterprogramm &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; übergeben. Jetzt kennt das Unterprogramm die&lt;br /&gt;
Adresse des Originals &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und kann direkt mit dem Inhalts-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&lt;br /&gt;
'''Besonderheit bei Feldern'''&lt;br /&gt;
&lt;br /&gt;
Bei der Übergabe von [[#Felder|Feldern]] gibt es eine Besonderheit. Schreibt man nämlich den Namen eines Feldes, so ist das nichts anderes als die '''Speicheradresse des ersten Elements'''.&lt;br /&gt;
Bei der Übergabe eines Feldes wird also eine Kopie der Startadresse übergeben. Somit kann das Unterprogramm auf den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 void erhoehe (int x[])&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
   int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
   erhoehe (a);&lt;br /&gt;
   {{comment|a hat jetzt folgenden Inhalte: 11, 23, 35}}&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Dass die Übergabe einer Adresse erfolgt, sieht man an folgendem Beispiel, das von der Funktionsweise '''absolut identisch''' mit dem vorhergehenden ist:&lt;br /&gt;
&lt;br /&gt;
 {{comment|Bei Parametern gibt es keinen Unterschied zwischen Zeiger und Feld}}&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
    int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
    erhoehe (a);&lt;br /&gt;
 &lt;br /&gt;
    {{comment|a hat jetzt folgenden Inhalt: 11, 23, 35}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
Die Länge des Feldes wird nicht automatisch übergeben. Dafür ist ggf. ein zusätzlicher Parameter notwendig.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Variable Argumentanzahl==&lt;br /&gt;
== Funktionen indirekt aufrufen ==&lt;br /&gt;
Siehe [[#Zeiger auf Funktionen|Zeiger auf Funktionen]]&lt;br /&gt;
&lt;br /&gt;
=Zeiger II=&lt;br /&gt;
&lt;br /&gt;
Zeiger haben wir bereits weiter oben kennen gelernt. Zeiger sind ein zentrales Konzept in C und sollen hier etwas eingehender behandelt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger-Arithmetik==&lt;br /&gt;
In C kann man den Wert eines Zeigers verändern. Betrachten wir dazu die Funktion &amp;lt;tt&amp;gt;suche_0&amp;lt;/tt&amp;gt;, die einen Zeiger auf einen &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; erhält. Die Funktion soll ab der gegebenen Adresse nach dem ersten long-Wert suchen, der 0 ist, und dessen Adresse zurückgeben:&lt;br /&gt;
 long * suche_0 (long * addr)&lt;br /&gt;
 {&lt;br /&gt;
    while (*addr != 0)&lt;br /&gt;
       addr = addr + 1;&lt;br /&gt;
 &lt;br /&gt;
    return addr;&lt;br /&gt;
 }&lt;br /&gt;
In der Bedingung der while-Schleife wird der Inhalt an der Speicherstelle &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf 0 getestet. Ist der Wert 0, dann wird die Schleife beendet und die Adresse zurückgeliefert. Ist der Wert ungleich 0, dann wird &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf den nächste long gesetzt, &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; also um 4 Bytes weitergezählt. &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ist ja ein Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, und ein &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; ist 4 Bytes lang.&lt;br /&gt;
&lt;br /&gt;
Die Bedeutung von&lt;br /&gt;
 address + n&lt;br /&gt;
ist also, die Adresse um das &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;-fache der Größe des Typs, auf den &amp;lt;tt&amp;gt;address&amp;lt;/tt&amp;gt; zeigt, zu erhöhen. Dabei ist &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; eine ganze Zahl und darf auch negativ sein.&lt;br /&gt;
&lt;br /&gt;
Hier noch ein Beispiel einer Funktion, die nach einer Person mit einer bestimmten ID sucht (für die Definition von &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; siehe [[#Strukturen|Strukturen]]). Der Parameter &amp;lt;tt&amp;gt;person&amp;lt;/tt&amp;gt; ist dabei ein Array von Strukturen. Eine Person mit der gesuchten ID muss existieren, ansonsten hat die Suchfunktion kein definiertes Verhalten.&lt;br /&gt;
 {{comment|Sucht nach einer Person mit der ID person_id}}&lt;br /&gt;
 struct Person * &lt;br /&gt;
 suche_person_id (struct Person * person, int person_id)&lt;br /&gt;
 {&lt;br /&gt;
    while (person-&amp;gt;id != person_id)&lt;br /&gt;
       person++;&lt;br /&gt;
 &lt;br /&gt;
    return person;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:1em; padding:1em; border:solid 2px #FF0040;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- Vorlage:FarbigerRahmen funzt hier net --&amp;gt;&lt;br /&gt;
Beachte, daß es nicht sinnvoll ist, zwei Zeiger zu addieren oder zu multiplizieren. Ausserdem ist das &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt; der Zeiger-Arithmetik nicht kommutativ. Eine Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, der an Adresse 1 im Speicher zeigt, wird man schreiben als&lt;br /&gt;
 (long *) 1&lt;br /&gt;
Addiert man darauf eine ganze Zahl, dann haben die entstehenden Ausdrücke unterschiedliche Werte:&lt;br /&gt;
 (long *) 1 + 2    {{comment|zeigt zu Adresse 9}}&lt;br /&gt;
 (long *) 2 + 1    {{comment|zeigt zu Adresse 6}}&lt;br /&gt;
 (long *) (1 + 2)  {{comment|zeigt zu Adresse 3}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==void-Pointer==&lt;br /&gt;
Eine besondere Art von Zeiger ist der void-Pointer&lt;br /&gt;
 void * addr;&lt;br /&gt;
Ein void-Pointer ist ein &amp;quot;Zeiger auf irgendwas&amp;quot;, dementsprechend kann er nicht dereferenziert werden, Anwenden von &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf einen solchen Zeiger gibt also einen Fehler. Ausserdem ist es nicht möglich, mit einem void-Pointer Zeigerarithmetik zu machen, weil er nicht auf eine definierte Art von Objekt zeigt. Der Vorteil eines void-Pointers ist, daß er jede Art von Zeiger aufnehmen kann.&lt;br /&gt;
&lt;br /&gt;
Dazu betrachten wir die Funktion &amp;lt;tt&amp;gt;send_buf&amp;lt;/tt&amp;gt;, die eine Adresse erhält und ab dieser Adresse &amp;lt;tt&amp;gt;num&amp;lt;/tt&amp;gt; Bytes versenden soll. Wir könnten die Funktion so schreiben:&lt;br /&gt;
 void send_buf (unsigned char * buf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   ...&lt;br /&gt;
Das ist jedoch hässlich, wenn wir damit etwas anderes verschicken wollen als &amp;lt;tt&amp;gt; unsigned char&amp;lt;/tt&amp;gt;, etwa eine Struktur wie &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; (vom Typ &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;):&lt;br /&gt;
 send_buf ((unsigned char*) &amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
Ohne den Cast der Adresse von &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; zu einem Zeiger auf &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt; bekommt man eine Warnung oder gar einen Compilerfehler.&lt;br /&gt;
Dieses Zeiger gecaste ist mühsam und hässlich, es muss bei jedem Aufruf der Funktion explizit hingeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Besser ist es, den ersten Parameter der Funktion als void-Pointer zu definieren und den Cast in der Funktion zu machen:&lt;br /&gt;
 void send_buf (void * vbuf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   unsigned char *buf = (unsigned char*) vbuf;&lt;br /&gt;
   ...&lt;br /&gt;
Durch den Cast in der Funktion kann auf den Inhalt des Zeigers zugegriffen werden. Man muss nur festlegen, ''wie'' man zugreifen will, nämlich als &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Der Aufruf kann jetzt ohne Pointer-Cast erfolgen: &lt;br /&gt;
 send_buf (&amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
&lt;br /&gt;
==Null-Pointer==&lt;br /&gt;
==Zeiger als Parameter==&lt;br /&gt;
Wenn Sie ein Unterprogramm aufrufen, können Sie diesem Parameter übergeben, aber keine Werte zurückgekommen (außer den Funktionswert bei Funktionen). Dies hat einen guten Grund: beim Aufruf werden nicht die aufgerufenen Parameter benutzt, sondern es werden deren Werte in neue Variablen kopiert. Diese Variablen werden am Ende des Unterprogrammes &amp;quot;zerstört&amp;quot;, ohne ihre Werte an die aufrufenden Parameter zu übergeben. Jede Veränderung eines Parameters hat daher keine Auswirkung auf den Parameter.&lt;br /&gt;
&lt;br /&gt;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der C-Compiler legt dann immer noch Kopien an. In dieser Kopie steht aber kein Wert, sondern die Adresse einer Varaiblen. Und auf diese können Sie dann zugreifen. Denken Sie nur an &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; &amp;amp;ndash; da übergeben Sie ja auch die Adresse einer Variablen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void erhoehe (int *zeiger)&lt;br /&gt;
{&lt;br /&gt;
  *zeiger = 1 + *zeiger;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  erhoehe (&amp;amp;zahl);&lt;br /&gt;
  printf (&amp;quot;\nDie erhoehte Zahl lautet: %d\n&amp;quot;, zahl);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Zeiger auf Funktionen==&lt;br /&gt;
&lt;br /&gt;
Stell dir vor, du willst einen Sortieralgorithmus wie Bubble-Sort oder Quick-Sort oder wie sie alle heissen implementieren. Für den Sortieralgorithmus ist eigentlich egal, ''was'' er zu sortieren hat. Ihm ist es egal, ob er Zahlen aufwärts sortieren soll oder Strings in lexikographischer Reihenfolge, ob Objekte nach Größe oder Gewicht, Personen nach Alter oder Adressen nach Postleitzahl. Das einzige, was der Algorithmus wissen muss, ist ''wie'' er zwei Objekte zu vergleichen hat und wann eines davon &amp;quot;kleiner&amp;quot; (im Sinne der Ordnung, nach der sortiert werden soll) ist. &lt;br /&gt;
&lt;br /&gt;
Eine einfache Sortierfunktion, die nur zwei Zahlen sortiert, könnte man also so schreiben: &lt;br /&gt;
 {{comment|Sortiert ein Array von 2 int-Zeigern nach den Inhalten &lt;br /&gt;
  * an den Zeiger-Adressen}}&lt;br /&gt;
 void sort2_a (int * p[])&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Inhalte vergleichen...}}&lt;br /&gt;
    if (*p[0] &amp;gt; *p[1])&lt;br /&gt;
    {&lt;br /&gt;
       {{comment|... und ggf. Dreieckstausch der 2 Zeiger}}&lt;br /&gt;
       int * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Die Funktion bekommt ein Array der Länge&amp;amp;nbsp;2. In diesem Array stehen Zeiger auf die zu sortierenden Zahlen. Ein Array mit Zeigern zu verwenden und nicht ein Array von &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; scheint recht umständlich, und das ist es hier auch. Aber stell dir vor, du willst Strukturen wie &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; sortieren. Das Tauschen zweier Strukturen würde bedeuten, ihre kompletten Inhalte umzukopieren! Das wäre sehr aufwändig. Viel einfacher ist das Kopieren, wenn nur die Adressen zu kopieren sind.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; könnte dann so aussehen:&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void sortiere (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|p[] enthält 2 int-Zeiger: die Adressen von a und b}}&lt;br /&gt;
    int * p[2];&lt;br /&gt;
    p[0] = &amp;amp;a; &lt;br /&gt;
    p[1] = &amp;amp;b; &lt;br /&gt;
 &lt;br /&gt;
    {{comment|Sortiere die Zeiger}} &lt;br /&gt;
    sort2_a (p);&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Sortiert: %d, %d\n&amp;quot;, *p[0], *p[1]);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Für den nächsten Schritt überlegen wir uns, daß das Array in &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; ebensogut void-Pointer enthalten kann. Die einzige Stelle, an der wir auf die endgültigen int-Objekte zugreifen, ist der Vergleich. Diesen Vergleich lagern wir in die Funktion &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; aus:&lt;br /&gt;
 {{comment|Bekommt zwei void-Pointer und vergleicht die Inhalte.&lt;br /&gt;
  * Liefert 0 bei Gleichheit,&lt;br /&gt;
  * -1 wenn der erste Wert kleiner ist als der zweite und&lt;br /&gt;
  * 1  wenn der erste Wert größer ist als der zweite}}&lt;br /&gt;
 int compare_int (void * p0, void * p1)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Um über die Zeiger zugreifen zu können müssen wir diese&lt;br /&gt;
     * erst zu int-Zeigern casten}}&lt;br /&gt;
    int a0 = * (int*) p0;&lt;br /&gt;
    int a1 = * (int*) p1;&lt;br /&gt;
 &lt;br /&gt;
    if (a0 &amp;gt; a1)  return  1;&lt;br /&gt;
    if (a0 &amp;lt; a1)  return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void sort2_b (void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare_int (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Ein Aufruf von &amp;lt;tt&amp;gt;sort2_b&amp;lt;/tt&amp;gt; sieht dann genauso aus wie ein Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt definieren wir uns den neuen Datentyp &amp;lt;tt&amp;gt;comparator_t&amp;lt;/tt&amp;gt;. Dieser ist ein Zeiger auf eine Funktion, die zwei void-Pointer erhält und einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; zurückliefert, also analog arbeitet zu &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; von oben. &lt;br /&gt;
&lt;br /&gt;
Unsere Sortierfunktion bekommt nun neben dem zu sortierenden Zeiger-Array auch eine Vergleichsfunktion &amp;lt;tt&amp;gt;compare&amp;lt;/tt&amp;gt; mitgeliefert, die sie aufruft, wenn sie zwei Objekte vergleichen will&lt;br /&gt;
 {{comment|comparator_t sind Zeiger auf Funktionen, die 2 void-Pointer&lt;br /&gt;
  * erhalten und einen int zurückliefern}}&lt;br /&gt;
 typedef int (*comparator_t) (void*, void*);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Der Sortierer bekommt einen Funktionszeiger auf den Vergleicher.&lt;br /&gt;
  * Der Aufruf vom compare geht so als wäre es eine &amp;quot;normale&amp;quot; Funktion&lt;br /&gt;
  * (ist es im Endeffekt ja auch)}}&lt;br /&gt;
 void sort2_c (comparator_t compare, void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Bei einem Aufruf von &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; muss man dann einen Komparator mit angeben. In einem Beispiel analog zu &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; von oben ist das:&lt;br /&gt;
 sort2_c (compare_int, p);&lt;br /&gt;
Um zwei Strings lexikographisch zu sortieren nehmen wie die Standard-Funktion &amp;lt;tt&amp;gt;strcmp&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void foo()&lt;br /&gt;
 {&lt;br /&gt;
    char * worte[] = { &amp;quot;Wort1&amp;quot;, &amp;quot;Wort2&amp;quot; };&lt;br /&gt;
 &lt;br /&gt;
    sort2_c ((comparator_t) strcmp, (void**) worte);&lt;br /&gt;
 }&lt;br /&gt;
Die Casts sind hier erforderlich. Alternativ könnte man &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; mit reinen void-Pointern versorgen und diese dann dort umcasten.&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
&lt;br /&gt;
Die Syntax zur Definition/Deklaration von Funktionszeigern ist etwas verzwackt. Zur Verdeutlichung ein paar Beispiele. Dabei legt das linke &amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt; jeweils den Return-Typ fest.&lt;br /&gt;
 {{comment|definiert einen neuen Funktionszeiger-Typ}}&lt;br /&gt;
 typedef {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert einen Funktionszeiger}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert ein Array von Funktionszeigern (mit Initializer)}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}[]) ({{type}}, {{type}}, ...) = { wert1, wert2, ... };&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer}}&lt;br /&gt;
 ({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer und ruft die Funktion auf}}&lt;br /&gt;
 (({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}) (arg1, arg2, ...);&lt;br /&gt;
&lt;br /&gt;
=Standard-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==String-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===strcpy===&lt;br /&gt;
Bei vielen Compilern können sie einem String nicht direkt einen Wert (Text) zuweisen. Dazu müssen Sie dann die Prozedur strcpy() benutzen. Diese erwartet als ersten Parameter den Namen einer String-Variablen (ohne eckige Klammern) und als zweiten Parameter den eines (anderen) Strings. Letzterer kann auch ein in doppelten Hochkommas (&amp;quot;) eingeschlossener Text sein. Die Funktion fügt am Ende automatisch ein 0-Zeichen ein. Um diese Funktion nutzen zu können, müssen Sie die Datei string.h includieren! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri1[21], eingabe[21];&lt;br /&gt;
&lt;br /&gt;
  strcpy (stri1, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Der 1. String: %s\n&amp;quot;, stri1);&lt;br /&gt;
  printf (&amp;quot;Bitte geben Sie maximal 20 Zeichen ein: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%s&amp;quot;, eingabe);&lt;br /&gt;
  strcpy (stri1, eingabe);&lt;br /&gt;
  printf (&amp;quot;\n%s = %s&amp;quot;, stri1, eingabe);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis:''' &lt;br /&gt;
Da ein String, wie jedes Feld, eigentlich ein Zeiger ist, dürfen Sie kein &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; bei &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; angeben!&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
Es werden zwei gleich große Strings definiert: &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;eingabe&amp;lt;/tt&amp;gt;, mit je 20 &amp;quot;nutzbaren&amp;quot; Zeichen. &lt;br /&gt;
In &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; wird die Zeichenkette &amp;lt;tt&amp;gt;&amp;quot;hallo&amp;quot;&amp;lt;/tt&amp;gt; hineinkopiert. Das 0-Zeichen am Ende wird automatisch angefügt. &lt;br /&gt;
Der String wird ausgegeben. Als neues &amp;quot;Sonderzeichen&amp;quot; kommt &amp;lt;tt&amp;gt;%s&amp;lt;/tt&amp;gt; ins Spiel. Es hat die gleiche Aufgabe wie &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt;, nur für Strings. &lt;br /&gt;
Sie werden gebeten, eine String einzugeben. &lt;br /&gt;
Dieser String wird danach in die Variable &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; kopiert. &lt;br /&gt;
Beide Strings, die ja nun die gleiche Zeichenkette enthalten, werden ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===strlen===&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;strlen&amp;lt;/tt&amp;gt;, die als Parameter eine String-Variable erwartet, liefert die Länge diese Strings zurück. Sie werden jetzt vermutlich sagen: &amp;quot;Das ist doch klar, wie lang der String ist. Ich habe es ja bei der Deklaratin angegeben&amp;quot;. Das stimmt schon, aber denken Sie noch einmal an die null-terminierten Strings. Das 0-Zeichen steht am Ende des Strings (am Ende der gültigen Zeichenfolge), aber nicht unbedingt am Ende des reservierten Speicherplatzes. Haben Sie eine Variable &amp;quot;char Variable[21];&amp;quot;, und ihr den Wert &amp;quot;hallo&amp;quot; zugewiesen, dann steht das null-Zeichen in Variable[5]. Der &amp;quot;gültige&amp;quot; String ist also 5 Zeichen (0-4) lang. Und genau das (5) würde strlen zurück liefern. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri[21];&lt;br /&gt;
  &lt;br /&gt;
  strcpy (stri, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
  printf (&amp;quot;Der String ist %d Zeichen lang&amp;quot;, strlen (stri));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird vor allem gebraucht, wenn Sie direkt auf den String zugreifen, mittels &amp;lt;tt&amp;gt;stri[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;stri[1]&amp;lt;/tt&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
==Ein- und Ausgabe-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===Bildschirm-Ausgabe===&lt;br /&gt;
Bisher war das Tutorial trotz aller Beispiele reine Theorie. Sie konnten zwar Programme schreiben, aber die Funktion nicht testen. Hier lernen Sie nun, wie Sie etwas am Bildschirm ausgeben.&lt;br /&gt;
&lt;br /&gt;
Die dazu notwendige Funktione heisst &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (das '&amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt;' ist kein Fehler!). Diese Anweisung gibt die ihr übergebenen Parameter auf das Standard-Ausgabegerät aus, in der Regel also auf den Bildschirm. Sie kann beliebig viele Parameter übernehmen. Es müssen jedoch Standard-Datentypen (z.B. &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;...) sein! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
    int zahl1 = 12;&lt;br /&gt;
    char zeichen1 = 'A';&lt;br /&gt;
    &lt;br /&gt;
    printf (&amp;quot;Das ist Text, und er wird als solcher ausgegeben. \n&amp;quot;);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zahl1' ist: %d \n&amp;quot;, zahl1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %c \n&amp;quot;, zeichen1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %d \n&amp;quot;, zeichen1);&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt Text aus. Das Zeichen am Ende (&amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;) bedeutet &amp;quot;New Line&amp;quot;, es bewegt den Cursor an den Anfang der nächsten Zeile. &lt;br /&gt;
&lt;br /&gt;
Der zweite &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt auch Text aus, am Ende befindet sich wieder das &amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;, um einen Zeilenvorschub zu erreichen. Das &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; wird vom Compiler durch den ersten Parameter ersetzt, der nach dem Text angegeben wird. In diesem Fall wird &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; also durch den Wert der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ersetzt. Das &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; im &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; bedeutet &amp;quot;Dezimalzahl&amp;quot;, der Computer gibt also eine ganze Zahl aus. &lt;br /&gt;
&lt;br /&gt;
In der dritten Ausgabe wird ein Zeichen ausgegeben. Diesmal bedeutet &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; &amp;quot;char&amp;quot; (Zeichen). Es wird also &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; durch ein &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt; ersetzt, denn die Variable &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; wird als Character interpretiert. &lt;br /&gt;
&lt;br /&gt;
Die letzte Ausgabe interpretiert den Inhalt von &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; als Zahl, und gibt dager den ASCII-Wert von &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, also 65 aus. Das ist ein typisches Beispiel für das mögliche unterschiedliche Interpretieren einer  Variablen!&lt;br /&gt;
&lt;br /&gt;
===Tastatur-Eingabe===&lt;br /&gt;
&lt;br /&gt;
Um ein &amp;quot;gscheites&amp;quot; Programm schreiben zu können, muß man wissen, wie der Benutzer über die Tastatur Befehle eingeben kann. Die dafür notwendigen Funktionen stelle ich in diesem Kapitel vor.&lt;br /&gt;
Die wichtigste Funktion ist &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt;. Er liest Daten von der Tastatur. Die Syntax entspricht derer von &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int  zahl1;&lt;br /&gt;
char zeichen1;&lt;br /&gt;
&lt;br /&gt;
printf (&amp;quot;Bitte geben Sie eine Zahl ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl1);&lt;br /&gt;
printf (&amp;quot;Geben Sie einen Zeichen ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%c&amp;quot;, &amp;amp;zeichen1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Programm gibt eine Eingabeaufforderung aus. Dann erwartet es vom Benutzer, daß er eine Zahl eingibt, die mit [ENTER] bestätigt wird. Dieser Wert wird in &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; abgespeichert. Danach erfolgt wiederum eine Aufforderung zur Eingabe, diesmal eines einzelnen Zeichens. Dieses kann man nun eingeben und ebenfalls mit [ENTER] bestätigen.&lt;br /&gt;
&lt;br /&gt;
Macht man keine dem Datentyp der erwarteten Variable entsprechende Eingabe, dann bricht das Programm mit einer Fehlermeldung ab (wenn man z.B. &amp;quot;1_T2&amp;quot; eingibt, wenn eine Zahl erwartet wird)!&lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; vor den Parametern ist notwendig. Warum, das erfahren Sie im Kapitel &amp;quot;Unterprogramme&amp;quot;. Für die Profis eine Kurz-Erklärung: Das Unterprogramm &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; bekommt zwar einen Wert übergeben, kann aber keinen zurückliefern (&amp;quot;call by value&amp;quot;). Daher wird kein Wert, sondern ein Zeiger auf eine Variable übergeben. Mit dem &amp;amp; Zeichen bekommen Sie die Adresse einer Variablen (&amp;quot;call by reference&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=Parameter von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;=&lt;br /&gt;
Das Unterprogramm &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; kann, wie jede andere Funktion, Parameter besitzen. Doch keine selbst gewählten, sondern nur bestimmte. Doch warum braucht main Parameter? Denken Sie einmal an alle Betriebssystembefehle:&lt;br /&gt;
&amp;lt;tt&amp;gt;dir *.exe &amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;copy *.* a:&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;ls -la &amp;lt;/tt&amp;gt;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;&amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen!&lt;br /&gt;
&lt;br /&gt;
=Kurzreferenz=&lt;br /&gt;
==Syntax-Bausteine==&lt;br /&gt;
&lt;br /&gt;
Die Erklärung des Aufbaus von C-Befehlen erfolgt neben einfachen Beispielen auch durch ihren prinzipellen Aufbau. In diesen Syntax-Beschreibungen finden sich immer wieder die gleichen Bausteine, die hier näher erklärt werden sollen. Falls die solch ein Syntax-Baustein begegnet, kannst Du ihn anclicken und kommst dann zu seiner Erläuterung. &lt;br /&gt;
&lt;br /&gt;
In den Beispielen selbst gehören auch die spitzen Klammern zu dem Baustein (was daran zu erkennen ist, daß auch die Klammern eingefärbt sind). Die Klammern dürfen in einem konkreten C-Programm daher nicht eingetippt werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bezeichner&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Bezeichner in C dienen dazu, Variablen zu identifizieren und ihnen sprechende Namen zu geben, um die Quelle lesbarer zu machen. Man braucht Bezeichner auch, um selbstdefinierte Datentypen zu benennen und zum Benennen von Struct- und Union-Komponenten sowie als Namen für Funktionen und Sprungmarken (Labels).&lt;br /&gt;
&lt;br /&gt;
Bezeichner dürfen aus den Kleinbuchstaben &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;z&amp;lt;/tt&amp;gt;, den Großbuchstaben &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;Z&amp;lt;/tt&amp;gt;, dem Unterstrich&amp;amp;nbsp;&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt; und den Ziffern &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;9&amp;lt;/tt&amp;gt; aufgebaut werden, wobei an erster Stelle jedoch keine Ziffer stehen darf.&lt;br /&gt;
&lt;br /&gt;
Es wird zwischen Groß- und Kleinschreibung unterschieden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Ausdruck in C ist ein Konstrukt, das einen Wert hat. Ob dieser Wert eine ganze Zahl ist, eine Kommazahl oder ein Zeiger, etc. ist dabei egal. Die einfachsten Ausdrücke sind Konstanten wie&lt;br /&gt;
 2&lt;br /&gt;
oder Variablen wie&lt;br /&gt;
 ein_zahl&lt;br /&gt;
Mehrere Ausdrücke können durch [[#Liste der Operatoren|Operatoren]] zu komplexeren Ausdrücken kombiniert werden, etwa&lt;br /&gt;
 eine_zahl + andere_zahl == 2&lt;br /&gt;
oder &lt;br /&gt;
 eine_zahl = 2&lt;br /&gt;
Letzterer hat den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; und den Nebeneffekt, daß er diesen Wert an &amp;lt;tt&amp;gt;eine_zahl&amp;lt;/tt&amp;gt; zuweist.&lt;br /&gt;
&lt;br /&gt;
Auch der Aufruf einer Funktion, die einen Rückgabewert liefert, ist ein Ausdruck:&lt;br /&gt;
 sin (1.2)&lt;br /&gt;
und kann zum Aufbau komplexerer Ausdrüche verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bedingung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Bedingung ist ein Ausdruck, bei der nur interessiert, ob dieser zu&amp;amp;nbsp;0 (unwahr) auswertet oder zu ungleich&amp;amp;nbsp;0 (wahr). Solche Ausdrücke findet man in if-Anweisungen, in Schleifenbedingungen und bedingten Zuweisungen&lt;br /&gt;
 (ein_wert &amp;lt; 2) || (ein_wert &amp;gt; 40)&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Lvalue ist ein Ausdruck, dem etwas zugewiesen werden kann. Der Name ''Lvalue'' kommt aus dem Englischen. Das ''L'' steht abkürzend für left. Ein Lvalue ist damit ein Ausdruck, der auf der linken Seite eine Zuweisung in C stehen darf. Das &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; in den folgenden Beispiel-Ausdrücken muss ein Lvalue sein:&lt;br /&gt;
 x = y-1&lt;br /&gt;
&lt;br /&gt;
 x++&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Konstante&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Konstante ist ein Ausdruck, dessen Wert dem Compiler bekannt ist. Beispiele für Konstanten sind etwa&lt;br /&gt;
 7&lt;br /&gt;
 'B'&lt;br /&gt;
 -13.98e12&lt;br /&gt;
 1+(2*3)&lt;br /&gt;
und die Werte von [[#Enum|Enum]]s. &lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; aus dem folgenden Codestück definiert jedoch keine Konstante in diesem Sinne&lt;br /&gt;
 const double Pi = 3.14159256;&lt;br /&gt;
denn in einem anderen Quellmodul könnte durch die Deklaration&lt;br /&gt;
 extern const double Pi;&lt;br /&gt;
das Symbol &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; bekannt sein, ohne daß sein Wert bekannt ist!&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Adresse&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Adresse ist ein Ausdruck, der einen Speicherort (physikalisch oder virtuell) halten kann. Adressen erhält man dadurch, daß man einem Bezeichner den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt;voranstellt, Adressen durch Arithmetik berechnet oder Zahlen zu Adressen castet. Folgende Ausdrücke sind Adressen (eine sinnvolle Deklaration der auftretenden Variablen vorausgesetzt)&lt;br /&gt;
 &amp;amp; eine_zahl&lt;br /&gt;
 &amp;amp; ein_array[10]&lt;br /&gt;
 &amp;amp; ein_struct&lt;br /&gt;
 &amp;amp; ein_struct.komponente&lt;br /&gt;
 (int *) 0x1234&lt;br /&gt;
 (int *) eine_zahl&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Deklaration&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Anweisungen sind gewissermassen die Atome (oder Moleküle?), aus denen ein C-Programm besteht. Jedes C-Programm ist eine Abfolge von Deklarationen und Anweisungen. Einfache Anweisungen erhält man, in dem man einen Ausdruck nimmt und einen Strichpunkt dahinter schreibt:&lt;br /&gt;
 {{Ausdruck|}};&lt;br /&gt;
wie in&lt;br /&gt;
 x = x+1;&lt;br /&gt;
&lt;br /&gt;
Andere Anweisungen sind die unten aufgeführten Schleifen und die if- sowie die switch-Anweisung.&lt;br /&gt;
&lt;br /&gt;
Mehrere Deklarationen und Anweisungen können zu einem Block zusammengefasst werden. Dieser Block stellt dann wieder eine einzelne Anweisung dar und kann genau so gehandhabt werden!&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
In diesem Sinne ist auch z.B. die Syntax der if-Anweisung zu verstehen&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
besagt, daß der abhängig ausgeführte Code eine einzelne Anweisung sein darf oder eben ein kompletter Block oder die Verschachtelung mehrerer Blöcke etc.&lt;br /&gt;
&lt;br /&gt;
Eine Anweisung kann auch &amp;quot;leer&amp;quot; sein, also nichts tun. Diese Anweisungen sind der leere Block&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
und der Strichpunkt&lt;br /&gt;
 ;&lt;br /&gt;
die man gelegentlich in Schleifen findet:&lt;br /&gt;
 while (!timeout())&lt;br /&gt;
    {}&lt;br /&gt;
oder hinter Sprungmarken, die sonst direkt vor einer schliessenden Blockklammer stünden:&lt;br /&gt;
 {&lt;br /&gt;
    ...&lt;br /&gt;
    goto ein_label;&lt;br /&gt;
    ...&lt;br /&gt;
    {{Label|ein_label}}:;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Nicht jede Anweisung ist an jeder Stelle eines C-Programms erlaubt, so darf ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; nut innerhalb einer Schleife stehen. Gleiches gilt für &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;, das aber auch innerhalb eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; vorkommen darf.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Dies steht für einen Datentyp. Es kann ein elementarer Typ sein wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;, ein Zeiger darauf wie &amp;lt;tt&amp;gt;char*&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;void*&amp;lt;/tt&amp;gt;, und auch Qualifier enthalten wie das &amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt; im Typ &amp;lt;tt&amp;gt;unsigned long long&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Zu den Typen gehören auch zusammengesetzte Datentypen wie Strukturen und Unions, mit &amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt; selbst definierte Typen und natürlich Zeiger darauf, wie aus dem Abschnitt [[#Datentypen|Datentypen]]:&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person *&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;data32_t&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;&lt;br /&gt;
und Zeiger auf Funktionen.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Parameterliste&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
Die Parameterliste bei einer Funktionsdefinition gibt an, wieviel Übergabeparameter sie bekommt, wie diese heissen und welchen Typs diese sind. Der prinzipielle Aufbau ist&lt;br /&gt;
 {{Type}} {{Bezeichner}}, {{Type}} {{Bezeichner}}, ...&lt;br /&gt;
Falls die Funktion keine Parameter hat, dann ist die Parameterliste leer.&lt;br /&gt;
&lt;br /&gt;
Hier als Beispiel die zweiparametrige Funktion &amp;lt;tt&amp;gt;produkt&amp;lt;/tt&amp;gt;. Der erste Parameter heisst&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und ist ein &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;. Der zweite namens&amp;amp;nbsp;&amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; ist vom Typ &amp;quot;Zeiger auf double&amp;quot;, der Inhalt &amp;lt;tt&amp;gt;*b&amp;lt;/tt&amp;gt; ist also auch ein double.&lt;br /&gt;
&lt;br /&gt;
'''Definition der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b)&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
In älteren C-Quellen findet man noch eine andere Syntax für die Deklaration der Parameter, die aber heute praktisch nicht mehr verwendet wird:&lt;br /&gt;
'''alte Definition der Funktion:'''&lt;br /&gt;
 double produkt (a, b)&lt;br /&gt;
 double a, *b;&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Um die Funktion bekannt zu machen, werdendet man eine Deklaration bzw. den Prototypen, der dem Compiler nur mitteilt, welche Parameter die Funktion bekommt und was sie zurückliefert. Für den Aufruf der Funktion muss der Compiler nur diesen Prototyp kennen, ''was'' die Funktion im Endeffekt macht und wie sie implementiert wurde ist egal, sie wird als BlackBox angesehen.&lt;br /&gt;
&lt;br /&gt;
'''Prototyp der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b);&lt;br /&gt;
Hier dürfen die Bezeichner auch fehlen:&lt;br /&gt;
 double produkt (double, double*);&lt;br /&gt;
&lt;br /&gt;
==if==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==if-else==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==for==&lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Eine for-Schleife entspricht folgendem Konstrukt. Dabei sind die drei Ausdrücke optional. Fehlt die Bedingung, dann wird diese als &amp;quot;wahr&amp;quot; angenommen. Die beiden anderen Ausdrücke wird man als Ausdrücke mit Nebeneffekt wählen wie z.B. &amp;lt;tt&amp;gt;x=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;x=x-2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
 {&lt;br /&gt;
    {{Ausdruck|1}};&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_loop}}:&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
    else&lt;br /&gt;
       goto _break;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_continue}}:&lt;br /&gt;
    {{Ausdruck|2}};&lt;br /&gt;
    goto _loop;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_break}}:;&lt;br /&gt;
 }&lt;br /&gt;
Die Labels &amp;lt;tt&amp;gt;_break&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_continue&amp;lt;/tt&amp;gt; entsprechen den Sprungzielen einer &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Anweisung innerhalb von &amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==do-while==&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while  ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
==while==&lt;br /&gt;
 while  ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==switch==&lt;br /&gt;
 switch  ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    ...&lt;br /&gt;
  &lt;br /&gt;
    default:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#break-Anweisung|&amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Konstanten|&amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#continue-Anweisung|&amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#do-while-Schleife|&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Enum|&amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#for-Schleife|&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#goto-Anweisung|&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#return-Anweisung|&amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Liste der Operatoren|sizeof]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Strukturen|&amp;lt;tt&amp;gt;struct&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Eigene Datentypen|&amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Unions|&amp;lt;tt&amp;gt;union&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#while-Schleife|&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund2}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Arithmetische Operatoren&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Dies sind die &amp;quot;normalen&amp;quot; arithmetischen Operationen, wie man sie aus der Schule kennt. Man kann damit und allen anderen Operatoren auch komplexere Ausdrücke aufbauen. Die Prioritäten sind so, wie man sie kennt, also &amp;quot;Punktrechnung vor Strichrechnung&amp;quot;. Will man dies ändern, dann mit den runden Klammern:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;1+2*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 7&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(1+2)*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 9&amp;lt;br/&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}}&amp;amp;nbsp;+&amp;amp;nbsp;{{Ausdruck|}}&amp;lt;/tt&amp;gt; || Addition&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} - {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Subtraktion&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} * {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Multiplikation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} / {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Division&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} % {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Rest der Division (modulo)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;- {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Vorzeichenumkehr, Zweier-Komplement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Logische Operatoren und Vergleiche&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die logischen und die vergleichenden Operatoren liefern als Ergebnis den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (wahr) oder einen Wert ungleich&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (falsch, um genau zu sein den Wert &amp;lt;tt&amp;gt;!0&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Man kann das Ergebnis zwar einer Variablen zuweisen, in aller Regel wird man solche Ausdrücke jedoch in Bedingungen zu &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder in Abbruch-Bedingungen von Schleifen finden.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;&amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches AND: beides wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124;&amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches OR: mind. eines ist wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;! {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches NOT (0 &amp;amp;harr; ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} == {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} != {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist nicht gleich&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bitweise Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~ {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise NOT (Einser-Komplement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise AND&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise ODER&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} ^ {{Ausdruck|}}&amp;lt;/tt&amp;gt; ||bitweise XOR&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Shift-Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;lt;&amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Bits nach links schieben&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;gt;&amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Schieben nach rechts schieben&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Typen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Ein Cast in C kann dazu verwendet werden, den Typ eines Ausdruckes zu ändern oder den Ausdruck mit einer bestimmten Genauigkeit zu berechnen. Wird z.B. eine Berechnung standardmässig in 16 Bit ausgeführt, dann kann man mit einem Cast &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(long) &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
ausdrücken, daß die Berechnung in 32 Bit erfolgen soll. Des weiteren kann man Zeiger und ganze Zahlen und Gleitkommazahlen ineinander umwandeln.&lt;br /&gt;
&lt;br /&gt;
Casts können ''nicht'' dazu verwendet werden, um z.B. eine Zahl in einen String zu konvertieren, der diese Zahl darstellt! Dafür gibt es spezielle Funktionen wie &amp;lt;tt&amp;gt;itoa&amp;lt;/tt&amp;gt;!&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Type}}) {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Cast, Typwandlung&lt;br /&gt;
|-&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;| &amp;lt;tt&amp;gt;sizeof ({{Type}})&amp;lt;/tt&amp;gt; || Eine Konstante, deren Wert die Größe (in Bytes) des Typs ist. &amp;lt;tt&amp;gt;sizeof&amp;lt;/tt&amp;gt; ist auch auf Objekte anwendbar wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, Arrays bekannter Größe, Strukturen und Unions,  Array-, Struktur- und Union-Komponenten, Pointer, etc. Beispiel:&amp;lt;br/&amp;gt;&lt;br /&gt;
 int i, sum=0, array[] = { 1, -13, 4, 0, sizeof (int*) };&lt;br /&gt;
 &lt;br /&gt;
 for (i=0; i&amp;lt; sizeof (array) / sizeof (array[0]); i++)&lt;br /&gt;
    sum += array[i];&lt;br /&gt;
Alle Elemente des Arrays werden aufaddiert, ohne daß deren Anzahl explizit in der Schleife genannt ist.&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zeiger und Adressen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;* {{Adresse}}&amp;lt;/tt&amp;gt; || der Inhalt an Adresse&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp; {{Lvalue}}&amp;lt;/tt&amp;gt; || Adresse von&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Strukturen, Unions, Arrays&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Struct&amp;gt;}}.{{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Zeiger-auf-Struct&amp;gt;}} -&amp;gt; {{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union, deren Adresse man hat&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Adresse}}&amp;amp;#91;{{Ausdruck|}}&amp;amp;#93;&amp;lt;/tt&amp;gt; || Array-Element&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bedingte Auswertung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Bedingung}}) ? {{Ausdruck|}} : {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Auswahl des Wertes abhängig von der Bedingung&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zuweisung und Operatoren mit Nebeneffekt&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die Unterschiede der post- und pre-Varianten der Increment/Decrement kommen in Konstrukten wie &amp;lt;tt&amp;gt;x = *p++&amp;lt;/tt&amp;gt; zum tragen:&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *p++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; p = p+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *++p;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; p = p+1; x = *p;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = (*p)++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; *p = (*p)+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = ++(*p);&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; *p = (*p)+1; x = *p;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} = {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Zuweisung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++ {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-- {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Decrement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ++&amp;lt;/tt&amp;gt; || Post-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} --&amp;lt;/tt&amp;gt; || Post-Decrement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Kurzschreibweisen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Für ganz Faule gibt es anstatt&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a = a @ b&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
für viele Operatoren (hier dargestellt durch ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;@&amp;lt;/tt&amp;gt;) die abkürzende Schreibweise&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a @= b&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} += {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} -= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} *= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} /= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} %= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ^= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;lt;&amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;gt;&amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Autoren'''&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
* Kernighan und Ritchie - Buch&lt;br /&gt;
* Christian Wirth , C Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://wwwuser.gwdg.de/~kboehm/ebook/inhalt.html C-Programmieren unter Linux]&lt;br /&gt;
* [http://www.gdv.uni-hannover.de/documentation.php Skripte zum Selbststudium: C, C++, Java, etc]&lt;br /&gt;
* [http://info.baeumle.com/ansic.html Einführung in ANSI-C]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Quellcode C|!]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Inrfb2</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10391</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10391"/>
				<updated>2007-03-13T11:07:42Z</updated>
		
		<summary type="html">&lt;p&gt;Inrfb2: /* Reihenfolge der Auswertung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Programmiersprache C wurde 1971 als Gundlage für das Betriebssystem UNIX in den USA entwickelt (UNIX ist zu über 90% in C geschrieben). 1978 wurde von Brian Kernighan und Dennis Ritchie eine eindeutige Sprachdefinition entwickelt. Mittlerweile ist C von ANSI und ISO standardisiert.&lt;br /&gt;
&lt;br /&gt;
Heute sind C und ihr Nachfolger C++ die dominierenden Programmiersprachen. Sehr viele Anwendungen sind in C geschrieben, was inzwischen auch auf eingebettete Systeme zutrifft, die lange in Assembler programmiert werden mussten, da keine ausreichend leistungsfähigen Compiler zur Verfügung standen. &lt;br /&gt;
&lt;br /&gt;
Leider ist C nicht einfach zu lernen &amp;amp;ndash; es wurde weder von noch für Hobby-Programmierer entwickelt &amp;amp;ndash; und eignet sich daher nur bedingt für den Einsteiger. Mit etwas Übung und einem optimierenden Compiler kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
Vom Design her ist C eine Hardware-unabhängig Sprache. Das bedeutet, daß C-Programme mit vertretbarem Aufwand auf ein anderes System portiert werden können. Dazu benötigt man lediglich einen anderen Compiler, und Inline-Assembler-Anweisungen (Assembleranweisungen innerhalb eines C-Programmes) müssen der neuen Hardware (Prozessor) angepasst werden. &lt;br /&gt;
&lt;br /&gt;
==Geschichte==&lt;br /&gt;
;1971: C wird entwickelt&lt;br /&gt;
;1978: Kernighan und Ritchie definieren die Sprache.&lt;br /&gt;
;1983: ANSI und ISO standardisieren C.&lt;br /&gt;
;1992: Bjarne Stroustrup enwickelt die Nachfolgesprache C++.&lt;br /&gt;
&lt;br /&gt;
=Aufbau eines C-Programmes=&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
   C-Programme haben keinen fixen Aufbau wie z.B. Pascal. Es gibt zwar gewisse Regeln, aber sonst sind dem Programmierer alle Freiheiten überlassen. Der folgende &amp;quot;Beispiel-Aufbau&amp;quot; ist daher nicht zwingend und kann durchaus verändert werden.&lt;br /&gt;
&lt;br /&gt;
   Natürlich haben C-Programme einen fixen Aufbau! Ebenso wie Pascal-Programme auch unterliegen sie einer strikten Grammatik! &lt;br /&gt;
Auskommentiert --[[Benutzer:SprinterSB|SprinterSB]] 10:23, 17. Feb 2006 (CET)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Ein einfaches C-Programm könnte folgendermassen aussehen. Das Programm tut eigentlich nichts, aber das Beispiel zeigt den prinzipiellen Aufbau. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 int Zahl1;&lt;br /&gt;
 char Zeichen1;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int zahl2;&lt;br /&gt;
 &lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Beschreibung:'''&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndash; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
 {{comment|void-Definition von main ist nur beim Controller ueblich}}&lt;br /&gt;
 {{comment|spezielle Compilereinstellungen sind noetig, damit bei dieser Definition von main}}&lt;br /&gt;
 {{comment|kein Fehler/Warnung erzeugt wird.}}&lt;br /&gt;
 void main ()&lt;br /&gt;
 {&lt;br /&gt;
     ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
 int main (void)&lt;br /&gt;
 {  {{comment|der Block &amp;quot;main&amp;quot; beginnt}}&lt;br /&gt;
    int zahl;&lt;br /&gt;
    &lt;br /&gt;
    {   {{comment|ein Block beginnt}}&lt;br /&gt;
        {{comment|hier koennen Deklarationen und Anweisungen stehen}}&lt;br /&gt;
    }   {{comment|der Block endet}}&lt;br /&gt;
   &lt;br /&gt;
    return 0;&lt;br /&gt;
 }  {{comment|&amp;quot;main&amp;quot; endet}}&lt;br /&gt;
&lt;br /&gt;
=Datentypen=&lt;br /&gt;
==Elementare Datentypen==&lt;br /&gt;
Der Datentyp einer Variable gibt an, welche Werte eine Variable enthalten kann, welcher Art diese Daten sind und wie sie verarbeitet werden, etwa in arithmetischen Operationen wie einer Addition. So ist es zum Beispiel möglich, in eine Variable vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ganze Zahlen zwischen ca. -32000 und +32000 einzutragen. In einer char-Variable können ASCII-Zeichen gespeichert werden (alles, was Sie mit der Tastatur erzeugen können) oder ganze Zahlen von -128 bis 127.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da C plattformabhängig ist, hängt die Größe eines Datentypes zum Teil von der genutzten Hardware (z.B. 8, 16 oder 32 Bit-Controller) und dem Compiler und dessen Einstellungen ab!&lt;br /&gt;
&lt;br /&gt;
===int, char, short, long (ganze Zahlen)===&lt;br /&gt;
In Variable dieser Typen können Sie ganze Zahlen abspeichern, also z.B. 1, &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;2, 100, 12345. Jeden dieser Typen gibt es in zwei Ausprägungen: als &amp;quot;&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;quot;, also als vorzeichenbehafteten Typ, und als &amp;quot;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&amp;quot;, also ohne Vorzeichen, d.h. das Vorzeichen wird als 0 oder +1 genommen. &lt;br /&gt;
&lt;br /&gt;
Vorzeichenbehaftete Ganzzahl-Typen werden intern im &amp;lt;tt&amp;gt;n-1&amp;lt;/tt&amp;gt;-Komplement dargestellt, das Vorzeichen selbst findet sich also im höchstwertigen Bit. Werden zur Speicherung ''b'' Bits verwendet, dann reicht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;z.B. *zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==Enum==&lt;br /&gt;
&lt;br /&gt;
Über &amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt; können Aufzählungen definiert werden. Die Werte sind &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Werte und beginnen mit&amp;amp;nbsp;0. Der folgende enum hat einen um&amp;amp;nbsp;1 grösseren Wert. Mit einer Zuweisung können auch andere Werte zugeordnet werden. Klarer wird's im Beispiel:&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 enum Farben&lt;br /&gt;
 {&lt;br /&gt;
    ROT,&lt;br /&gt;
    GRUEN,&lt;br /&gt;
    BLAU,&lt;br /&gt;
    BRAUN = 5,&lt;br /&gt;
    SCHWARZ&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
Dies definiert die Konstanten &amp;lt;tt&amp;gt;ROT=0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;GRUEN=1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BLAU=2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BRAUN=5&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;SCHWARZ=6&amp;lt;/tt&amp;gt; und den Typ &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void foo (enum Farben farbe)&lt;br /&gt;
{&lt;br /&gt;
   switch (farbe)&lt;br /&gt;
   {&lt;br /&gt;
      case ROT:&lt;br /&gt;
         ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit kann man anstatt &amp;quot;magischer&amp;quot; Zahlen sprechende Namen im Code verwenden, etwa in Berechnungen und Zuweisungen, Vergleichen oder als Konstante hinter einem &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zusammengesetzte Datentypen==&lt;br /&gt;
===Arrays===&lt;br /&gt;
Oft muß man sehr viele Werte gleichzeitig abspeichern und betrachten, die alle der selben Aufgabe dienen. Man schreibt z.B. ein Programm, das 10 Zahlen einlesen und anschließend wieder ausgeben soll. Man könnte das natürlich mit 10 einzelnen Variablen bewerkstelligen, aber es ist sinnvoller, dabei Arrays &amp;amp;ndash; teilweise auch als ''Felder'' bezeichnet &amp;amp;ndash; zu verwenden.&lt;br /&gt;
&lt;br /&gt;
In einem Array werden mehrere Variablen gleichen Typs zusammengefasst und hintereinander im Speicher abgelegt. So kann man viele tausend Variablen anlegen mit nur einer Zeile Code. Doch es gibt noch größere Vorteile: Sie können das Array mit einer Schleife ganz einfach nach Werten durchsuchen. Stellen Sie sich vor, Sie müssten mit 100 verschiedenen Variablen &amp;lt;tt&amp;gt;Zahl_00&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;Zahl_99&amp;lt;/tt&amp;gt; arbeiten!&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}}&amp;amp;#91;{{Konstante}}&amp;amp;#93;;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 unsigned int werte[100];&lt;br /&gt;
&lt;br /&gt;
Der Name muß natürlich ein gültiger Bezeichner sein, als Datentyp kann jeder Typ genommen werden &amp;amp;ndash; sowohl elementare Datentypen als auch Zeiger, Strukturen, Unions oder selbst definierte Datentypen. In der eckigen Klammer wird die Anzahl der Elemente bekanntgegeben. Ein mit [3] definiertes Array hat Platz für drei Variablen. Da der Index immer bei 0 beginnt, greift man also mit &amp;lt;tt&amp;gt;[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;[1]&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;[2]&amp;lt;/tt&amp;gt; auf den jeweilige Inhalt zu. Um auf eine der im Array enthaltenen Variablen zugreifen zu können, müssen Sie den Variablennamen und in eckigen Klammern den Index (die &amp;quot;Nummer&amp;quot;) der Variablen angeben. Diese Variable verhält sich dann wie eine ganz normale Variable des jeweiligen Datentypes. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #define NZAHLEN 10&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int i;&lt;br /&gt;
    int zahlen[NZAHLEN];  {{comment|zahlen[0] ... zahlen[9]}}&lt;br /&gt;
  &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++)&lt;br /&gt;
    {&lt;br /&gt;
       printf (&amp;quot;Bitte Zahl %d eingeben: &amp;quot;, i);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; zahlen[i]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++) &lt;br /&gt;
       printf (&amp;quot;Zahl %d ist: %d\n&amp;quot;, i, zahlen[i]);&lt;br /&gt;
      &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 10 int-Variablen großes Array angelegt. &lt;br /&gt;
In dieses wird nun der Reihe nach 10 Zahlen eingelesen. &lt;br /&gt;
Anschließend werden alle 10 Zahlen ausgegeben. &lt;br /&gt;
&lt;br /&gt;
Dabei wird die Größe der Arrays und das Schleifenende über das Define &amp;quot;&amp;lt;tt&amp;gt;NZAHLEN&amp;lt;/tt&amp;gt;&amp;quot; angegeben. Dadurch muss nur ''eine Stelle'' im Code geändert werden, wenn die Größe des Arrays einmal einen anderer Wert als 10 haben soll &amp;amp;ndash; dies vermeidet Fehler die dadurch entstehen, wenn man beim Anpassen der Array-Größe eine Codestelle vergisst, zudem wird der Code lesbarer als wenn irgendwo die Zahl &amp;quot;10&amp;quot; auftaucht.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
:Wird ein ungültiger Index angeben (einer, der in der Deklaration nicht enthalten ist) können  undefinierte Dinge passieren, wenn dadurch andere Variableninhalte oder Programmcode überschrieben wird, der hinter oder vor dem Array im Speicher liegt. Schlimmstenfalls kann sogar der Computer/Controller abstürzen. Also darauf achten, daß keine ungültigen Werte als Index auftreten!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Strings (Zeichenketten)===&lt;br /&gt;
Ein String ist nichts anderes als ein Array, das aus einzelnen Zeichen (&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;) gebildet wird. Die Ausgabe auf dem Bildschirm funktioniert am einfachsten mittels Strings.&lt;br /&gt;
&lt;br /&gt;
Die Definition eines Strings erfolgt also genauso wie bei Arrays:&lt;br /&gt;
 char string[21];&lt;br /&gt;
&lt;br /&gt;
Nun haben Sie eine String, in dem Sie 21 Zeichen speichern können. Ganz richtig ist das jedoch nicht. C arbeitet mit &amp;quot;null-terminierten Strings&amp;quot;. Das beudeutet, dass die Länge des Strings nicht abgespeichert wird, sondern das Zeichen mit dem ASCII-Wert 0 das Stringende kennzeichnet. Daher auch die Bezeichnung  &amp;quot;null terminiert&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Das letzte Zeichen eines Strings muß daher immer das ASCII-Zeichen Nr. 0 sein. Ist es das nicht, hat der String kein definiertes Ende, und wenn Sie versuchen, ihn durch eine Standard-Funktion auszugeben zu lassen, könnte es eine Weile dauern, bis sich im Speicher zufällig irgendwo eine 0 befindet. Es stehen ihnen daher bei dem Beispiel nur 20 Zeichen zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
===Mehrdimensionale Arrays===&lt;br /&gt;
Manchmal benötigt man mehr als nur ein eindimensionales Array, wie Sie es bisher kennengelernt haben. Auch dies ist kein Problem. In der Deklaration geben Sie einfach mehrere eckige Klammern hintereinander an. Aber Vorsicht: der Speicherplatz ist begrenzt, ein &amp;quot;&amp;lt;tt&amp;gt;char feld[1024][1024]&amp;lt;/tt&amp;gt;&amp;quot; hat die Speicherplatzgrenzen vermutlich bereits weit überschritten, und der Compiler wird einen (bei gewissen Einstellung auch keinen) Fehler liefern.&lt;br /&gt;
Beim Zugriff auf mehrdimensionale Felder müssen auch mehrere Indizes angeben werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  int x,y;&lt;br /&gt;
  int feld[3][5];&lt;br /&gt;
 &lt;br /&gt;
  for (x=0; x&amp;lt;3; x++) &lt;br /&gt;
  {&lt;br /&gt;
     for (y=0; y&amp;lt;5; y++)&lt;br /&gt;
     {&lt;br /&gt;
       printf (&amp;quot;Feldwert x: %d,  y: %d &amp;quot;, x, y);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; feld[x][y]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  for(x=0; x&amp;lt;3; x++) &lt;br /&gt;
     for (y=0; y&amp;lt;5; y++) &lt;br /&gt;
        printf (&amp;quot;Wert: feld[%d][%d] = %d\n&amp;quot;, x, y, feld[x][y]);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 3 mal 5 &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array angelegt. &lt;br /&gt;
Dann werden die Werte eingegeben: zuerst &amp;lt;tt&amp;gt;feld[0][0]&amp;lt;/tt&amp;gt;, dann &amp;lt;tt&amp;gt;feld[0][1]&amp;lt;/tt&amp;gt;, usw. bis &amp;lt;tt&amp;gt;feld[2][4]&amp;lt;/tt&amp;gt;. &lt;br /&gt;
Zum Schluß werden alle Werte noch einmal ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===Strukturen===&lt;br /&gt;
In C können Sie sogenannte &amp;quot;Strukturen&amp;quot; definieren. Dabei handelt es sich um eine Zusammenfassung mehrerer Datentypen zu einem größeren. Im Unterschied zu Feldern können in Strukturen unterschiedliche Datentypen zusammengestellt und gespeichert werden: &lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 struct {{Bezeichner}}&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur 'Person'}}&lt;br /&gt;
 struct Person &lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;lt;tt&amp;gt;struct Person {&amp;lt;/tt&amp;gt;&amp;quot; leitet die Definition der Struktur mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;Person&amp;lt;/tt&amp;gt;&amp;quot; ein. &lt;br /&gt;
Dann werden in dieser Struktur fünf Komponenten definiert: drei Strings und zwei &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. &lt;br /&gt;
mit &amp;lt;tt&amp;gt;}&amp;lt;/tt&amp;gt; wird die Definition abgeschlossen. Sie haben damit einen Datentyp erstellt. Um eine Variable des Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach an&lt;br /&gt;
 struct Person {{Bezeichner}};&lt;br /&gt;
&lt;br /&gt;
Zum Zugriff auf eine Komponente der Struktur gibt man den Namen der Struktur-Variablen an (im folgenden Beispiel also &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;klaus&amp;lt;/tt&amp;gt;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
 {{comment|Definition zweier Struktur-Variablen}}&lt;br /&gt;
 struct Person hubert, klaus;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Zugriff auf Struktur-Komponenten}}&lt;br /&gt;
 hubert.alter = 32;&lt;br /&gt;
 klaus.alter = hubert.alter + 1;&lt;br /&gt;
&lt;br /&gt;
===Unions===&lt;br /&gt;
Eine Union wird ganz analog zu einer Struktur deklariert und verwendet. Sie unterscheidet sich von einer Struktur jedoch dadurch, daß ihre Elemente nicht nacheinander im Speicher abgelegt werden, sondern sich überlagern. Auf die in einer Union enthaltenen Daten gibt es also verschiedene Sichten: je nachdem, welche Sicht bzw. Interpretation der Daten man gerne hätte, wählt man den gewünschten Zugriff.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
union Daten &lt;br /&gt;
{&lt;br /&gt;
   int id;&lt;br /&gt;
&lt;br /&gt;
   struct Person u_person;&lt;br /&gt;
&lt;br /&gt;
   struct u_double&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      double wert;&lt;br /&gt;
   };&lt;br /&gt;
&lt;br /&gt;
   struct u_pointer&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      union Daten * p1;&lt;br /&gt;
      union Daten * p2;&lt;br /&gt;
   };&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
union Daten data;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies definiert eine Union mit den vier Zugriffsmöglichkeiten &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_double&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Größe der Union richtet sich dabei nach der grössten Komponente. In diesem Beispiel sind alle Komponenten so angelegt worden, daß sie an erster Stelle ein &amp;lt;tt&amp;gt;int id&amp;lt;/tt&amp;gt; enthalten. In &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; könnte man sich also merken, wie die Daten in der Union zu interpretieren sind. Würde &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; nicht dieses &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; enthalten, so würde sich &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; mit &amp;lt;tt&amp;gt;data.u_person.vname&amp;lt;/tt&amp;gt; überlagern. Ein Ändern der ersten Buchstaben von &amp;lt;tt&amp;gt;vname&amp;lt;/tt&amp;gt; hätte also ein Ändern von &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; zur Folge, und man könnte es nicht mehr als Merker verwenden. Mit diesem Feld überlagert das &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; die &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;-Felder der anderen Sichten, z.B. ist &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; der selbe Zugriff wie auf &amp;lt;tt&amp;gt;data.u_person.id&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein anderes Beispiel ist eine Union, die es ermöglicht, auf die einzelnen Bytes eines &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; zuzugreifen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef union&lt;br /&gt;
{&lt;br /&gt;
   unsigned long  as_long;&lt;br /&gt;
   unsignen short as_short[2];&lt;br /&gt;
   unsignen char  as_byte[4];&lt;br /&gt;
} data32_t;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies überlagert einen &amp;lt;tt&amp;gt;unsigned long&amp;lt;/tt&amp;gt; &amp;amp;ndash; also eine 32-Bit-Zahl &amp;amp;ndash; mit vier Bytes bzw. zwei Shorts.&lt;br /&gt;
 data32_t wert;&lt;br /&gt;
 &lt;br /&gt;
 wert.as_long = 0x12345678;&lt;br /&gt;
 wert.as_byte[0] = 0xab;&lt;br /&gt;
 {{comment|nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform)}}&lt;br /&gt;
&lt;br /&gt;
==Eigene Datentypen==&lt;br /&gt;
&lt;br /&gt;
=Variablen=&lt;br /&gt;
Eine Variable ist ein Synonym (=anderer Name) für eine Speicherstelle in einem Computer. Einfacher gesagt, eine Variable bietet Raum, um Daten wie Zahlen oder Zeichen zu speichern und wieder zu lesen.&lt;br /&gt;
&lt;br /&gt;
==Variablennamen==&lt;br /&gt;
Ein Variablenname kann zusammengesetzt werden aus den Buchstaben &amp;lt;tt&amp;gt;'''A'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''Z'''&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;'''a'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''z'''&amp;lt;/tt&amp;gt;, den Ziffern &amp;lt;tt&amp;gt;'''0'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''9'''&amp;lt;/tt&amp;gt;, sowie dem Sonderzeichen &amp;quot;Unterstrich&amp;quot; (underscore) &amp;lt;tt&amp;gt;'''_'''&amp;lt;/tt&amp;gt;. Dabei darf an erster Stelle keine Ziffer stehen. Die Bezeichner &amp;lt;tt&amp;gt;hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALLO&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALL0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;_123&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_HALLO&amp;lt;/tt&amp;gt; sind also alle gültige und unterschiedliche Variablennamen.&lt;br /&gt;
&lt;br /&gt;
==Anlegen von Variablen==&lt;br /&gt;
Um eine Variable verwenden zu können, muss sie zuerst vereinbart (&amp;quot;erzeugt&amp;quot;) werden. Dies wird auch als &amp;quot;''Definition der Variablen''&amp;quot; bezeichnet und geht so: Schreiben Sie zuerst den Datentyp, dann den Namen der Variablen. Zum Schluß kommt noch der Strichpunkt, wie nach jeder C-Anweisung oder Deklaration. Und nicht vergessen: C unterscheidet zwischen  Groß- und Kleinschreibung! &lt;br /&gt;
 int Zahl1, Zahl2;&lt;br /&gt;
 char Zeichen;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    float gleitZahl;&lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:'''&lt;br /&gt;
In einer Zeile können auch mehrere Variablen gleichen Types vereinbart werden, wenn man ein Komma dazwischen setzt. Variablen können in jedem Block vereinbart werden. Siehe [[#Gültigkeitsbereich|Gültigkeitsbereich]].&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen==&lt;br /&gt;
Man kann einer vereinbarten Variable Werte [[#Zuweisungen|zuweisen]]. Dazu schreibt man zuerst den Variablennamen, ein Gleichheitszeichen &amp;quot;&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;&amp;quot; und anschliessend den zuzuweisenden [[#Ausdrücke|Ausdruck]]. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, zahl2 = 12;&lt;br /&gt;
  char zeichen1 = 'A';&lt;br /&gt;
&lt;br /&gt;
  zahl1 = 52;&lt;br /&gt;
  zeichen1 = zeichen1 + 1; &lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Zuerst werden drei Variablen angelegt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;: wird gleich bei der Vereinbarung der Wert 12 zugewiesen. &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl1 = 52&amp;lt;/tt&amp;gt;: Hier wird der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; der Wert 52 zugewiesen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;: wird um 1 erhöht. Da in der Variablen &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; gespeichert ist, gibt sich ihr neuer Wert aus &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt;. Weil &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; dem Wert 65 entspricht, ist &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt; gleich 66, was dem Wert für &amp;lt;tt&amp;gt;'B'&amp;lt;/tt&amp;gt; entspricht.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei float==&lt;br /&gt;
Das funktioniert genau wie bei normale Zuweisungen. Nachkommastellen werden durch einen Punkt abgegrenzt: &lt;br /&gt;
 floatVariable = 3.14;&lt;br /&gt;
Zusätzlich kann eine Zehnerpotenz angegeben werden:&lt;br /&gt;
 floatVariable2 = -1.234E-6;&lt;br /&gt;
Dadurch wird der erst Wert mit 10&amp;lt;sup&amp;gt;&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;6&amp;lt;/sup&amp;gt; multipliziert, der Wert der Variablen ist also &lt;br /&gt;
:&amp;lt;math&amp;gt;-1{,}234\cdot10^{-6} = -0.000001234&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei logischen Variablen==&lt;br /&gt;
Wie bereits erwähnt, besitzt C keinen logischen Datentyp. Es müssen also &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; dafür genutzt werden. Die Zuweisung entpricht der Standard-Zuweisung. Wird der Wert 0 zugewiesen, dann ist die Variable &amp;quot;unwahr&amp;quot;, ansonsten ist sie &amp;quot;wahr&amp;quot;. &lt;br /&gt;
 intVariable = !0;   /* entspricht &amp;quot;wahr&amp;quot;   */&lt;br /&gt;
 intVariable = 0;    /* entspricht &amp;quot;unwahr&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
==Konstanten==&lt;br /&gt;
Konstanten können als Variable angesehen werden, die nicht beschrieben, sondern nur gelesen werden können. Ein typisches Beispiel dafür ist die Zahl &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; (rund 3,141592654). Niemand würde in der realen Welt versuchen, ihr einen anderen Wert zuzuweisen. Würde man &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; jedoch wie eine normale Variable anlegen, wäre dies ohne weiteres möglich. Um dies zu verhindern, gibt es das Schlüsselwort &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in C:&lt;br /&gt;
 const {{Type}} {{Bezeichner}} = {{Konstante}};  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Wichtig dabei ist, dass man Konstanten nur bei der Vereinbarung einen Wert zuweisen kann. &lt;br /&gt;
Da Konstanten gewöhnlich im gesamten Programm, zumindest einer Quelldatei genutzt werden, definiert man diese allerdings gewöhnlich außerhalb des main-Blockes entweder am Anfang eines Programmes, oder in einer sogenannten Header-Datei, die per &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; eingebunden wird.&lt;br /&gt;
 const float PI = 3.141592;  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Es sei jedoch erwähnt, daß auch einer Konstanten nachträglich ein anderer Wert zugewieden werden kann. Im obigen Beispiel könnte mit&lt;br /&gt;
 * ((float*) &amp;amp;PI) = 2;&lt;br /&gt;
der Wert von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; im Nachhinein verändert werden. Es wird die Adresse von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; genommen und diese Adresse durch den Cast in eine ganz normale &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;-Adresse umgewandelt, über welche der Wert geändert wird. Die sei der Vollständigkeit halber erwähnt.&lt;br /&gt;
&lt;br /&gt;
Je nachdem, an welcher Stelle sich das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; bei einer Pointer-Deklaration befindet, markiert es den Pointer als konstant oder das Objekt, auf das dieser Pointer zeigt. Eine häufige Parameterdeklaration in Ausgabe-Funktionen, die einen String erhalten, ist&lt;br /&gt;
 void foo (const char * str, ...);&lt;br /&gt;
Dadurch ist &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; der Zeiger auf eine Zeichenkette, die innerhalt der Funktion nicht verändert wird bzw. verändert werden darf. Eine Zuweisung wie &amp;lt;tt&amp;gt;*str = 'a'&amp;lt;/tt&amp;gt; ergibt also einen Fehler. &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; selbst kann aber sehr wohl verändert werden, etwa mit &amp;lt;tt&amp;gt;str++&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Soll ausgedrückt werden, daß &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; unveränderlich ist, dann so:&lt;br /&gt;
 void foo (char * const str, ...);&lt;br /&gt;
Jetzt wäre eine Änderung des Strings in Ordnung, etwa durch &amp;lt;tt&amp;gt;str[10] = 'a'&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Um sich zu merken, worauf das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; wirkt, trennt man die Deklaration in Gedanken beim&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf: Steht das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; links vom&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, dann gehört es zum &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, steht es rechts davon, dann gehört es zum Pointer. Natürlich ist es auch denkbar, beides &amp;amp;ndash; also den Zeiger und sein Ziel &amp;amp;ndash; als konstant zu markieren.&lt;br /&gt;
&lt;br /&gt;
==Gültigkeitsbereich==&lt;br /&gt;
In C können mehrere Variablen den gleichen Namen haben, solange eindeutig ist, welche in welchen Block gültig ist. Dabei gelten folgende Regeln: &lt;br /&gt;
&lt;br /&gt;
;Lokale Variablen: sind Variablen, die innerhalb eines Blockes definiert werden. Jede Variable ist nur in dem Block gültig, in dem sie vereinbart wurde, sowie in allen darin enthaltenen Blöcken; es sei denn, in einem Unter-Block wird eine Variable gleichen Namens definiert. Dann bezieht sich in diesem Unter-Block der Bezeichner auf die im Unter-Block angelegte Variable.&lt;br /&gt;
;Globale Variablen: werden ausserhalb jedes Blockes definiert und gelten ab der Stelle, an der sie deklariert werden, siehe auch [[#Deklaration und Definition|Deklaration und Definition]]. Wird jedoch in einem Block eine Variable gleichen Namens angelegt, gilt ab hier bis zum Ende des Blocks nicht mehr die globale Variable, sondern die im Block deklarierte. Das Spiel kann man weiterspielen: wird in einem Unter-Block wieder eine namensgleiche Variable angelegt, gilt diese in dem Unterblock.&lt;br /&gt;
&lt;br /&gt;
==Speicherklassen==&lt;br /&gt;
Jede Variable in C gehört zu einer bestimmten Speicherklasse&lt;br /&gt;
;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;: Lokale Variablen sind in aller Regal sogenannte ''automatische Variablen''. Das bedeutet, sie werden automatisch angelegt, wenn ein Block bzw. eine Funktion betreten wird und danach wieder entfernt. Das Schlüsselwort &amp;quot;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;&amp;quot; wird praktisch nie hingeschrieben, denn lokale Variablen ohne die ausdrückliche Angabe einer Speicherklasse, sind automatisch automatische Variablen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;: Eine externes Symbol ist im ganzen Programm bekannt bzw. in dem Block, in der die Deklaration steht. In unterschiedlichen Blöcken stehende Deklarationen beziehen sich auf das gleiche Symbol! Obgleich das Datum global zugreifbar ist, ist der Gültigkeitsbereich auf den deklarierenden Block begrenzt bzw. auf das deklarierende Quell-Modul, sofern das Symbol ausserhalb jedes Blocks des Moduls deklariert wird. Siehe auch [[#Deklaration und Definition|Deklaration und Definition]].&lt;br /&gt;
;&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;: Die Variable ist im Block gültig bzw. im Quell-Modul (also in der C-Datei, in der die angelegt wurde), wenn sie nicht innerhalb eines Blockes angelegt wurde. Statische Variablen werden nicht in Registern oder im Frame der Funktion angelegt, sondern im selben Speicherbereich, in dem auch die globalen Variablen liegen; Konstanten evtl. auch im Flash. Eine lokale Variable, die als &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; angelegt wird, &amp;quot;überlebt&amp;quot; also das Verlassen des Blocks und hat beim neuerlichen Betreten des Blockes ihren bisherigen Wert. In unterschiedlichen Blöcken angelegte lokale statische Variablen beziehen sich auf unterschiedliche Speicherstellen, genau wie bei lokalen Variablen auch.&lt;br /&gt;
;&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;: Durch diese Speicherklasse wird eine Variable &amp;amp;ndash; falls möglich &amp;amp;ndash; als Registervariable angelegt, also in einem Maschinenregister des Computer/Controllers gehalten. Dadurch kann auf solche Variablen besonders schnell zugegriffen werden. Dieses Schlüsselwort ist bei modernen Compilern weitgehend überflüssig, da die entsprechenden Optimierungen selbständig vorgenommen werden, wenn ausreichend Register vorhanden sind. Auch globale Variablen können als Register angelegt werden, davon ist dem Anfänger aber dringend abzuraten, weil leicht schwerauffindbare Fehler und Abstürze auftreten, wenn man nicht genau weiss, welche Implikationen in einer solchen Definition stecken!&lt;br /&gt;
;&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;: (FIXME: volatile ist ein Qualifier und keine Speicherklasse) Dies ist das genaue Gegenteil von &amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt; und bewirkt, dass die Variable auf keinen Fall in einem Register zwischengespeichert werden darf, sondern immer aus dem RAM gelesen und ins RAM geschrieben werden soll. &amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt; müssen alle ''globalen'' Variablen markiert werden, die in [[ISR | Interrupt-Handlern]] verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Ausdrücke=&lt;br /&gt;
Eine Variable oder eine Konstante in C stellen einfache Ausdrücke dar.&lt;br /&gt;
Diese elementaren Ausdrücke können durch Operatoren miteinander verknüpft werden und so zu neuen, komplexeren Ausdrücken zusammen gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Einfache Beispiele für Ausdrücke sind also z.B.:&lt;br /&gt;
 1&lt;br /&gt;
 a&lt;br /&gt;
 'a'&lt;br /&gt;
 1 + a&lt;br /&gt;
 a == 1&lt;br /&gt;
&lt;br /&gt;
Auch Funktionen können einen Wert zurückliefern und in Ausdrücken weiter benutzt werden.&lt;br /&gt;
In den folgenden Abschnitten wird gezeigt, welche Operatoren in C vorhanden sind,&lt;br /&gt;
und wei man damit neue Ausdrücke aufbauen kann.&lt;br /&gt;
&lt;br /&gt;
==Lvalues==&lt;br /&gt;
&lt;br /&gt;
Ein Lvalue in C ist ein Ausdruck, dem ein anderer Ausdruck zugewiesen werden kann, dessen Wert also durch eine Zuweisung verändert werden kann.&lt;br /&gt;
das 'L' leitet sich ab von 'left' bwz. 'links' und das 'value' bedeutet Wert: Ein Lvalue ist ein Ausdruck, der auf der linken Seite einer Zuweisung stehen darf. Ein Lvalue ist also immer auch ein gültiger Ausdruck, aber die Umkehrung gilt in alles Regel nicht.&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für einen Lvalue ist eine &amp;quot;normale&amp;quot; Variable, die nicht mit &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; als Konstante markiert ist:&lt;br /&gt;
 a = 1;&lt;br /&gt;
Hingegen ist der Ausdruck &amp;lt;tt&amp;gt;a+1&amp;lt;/tt&amp;gt; kein Lvalue, denn eine Zuweisung wie&lt;br /&gt;
 a+1 = 2;&lt;br /&gt;
die mathematisch durchaus sinnvoll ist, erzeugt einen Compilerfehler, der etwa lauten könnte &amp;quot;illegal lvalue in assignment&amp;quot;:&lt;br /&gt;
&amp;quot;ungültiger Wert in Zuweisung&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Andere Beipiele für Lvalues sind die Komponenten von (nicht-konstanten) [[#Strukturen|Strukturen]] und [[#Unions|Unions]], [[#Arrays|Array]]-Elemente und die Dereferenzierungen von Pointern: Die Konstante&amp;amp;nbsp;4 wird durch den Cast in eine Adresse umgewandelt. Über die Dereferenzierung&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; wird an die Adresse&amp;amp;nbsp;4 im Speicher eine&amp;amp;nbsp;3 geschrieben. Ob das erlaubt bzw. sinnvoll ist, ist abhängig von der jeweiligen Architektur.&lt;br /&gt;
 * ((unsigned int *) 4) = 3;&lt;br /&gt;
Hier ist der gesamte &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;-Ausdruck ein Lvalue&lt;br /&gt;
&lt;br /&gt;
==Logische (boolsche) Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp;amp;&amp;amp;amp; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr oder &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; || gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; || ungleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;= b&amp;lt;/tt&amp;gt; || kleiner oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt; b&amp;lt;/tt&amp;gt; || kleiner als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt;= b&amp;lt;/tt&amp;gt; || glösser oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt; b&amp;lt;/tt&amp;gt; || grösser als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; nicht wahr und vice versa&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine interessante Eigenschaft der Operatoren &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;amp;amp;&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; ist, dass&lt;br /&gt;
sie die Auswertung abbrechen, sobald das Ergebnis feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet. Ein oft anzutreffendes Codestück sieht so aus, dabei sei &amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
  if (p &amp;amp;&amp;amp; *p == 5)&lt;br /&gt;
  {&lt;br /&gt;
     {{comment|mach was}}&lt;br /&gt;
  }&lt;br /&gt;
Zuerst wird in der Bedinung geprüft, ob Zeiger&amp;amp;nbsp;&amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; einen Wert ungleich Null hat, also ob er überhaupt einen gültigen Wert enthält. Es ist weit verbreitete Konvention in C, daß Zeiger, die keinen gültigen Wert haben, die Adresse&amp;amp;nbsp;0 enthalten. '''Nur dann, wenn ein Zeiger nicht ein Null-Pointer ist, darf überhaupt ein Zugriff über ihn erfolgen!'''&lt;br /&gt;
&lt;br /&gt;
==Vergleich von Variablen==&lt;br /&gt;
Skalare Variablen (also ganze Zahlen, Gleitkommazahlen, Zeiger) können miteinander verglichen werden. Dazu gibt es die folgenden Operatoren in C: &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; || ist nicht gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;=&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;=&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das Ergebnis der Auswertung ist eine ganze Zahl. Ist die Bedingung erfüllt, dann ist der Wert ungleich&amp;amp;nbsp;0. Ist die Bedingung nicht erfüllt, dann ist ihr Wert gleich&amp;amp;nbsp;0.&lt;br /&gt;
Meistens wird man diese Operatoren in &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Konstrukten finden wie zum Beispiel&lt;br /&gt;
 if (x &amp;gt;= 10)&lt;br /&gt;
    x = 10;&lt;br /&gt;
oder in Abbruchbedingungen von Schleifen, wie sie weiter unten erklärt werden.&lt;br /&gt;
&lt;br /&gt;
Es ist auch möglich, das Ergebnis der Auswertung in einer &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Variablen zu speichern:&lt;br /&gt;
 int i;&lt;br /&gt;
 int z1, z2;&lt;br /&gt;
 &lt;br /&gt;
 z1 = 5;&lt;br /&gt;
 z2 = 100;&lt;br /&gt;
 i = z1 &amp;lt;= z2;  {{comment|Ein Vergleich. i wird &amp;quot;wahr&amp;quot;, da z1 kleinergleich z2 ist}}&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich&amp;amp;nbsp;0 (&amp;quot;wahr&amp;quot;), wenn &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; kleiner oder gleich &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt; ist. Ist &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; jedoch größer als &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt;, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich&amp;amp;nbsp;0 (&amp;quot;unwahr&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
==Arithmetische Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a + b&amp;lt;/tt&amp;gt; || Summe (Addition)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a - b&amp;lt;/tt&amp;gt; || Differenz (Subtraktion)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a * b&amp;lt;/tt&amp;gt; || Produkt (Multiplikation)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a / b&amp;lt;/tt&amp;gt; || Quotient (Division, evtl. mit Rest)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a % b&amp;lt;/tt&amp;gt; || Rest bei Division (Modulo)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;-a&amp;lt;/tt&amp;gt; || Vorzeichenumkehr (Zweierkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Bit-Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp; b&amp;lt;/tt&amp;gt; || bitweise und (and)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || bitweise oder (or)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a ^ b&amp;lt;/tt&amp;gt; || bitweise exclusiv-oder (xor, exor)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;~a&amp;lt;/tt&amp;gt; || jedes Bit in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; invertieren (not, Einerkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Index-Operator bei Arrays==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a[b]&amp;lt;/tt&amp;gt; || das (b+1)ste Element des Feldes a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Folgendes gilt es bei der Verwendung des Indexoperators zu beachten:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; muss ein [[C-Tutorial#Felder | Feld]] oder [[C-Tutorial#Zeiger | Zeiger]] sein&lt;br /&gt;
# &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; muss ein Integer sein oder ein Datentyp, der sich in einen int umwandeln läßt (z.B. char)&lt;br /&gt;
# Es wird nicht geprüft, ob der Index &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; im Feld &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gültig ist!&lt;br /&gt;
# Der erste Index eines Feldes ist immer 0. Daher ''(b+1)stes Element'' in der Beschreibung&lt;br /&gt;
&lt;br /&gt;
==Komponenten-Auswahl bei Structs und Unions==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a.b&amp;lt;/tt&amp;gt; || Element b der [[C-Tutorial#Strukturen | Struktur]] oder des Unions a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adress-Operator und Dereferenzierung==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&amp;amp;amp;a&amp;lt;/tt&amp;gt; || Speicheradresse der Variablen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;*a&amp;lt;/tt&amp;gt; || Wert, der an der Adresse &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a-&amp;amp;gt;b&amp;lt;/tt&amp;gt; || Wert des Elements &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; der Struktur, deren Adresse in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Adressoperator &amp;amp; kann auf Variablen angewendet werden und&lt;br /&gt;
gibt die Startadresse der Variablen im Speicher zurück.&lt;br /&gt;
&lt;br /&gt;
Handelt es sich bei einer Variable um einen [[C-Tutorial#Zeiger | Zeiger]], so enthält&lt;br /&gt;
sie eine Speicheradresse. Um an den '''Wert''' zu gelangen, der&lt;br /&gt;
an dieser Adresse steht, wird der Operator * vorangestellt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
&lt;br /&gt;
 {{comment|x ist eine Integervariable und hat den Wert 5}}&lt;br /&gt;
 int x = 5;&lt;br /&gt;
     &lt;br /&gt;
 {{comment|z ist ein Zeiger auf eine Integer-Variable und enthaelt somit}}&lt;br /&gt;
 {{comment|die Speicheradresse einer Integer-Variablen}}&lt;br /&gt;
 int *z;       &lt;br /&gt;
  &lt;br /&gt;
 {{comment|Verwendung des Adress-Operators: weist an z die Adresse von x zu}}&lt;br /&gt;
 z = &amp;amp;x;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Verwendung der Dereferenzierung}}&lt;br /&gt;
 {{comment|erhoehe den Wert, der bei Adresse z steht, um eins}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|da z auf x zeigt, hat x jetzt den Wert 6}}&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff auf Struktir- und Union-Elemente eine abkürzende Schreibweise möglich:&lt;br /&gt;
&lt;br /&gt;
Statt &lt;br /&gt;
  (*strukturZeiger).element&lt;br /&gt;
kann geschrieben werden&lt;br /&gt;
  strukturZeiger-&amp;gt;element&lt;br /&gt;
Beide Schreibweisen sind absolut gleichbedeutend, die Klammern bei der ersteren sind notwendig.&lt;br /&gt;
&lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
:Bei der Dereferenzierung durch &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; findet keine Prüfung statt, ob der Zeiger auch auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu einer Änderung '''irgendeiner''' Speicherstelle!&lt;br /&gt;
&lt;br /&gt;
 int *z; {{comment|z ist ein Zeiger auf einen int}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.}}&lt;br /&gt;
 {{comment|z enthaelt irgendeine ungueltige Adresse!!}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|&amp;quot;Erhoehe einen Integer _irgendwo_ im Speicher um 1&amp;quot; -&amp;gt; CRASH !!!}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
&lt;br /&gt;
==Cast-Operator==&lt;br /&gt;
&lt;br /&gt;
Der Cast Operator dient dazu, den Datentyp eines Wertes zu ändern. Dafür wird einfach der neue Datentyp in Klammern vor den Wert geschrieben.&lt;br /&gt;
&lt;br /&gt;
Um zum Beispiel aus einem Float ein Integer zu machen:&lt;br /&gt;
 var  = (int) 5.60;&lt;br /&gt;
Dabei wird der Wert aber auch gerundet, und es findet somit ein Informationsverlust statt.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Umwandeln einer ganzen Zahl in eine Adresse:&lt;br /&gt;
 int * addr;&lt;br /&gt;
 addr = (int*) 0x1234;&lt;br /&gt;
Damit ist &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; an Adresse 0x1234.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
Der Cast-Operator selbst führt ''keine Konvertierung'' von Darstellungen durch, etwa die Umwandlung der ganzen Zahl 123 ein den String &amp;lt;tt&amp;gt;&amp;quot;123&amp;quot;&amp;lt;/tt&amp;gt;, der diese Zahl darstellt! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
  int main(int argc, char ** argv)&lt;br /&gt;
  {&lt;br /&gt;
        char text[] = &amp;quot;5.6&amp;quot;;&lt;br /&gt;
        int zahl = (int) text;&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, zahl);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Anfangsadresse des Strings &amp;lt;tt&amp;gt;&amp;quot;5.6&amp;quot;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Komma-Operator==&lt;br /&gt;
Mit einem &amp;lt;tt&amp;gt;,&amp;lt;/tt&amp;gt; können mehrere Ausdrücke nacheinander ausgewertet werden.&lt;br /&gt;
Die Auswertung erfolgt von links nach rechts.&lt;br /&gt;
&lt;br /&gt;
Solche Konstrukte sieht man manchmal in Abfragen wie&lt;br /&gt;
 FILE  *file;&lt;br /&gt;
 if (file = fopen (&amp;quot;foo.exe&amp;quot;, &amp;quot;r&amp;quot;), file != NULL)&lt;br /&gt;
was erst an &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; einen Wert zuweist und den &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Block nur betritt,&lt;br /&gt;
wenn &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; nicht der Nullpointer ist.&lt;br /&gt;
&lt;br /&gt;
Bequem kann das auch in einer [[#for-Schleife|for-Schleife]] sein, wenn man zwei (oder mehr) Laufvariablen hat oder so:&lt;br /&gt;
 for (i=0, j=0; i &amp;lt; 10; i++, j += 2)&lt;br /&gt;
    &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Zuweisung===&lt;br /&gt;
=== ++ und -- ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; stellen einfachere Schreibweisen dar zum Addieren bzw. Subtrahieren von&amp;amp;nbsp;1.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; (Inkrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo++; &lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo + 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; 3}}&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; (Dekrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo--;&lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo - 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; -1}}&lt;br /&gt;
&lt;br /&gt;
Die beiden Operatoren können sowohl in der Präfix-Schreibweise (vor der Variablen) als auch als Postfix-Schreibweise (hinter der Variablen) notiert werden. &lt;br /&gt;
Der Unterschied liegt darin, dass beim Präfix der Wert zuerst neu berechnet wird und die Variable dann verwendet wird. Beim Postfix wird die Variable zuerst verwendet und erst nach Auswertung des Ausdrucks, in dem sie enthalten ist, neu berechnet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 int ausgabe1, ausgabe2, var1 = 10, var2 = 10;&lt;br /&gt;
 ausgabe1 = 3 * ++var1; {{comment|ausgabe1 &amp;amp;#61; 33; var1 &amp;amp;#61; 11;}}&lt;br /&gt;
 ausgabe2 = 3 * var2++; {{comment|ausgabe2 &amp;amp;#61; 30; var2 &amp;amp;#61; 11;}}&lt;br /&gt;
&lt;br /&gt;
Für Zeiger arbeiten diese Operatoren etwas anders, siehe dazu [[#Zeiger-Arithmetik|Zeiger-Arithmetik]].&lt;br /&gt;
&lt;br /&gt;
===Bedingter Ausdruck===&lt;br /&gt;
 ({{Bedingung}}) ? {{Ausdruck|1}} : {{Ausdruck|2}}&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; erfüllt ist, dann wertet dieser Ausdruck aus zu &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt;. Ist er nicht erfüllt, dann wertet er aus zu &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 x = (x &amp;gt;= 3) ? 0 : x+1;&lt;br /&gt;
Startet man &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; mit dem Wert 0, dann nimmt es bei mehrfacher Anwendung dieser Zeile (z.B. in einer Schleife) nacheinander die folgende Werte an:&lt;br /&gt;
:&amp;lt;tt&amp;gt;1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, ...&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Priorität ||Operator||Assoziativität&lt;br /&gt;
|-&lt;br /&gt;
  &lt;br /&gt;
|&amp;lt;tt&amp;gt;15&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; ( ) [ ] -&amp;gt; . &amp;lt;/code&amp;gt;                      ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;14&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; ! ~ ++ -- + - (TYP) * &amp;amp; sizeof &amp;lt;/code&amp;gt;    ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;13&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; * / % (Rechenoperationen) &amp;lt;/code&amp;gt;         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;12&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; + - (binär) &amp;lt;/code&amp;gt;                       ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;11&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; &amp;lt;&amp;lt; &amp;gt;&amp;gt; &amp;lt;/code&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;10&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; &amp;lt; &amp;lt;= &amp;gt; &amp;gt;= &amp;lt;/code&amp;gt;                         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 9&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; == != &amp;lt;/code&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 8&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; &amp;amp; (AND-Operator)&amp;lt;/code&amp;gt;                   ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 7&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; ^ (XOR-Operator)&amp;lt;/code&amp;gt;                   ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 6&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; (OR-Operator)&amp;lt;/code&amp;gt;   ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 5&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; &amp;amp;&amp;amp; &amp;lt;/code&amp;gt;                                ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 4&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; &amp;lt;/code&amp;gt;               ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 3&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; ?: &amp;lt;/code&amp;gt;                                ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 2&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; = += -= /= *= %= &amp;gt;&amp;gt;= &amp;lt;&amp;lt;= &amp;amp;= |= ^= &amp;lt;/code&amp;gt; ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 1&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; , (Sequenz-Operator) &amp;lt;/code&amp;gt;              ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
Eine Kontrollanweisung ist eine Anweisung, die Einfluss auf den Programmfluss hat. Normalerweise werden Anweisungen so ausgeführt, wie sie in der Quelldatei stehen: Von links nach rechts (falls mehrere Anweisungen in einer Zeile stehen sollten, wovon i.A. abzuraten ist) und von oben nach unten. Mit einer Kontrollanweisung kann dieser lineare Programmfluss durchbrochen werden: Die Codeausführung kann kann abhängig von einer Bedingung gemacht werden (&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;), kann wiederholt werden (Schleife) oder an einer anderen Stelle der Funktion fortgesetzt werden (&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==if-Anweisung==&lt;br /&gt;
Mit Hilfe des if-Befehls kann man Codeteile abhängig davon einer Bedingung ausführen lassen:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
oder mit else-Teil&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 if (x &amp;gt; 100)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;gt; 100 ist: Fehlerausgabe}}&lt;br /&gt;
    printf (&amp;quot;x = %d ist zu gross fuer die Berechnung!\n&amp;quot;, x);&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;lt;&amp;amp;#61; 100 ist: Berechne Summe der Zahlen 1...x}}&lt;br /&gt;
    {{comment|Die lokale Variable x2 lebt nur innerhalb dieses alse-Blocks}}&lt;br /&gt;
    int x2 = x;&lt;br /&gt;
 &lt;br /&gt;
    for (x = 0; x2 &amp;gt; 0; x2--)&lt;br /&gt;
       x += x2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Wenn die Bedingung wahr ist (&amp;lt;tt&amp;gt;x &amp;gt; 100&amp;lt;/tt&amp;gt;), dann wird eine Meldung ausgegeben; danach ist die if-Anweisung beendet. Der else-Block wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung nicht erfüllt (&amp;lt;tt&amp;gt;x &amp;amp;le; 100&amp;lt;/tt&amp;gt;), dann wird gleich zum else-Teil gesprungen, und nach dessen Ausführung der if-Befehl beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Ein häufiger Fehler ist es, statt &amp;lt;tt&amp;gt;if (a &amp;amp;#61;&amp;amp;#61; 23)&amp;lt;/tt&amp;gt; etwas wie &amp;lt;tt&amp;gt;if (a &amp;amp;#61; 23)&amp;lt;/tt&amp;gt; zu schreiben. &lt;br /&gt;
Dann wird allerdings nicht geprüft, ob die Variable&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gleich 23 ist, sondern der Variablen&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wird der Wert 23 zugewiesen. Der Ausdruck &amp;lt;tt&amp;gt;a &amp;amp;#61; 23&amp;lt;/tt&amp;gt; hat den Wert&amp;amp;nbsp;23 und ist damit immer &amp;quot;wahr&amp;quot;! Daher ist diese if-Bedingung immer erfüllt!&lt;br /&gt;
&lt;br /&gt;
Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken sondern bestenfalls eine Warnung. Damit ist dieser Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise &amp;lt;tt&amp;gt;if (23 &amp;amp;#61;&amp;amp;#61; a)&amp;lt;/tt&amp;gt;. Wenn man dort anstatt des Vergleichsoperators '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;amp;#61;&amp;lt;/tt&amp;gt;' den Zuweisungsoperator '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;lt;/tt&amp;gt;' verwendet, spuckt der Compiler sehr wohl einen Fehler aus! Ist die Zuweisung jedoch erwünscht und eine Compiler-Warnung lästig, dann wählt man eine Schreibweise wie &amp;lt;tt&amp;gt;if ((a &amp;amp;#61; b))&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;if (a &amp;amp;#61; b, a)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist zu schreiben &amp;lt;tt&amp;gt;if (Bedingung);&amp;lt;/tt&amp;gt; Richtig muss es heissen &amp;quot;&amp;lt;tt&amp;gt;if(Bedingung)&amp;lt;/tt&amp;gt;&amp;quot; Das Semikolon im ersten Fall ist eine leere Anweisung, die im if-Falle ausgeführt wird &amp;amp;ndash; sie bleibt also ohne Resultet. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt; ein auf das Semikolon folgende Anweisung die eigentlich zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören soll wird immer ausgeführt, die sie nicht mehr zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; dazu gehört.&lt;br /&gt;
}}&lt;br /&gt;
Bei verschachtelten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Konstrukten gehört ein &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zu letzten &amp;quot;freien&amp;quot; &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;. Soll in einer &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Folge das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zum ersten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören, dann ist das so zu hinzuschreiben:&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Ohne die geschweiften Klammern um das zweite &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehörte das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; dort hinzu.&lt;br /&gt;
&lt;br /&gt;
==switch-Anweisung==&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
&lt;br /&gt;
 switch ({{Ausdruck|}}) &lt;br /&gt;
 {&lt;br /&gt;
     case konstante1:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
    &lt;br /&gt;
     case konstante2:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 &lt;br /&gt;
     {{comment|weitere case-Marken}}&lt;br /&gt;
 &lt;br /&gt;
     default:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 } {{comment|Ende von switch}} &lt;br /&gt;
&lt;br /&gt;
Der Ausdruck muss ein skalarer Typ sein, er wird in die nächste ganze Zahl gewandelt und mit den Werten hinter den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Marken verglichen. Bei einer Übereinstimmung werden alle Befehle ab dem zutreffenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; ausgeführt. Stimmt der Ausdruck mit keinem der Werte überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt falls vorhanden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der nachfolgenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;- und des &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitts werden ausgeführt, wenn die Anweisungen des &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitts nicht mit dem Befehl &amp;lt;tt&amp;gt;break;&amp;lt;/tt&amp;gt; beendet werden!&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es dürfen beliebig viele &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitte angegeben werden, pro Vergleichswert jedoch nur einer.&lt;br /&gt;
Der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ist optional. Die Reihenfolge, in der &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt; angegeben werden, ist unerheblich.&lt;br /&gt;
&lt;br /&gt;
==Schleifen==&lt;br /&gt;
Um Anweisungen mehrmals hintereinander auszuführen, benötigt man Schleifen. Diese führen Anweisungen aus, bis oder solange Bedingungen erfüllt sind.&amp;lt;br&amp;gt; &lt;br /&gt;
Wichtig ist also, ob die Bedingung '''vor''' oder '''nach''' den Schleifen-Anweisungen geprüft wird. &lt;br /&gt;
&lt;br /&gt;
===while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 while ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Die while-Schleife wird solange durchlaufen, wie die Bedingung erfüllt ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Die Anweisung kann natürlich auch ein Block sein, der aus mehreren Deklarationen und Anweisungen besteht. &lt;br /&gt;
&lt;br /&gt;
 int zahl1 = 0;&lt;br /&gt;
 int zahl2 = 1;&lt;br /&gt;
 &lt;br /&gt;
 while (zahl1 &amp;lt; 3)&lt;br /&gt;
 {&lt;br /&gt;
    zahl1 = zahl1 + 1;&lt;br /&gt;
    zahl2 = zahl2 * 2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife drei mal durchlaufen. Zu Beginn des vierten Durchlaufs ist die Bedingung nicht mehr erfüllt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
&lt;br /&gt;
===do-while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
Die do-while-Schleife wird auf jeden Fall einmal durchlaufen und dann solange wiederholt, wie die Bedingung erfüllt ist.&lt;br /&gt;
 int i = 2;&lt;br /&gt;
 &lt;br /&gt;
 do &lt;br /&gt;
 {&lt;br /&gt;
     i = i*i;   {{comment|i quadrieren}}&lt;br /&gt;
     printf (&amp;quot;i = %d\n&amp;quot;, i);&lt;br /&gt;
 }&lt;br /&gt;
 while (i &amp;lt; 20);&lt;br /&gt;
&lt;br /&gt;
Die Schleife wird durchlaufen und wiederholt, solange &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; kleiner als 20 ist. Es werden also nacheinander die Werte 2, 4 und 16 ausgegeben. Nach der Schleife hat&amp;amp;nbsp;&amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; den Wert 256.&lt;br /&gt;
&lt;br /&gt;
===for-Schleife===&lt;br /&gt;
'''Syntax:''' &lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Bei den Ausdrücken wird es sich um einen Ausdrücke mit Nebeneffekt handeln wie etwa &amp;lt;tt&amp;gt;i=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;i=i+2&amp;lt;/tt&amp;gt;. Es werden folgende Aktionen ausgeführt:&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# falls die Bedingung wahr ist, dann führe &amp;lt;tt&amp;gt;Anweisung&amp;lt;/tt&amp;gt; aus.&lt;br /&gt;
# falls die Bedingung unwahr ist, dann sprinte zu 7 (Ende).&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# gehe zu 2&lt;br /&gt;
# nächste Anweisung nach der for-Schleife&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int lauf, summe;&lt;br /&gt;
 &lt;br /&gt;
 for (lauf=1, summe=0; lauf &amp;lt;= 10; lauf += 2) &lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel ist &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; ein [[#Komma-Operator|Komma-Ausdruck]], der zwei Anweisungen kombiniert und daher sogar zwei Nebeneffente hat: er setzt &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;1 und &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;0.&lt;br /&gt;
&lt;br /&gt;
Das Äquivalent als while-Schleife:&lt;br /&gt;
&lt;br /&gt;
 int lauf  = 1;                 {{comment|Anfangswerte}}&lt;br /&gt;
 int summe = 0;&lt;br /&gt;
 &lt;br /&gt;
 while (lauf &amp;lt;= 10)             {{comment|Bedingung}}&lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
    lauf  += 2;                 {{comment|Inkrement}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; in jedem Schleifendurchlauf um die Laufvariable &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; erhöht. Da &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nacheinander die ungeraden Werte von&amp;amp;nbsp;1 bis&amp;amp;nbsp;10 annimmt, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von&amp;amp;nbsp;1 bis kleinergleich 10 gespeichert, also der Wert&amp;amp;nbsp;25. &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; hat nach der Schleife den Wert&amp;amp;nbsp;11.&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf = 1&amp;lt;/tt&amp;gt; bedeutet, dass der Variablen &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; vor dem ersten Schleifendurchlauf der Wert&amp;amp;nbsp;1 zugewiesen wird. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf &amp;lt;= 10&amp;lt;/tt&amp;gt; ist die Schleifenbedingung; ist sie nicht erfüllt, wird die Schleife beendet. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf += 2&amp;lt;/tt&amp;gt; bedeutet, dass &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nach jedem Durchlauf um&amp;amp;nbsp;2 erhöht wird.&lt;br /&gt;
&lt;br /&gt;
===continue-Anweisung===&lt;br /&gt;
Innerhalb einer Schleife darf die &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die nachfolgenden Anweisungen übersprungen werden und mit dem nächsten Schleifendurchlauf fortgesetzt wird &amp;amp;ndash; vorausgesetzt die Schleifenbedingung ist noch erfüllt. Ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; etc. stehen, wenn dieses innerhalb einer Schleife steht.&lt;br /&gt;
&lt;br /&gt;
==break-Anweisung==&lt;br /&gt;
Innerhalb einer Schleife oder eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; darf die &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die Schleifen-/Switch-Anweisung sofort verlassen wird und das Programm dahinter weiter macht. Bei mehrfach geschachtelten Schleifen wird nur die innere verlassen. Ein &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; stehen, wenn dieses innerhalb einer Schleife/Switch-Anweisung steht.&lt;br /&gt;
&lt;br /&gt;
==goto-Anweisung==&lt;br /&gt;
&lt;br /&gt;
Innerhalb ein und derselben Funktion kann mit &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; an eine andere Stelle gesprungen werden. Dazu gibt man hinter dem &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einen Bezeichner an, der dadurch als Label fungiert:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 goto {{Bezeichner}};&lt;br /&gt;
Die Bezeichner selbst steht irgendwo in der Funktion und wird dadurch zur Sprungmarke (Label), daß er von einem Doppelpunkt (und mindestens einer C-Anweisung, die auch leer sein darf) gefolgt wird.&lt;br /&gt;
&lt;br /&gt;
Das Beispiel durchsucht das 2-dimensionale &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array &amp;lt;tt&amp;gt;feld&amp;lt;/tt&amp;gt; mit den &amp;lt;tt&amp;gt;SIZE_X &amp;amp;times; SIZE_Y&amp;lt;/tt&amp;gt; Werten nach dem Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;. Wird er gefunden, dann wird die 2-fach geschachtelte Suchschleife verlassen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int x, y;&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y; y++)&lt;br /&gt;
       if (feld[x][y] == 0)&lt;br /&gt;
          goto done;&lt;br /&gt;
 {{Label|done:}};&lt;br /&gt;
&lt;br /&gt;
Der folgende Code hat die gleiche Funktion, arbeitet jedoch ohne &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int x, y;&lt;br /&gt;
 int found = 0; {{comment|FALSE}}&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X &amp;amp;&amp;amp; !found; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y &amp;amp;&amp;amp; !found; y++)&lt;br /&gt;
       found = (0 == feld[x][y]);&lt;br /&gt;
Der Nachteil der &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-losen Variante ist, daß man eine Variable, die merkt, ob das Suchziel gefunden wurde, mitschleppen und in ''jedem'' Schleifendurchlauf abtesten muss. Dies bedeutet einen höheren Programmier- und Laufzeitaufwand und ist nicht so klar formuliert wie das &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-Beispiel.&lt;br /&gt;
&lt;br /&gt;
Gleichwohl sei angemerkt, daß die Verwendung von &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einem gewissen Dogmatismus unterliegt, der sich wie folgt subsummieren liesse:&lt;br /&gt;
:''goto ist böse und sollte keinesfalls verwendet werden! Wer es dennoch tut, offenbart dadurch seinen schlechten Geschmach sowie mangelhafte C-Kenntnis.'' &amp;lt;div align=&amp;quot;right&amp;quot;&amp;gt;http://www.roboternetz.de/phpBB2/images/smiles/icon_wink.gif&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Funktionen=&lt;br /&gt;
Stellen Dir vor, Du hast eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben &amp;amp;ndash; was Dich Zeit beim Erstellen des Programms und Speicherplatz im ausführbaren Programm kostet &amp;amp;ndash; kannst Du den Code-Abschnitt in eine Funktion schreiben und diese von jeder Stelle des Programms aus verwenden. Die Hauptgründe, um Funktionen zu verwenden, sind:&lt;br /&gt;
;Wiederverwendung von Code: Mehrfach verwendete Codestücke müssen nicht mehrfach implementiert werden. Oft unterscheiden sich die Codesequenzen nur in Kleinigkeiten, die man der Funktion über Parameter mitteilen kann.&lt;br /&gt;
;Übersichtlichkeit: Ein gut gegliedertes C-Programm implementiert klar umrissene Aufgaben in einer Funktion, auch wenn diese Funktion nur einmal im Code aufgerufen wird! Dadurch bleibt der Code um die Aufrufstelle besser verständlich, und man kann auf verschiedenen &amp;quot;Ebenen&amp;quot; denken. Eine Funktion wie &amp;quot;Datei öffnen&amp;quot; kann recht komplex sein. Auf höherer Ebene interessieren die Innereien nicht mehr, man möchte sich um andere Dinge kümmern und will den Code an der Stelle garnicht sehen...&lt;br /&gt;
;Rekursive Funktionen: Eine Funktion kann sich auch selbst aufrufen. In dem Falle nennt man die Funktion ''rekursiv''. Zwar lässt sich das, was eine rekursive Funktion tut, auch mit anderen Mitteln formulieren, die keine rekursiven Funktionen brauchen, aber oft ist der rekursive Weg knackiger und klarer formulierbar als eine nicht-rekursiven Ansatz, auch wenn es etwas mehr Resourcen verbraucht.&lt;br /&gt;
;Modulare Programmierung: Funktionen können anhand ihres Aufgabenbereichs auf verschiedene C-Quellen &amp;amp;ndash; sogenannte ''Module'' &amp;amp;ndash; verteilt werden. Funktionen, die etwas mit dem USB-Bus anstellen, werden in einem anderen Modul sein als mathematische Funktionen. Dies erhöht die Übersichtlichkeit und vereinfacht die Entwicklung im Team.&lt;br /&gt;
;Bibliotheken: Standard-Funktionen wie das hier oft auftauchende &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; sind in Bibliotheken gespeichert. Wenn das eigene Programm übersetzt wird, dann müssen nicht mehr alle Standard-Funktionen übersetzt werden, sondern werden nur noch aus der Bibliothek gelesen und ihr Code zum Programm dazugelinkt. Die Bibliotheks-Funktionen wurden schon zu einem früheren Zeitpunkt compiliert und liegen in dieser compilerten Form in der Bibliothek. Das spart mächtig Entwicklungszeit. Man kann auch selbst solche Bibliotheken erstellen und in diversen Projekten wiederverwenden.&lt;br /&gt;
;Generische Programmierung: In C ist es möglich, einer Funktion eine andere Funktion zu übergeben. (Damit ist nicht gemeint, ihr deren ''Rückgabewert'' zu übergeben (was auch ginge), sondern ''die Funktion selbst'' wird als Parameter übergeben und kann aufgerufen werden.) Ein typisches Beispiel dafür sind Sortieralgorithmen. Einem Sortieralgorithmus kann es egal sein, ''was'' er sortiert. Er muss lediglich wissen, ''wie'' er das Zeug zu sortieren hat: aufsteigend, absteigend, als Zahl, in lexikographischer Ordnung, nach der Quersumme, Körper nach Oberfläche, Durchmesser, Gewicht oder Volumen... Diese Vergleichsfunktion, die für zwei Objekte entscheidet, welches davon &amp;quot;kleiner&amp;quot; ist, kann man dem Sortierer übergeben. Will er zwei Werte vergleichen, dann muss er nur die Vergleichsfunktion aufrufen, ohne zu wissen, was diese tut. Damit kann der Sortieralgorithmus unanhängig von den Objekten gehalten werden, mit denen er hantieren soll.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Definition==&lt;br /&gt;
&lt;br /&gt;
In der ''Definition'' der Funktion wird gesagt, welche Werte sie liefern kann, wie sie heisst (Bezeichner) und wieviele und welche Parameter sie hat. Danach folgt ihre Implementierung:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}} ({{Parameterliste}})&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 &lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
Für Funktionen, die keinen Wert zurückliefern, gibt es den speziellen Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der besagt, daß die Funktion nichts zurückgibt. Die einfachste denkbare Funktion ist eine solch void-Funktion. Sie bekommt keine Parameter, gibt nicht zurück und ihr Body ist leer:&lt;br /&gt;
 void dummy()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==return-Anweisung==&lt;br /&gt;
An jeder Stelle des Programmflusses einer Funktion kann diese mit &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; beendet werden.&lt;br /&gt;
&lt;br /&gt;
'''bei void-Funktionen:'''&lt;br /&gt;
 return;&lt;br /&gt;
'''Funktionen mit Rückgabe-Wert:'''&lt;br /&gt;
 return {{Ausdruck|}};&lt;br /&gt;
Die zweite Variante gibt an, welcher Wert zurückgegeben wird.&lt;br /&gt;
 int main (int argc, char * argv[])&lt;br /&gt;
 {&lt;br /&gt;
    if (argc &amp;lt; 2)&lt;br /&gt;
       return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
Falls die letzte Anweisung einer void-Funktion ein &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; ist, kann es auch weggelassen werden wie oben bei der Funktion &amp;lt;tt&amp;gt;dummy&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Aufruf==&lt;br /&gt;
Um die Funktion aufzurufen gibt man ihren Namen an, gefolgt von den durch Komma getrennten Argumenten in runden Klammern wie im Beispiel unten das&lt;br /&gt;
 quadrat (5) &lt;br /&gt;
Da &amp;lt;tt&amp;gt;quadrat&amp;lt;/tt&amp;gt; einen Wert liefert, kann man damit weiter rechnen wie mit einem normalen Ausdruck:&lt;br /&gt;
 if (quadrat (a) + quadrat (b) == quadrat (c))&lt;br /&gt;
    c = quadrat (quadrat (a)); {{comment|c &amp;amp;#61; a hoch 4}}&lt;br /&gt;
&lt;br /&gt;
==Rekursive Funktionen==&lt;br /&gt;
Eine Funktion die sich selbst &amp;amp;ndash; möglicheweise auch über andere Zwischenfunktionen &amp;amp;ndash; wieder selbst aufruft, wird als ''rekursive Funktion'' bezeichnet. In der Definition ist nichts besonderes zu beachten. Ist die Verschachtelungstiefe im laufenden Programm zu tief, dann gibt das natürlich Probleme, aber das gilt bei tief verschachtelten 'normalen' Funktionen abenso...&lt;br /&gt;
&lt;br /&gt;
Das Beispiel berechnet den Größten Gemeinsamen Teiler zweier Zahlen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int ggT (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
     if (0 == a)&lt;br /&gt;
        return b;&lt;br /&gt;
 &lt;br /&gt;
    return ggT (b % a, a);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Ein komplettes kleines Programm:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int quadrat (int param1)&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  zahl = param1 * param1;&lt;br /&gt;
  return zahl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl, ergebnis;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Bitte Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = quadrat (zahl);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, zahl, ergebnis);&lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, 5, quadrat (5));&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur ausserhalb von Blöcken. Geschachtelte Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen beim Aufruf die Klammern angeben werden:&lt;br /&gt;
 dummy();&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Prototypen==&lt;br /&gt;
Wie oben erwähnt, kann ein Unterprogramm an jeder beliebigen Stelle im Programm stehen. Damit ist jedoch eine Bedingung verknüpft: Das Unterprogramm muß in der Datei oberhalb des ersten Aufrufes definiert worden sein. Wenn Sie ein Unterprogramm in Zeile 10 zum ersten mal aufrufen, müssen Sie die Deklaration davor erledigt haben. Verstanden?&lt;br /&gt;
Um dies zu erreichen, gibt es zwei Möglichkeiten: &lt;br /&gt;
&lt;br /&gt;
Entweder Sie schreiben alle Unterprogramme vor &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; in die Datei. Dies muß jedoch wiederum so geschehen, dass Funktionen zum Zeitpunkt ihres Aufrufes bereits bekannt sind! &lt;br /&gt;
Wo dies nicht möglich ist (z.B. sich gegenseitig aufrufende Unterprogramme), oder wenn Sie das stört, müssen Sie Prototypen verwenden. &lt;br /&gt;
Wie definiert man nun Prototypen? Sie kopieren einfach die erste Zeile des Unterprogrammes (z.B. &amp;quot;&amp;lt;tt&amp;gt;void ausgeben (int zahl)&amp;lt;/tt&amp;gt;&amp;quot;), fügen einen Strichpunkt&amp;amp;nbsp;&amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;an und fügen es an einer geeigneten Stelle ein (so, dass alle Aufrufe später in der Datei kommen). &lt;br /&gt;
Solche Definitionen stehen gewöhnlich am Anfang der Quelldatei oder in einer Header-Datei, die eingebunden wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl);  /* Der Prototyp */&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
   ausgeben (12);&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl)   /* Die eigentliche Prozedur */&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Ausgabe: %d\n&amp;quot;, zahl);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Parameterübergabe==&lt;br /&gt;
&lt;br /&gt;
Alle Werte, die an Prozeduren und Funktionen übergeben werden, werden grundsätzlich '''kopiert'''.&lt;br /&gt;
Das hat folgende Auswirkungen:&lt;br /&gt;
&lt;br /&gt;
# Änderungen an einem Parameter in einer Funktion erscheinen ''nicht'' beim Aufrufer!&lt;br /&gt;
# Möchte man, dass eine Funktion einen Wert trotzdem dauerhaft ändern soll, so muss die Adresse des Wertes via [[#Zeiger|Zeiger]] übergeben werden.&lt;br /&gt;
# Werden [[#Strukturen|Strukturen]] übergeben, so wird von ihnen eine Kopie erstellt, was bei großen Strukturen viel Zeit und Arbeitsspeicher kostet. Deshalb wird häufig nur die Adresse von Strukturen übergeben, da die Adresse viel schneller und platzsparender als die Struktur selbst kopiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele:'''&lt;br /&gt;
 void erhoehe (int x)&lt;br /&gt;
 {&lt;br /&gt;
    x = x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe(a);&lt;br /&gt;
    {{comment|a ist immer noch 0}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Beim Aufruf von &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; wird eine Kopie des Wertes von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; (im Beispiel also 0) erstellt und der Prozedur als Parameter &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; übergeben. Weil dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat dies keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|erhoehe den Wert an der Adresse x um eins}}&lt;br /&gt;
    *x = *x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe (&amp;amp;a);&lt;br /&gt;
    {{comment|a ist jetzt 1}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Jetzt wird im Hauptprogramm mittels [[#Adress-Operator und Dereferenzierung|Adress-Operator]] &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; die Speicheradresse von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; bestimmt. Dann wird eine ''Kopie der Adresse'' an das Unterprogramm &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; übergeben. Jetzt kennt das Unterprogramm die&lt;br /&gt;
Adresse des Originals &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und kann direkt mit dem Inhalts-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&lt;br /&gt;
'''Besonderheit bei Feldern'''&lt;br /&gt;
&lt;br /&gt;
Bei der Übergabe von [[#Felder|Feldern]] gibt es eine Besonderheit. Schreibt man nämlich den Namen eines Feldes, so ist das nichts anderes als die '''Speicheradresse des ersten Elements'''.&lt;br /&gt;
Bei der Übergabe eines Feldes wird also eine Kopie der Startadresse übergeben. Somit kann das Unterprogramm auf den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 void erhoehe (int x[])&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
   int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
   erhoehe (a);&lt;br /&gt;
   {{comment|a hat jetzt folgenden Inhalte: 11, 23, 35}}&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Dass die Übergabe einer Adresse erfolgt, sieht man an folgendem Beispiel, das von der Funktionsweise '''absolut identisch''' mit dem vorhergehenden ist:&lt;br /&gt;
&lt;br /&gt;
 {{comment|Bei Parametern gibt es keinen Unterschied zwischen Zeiger und Feld}}&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
    int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
    erhoehe (a);&lt;br /&gt;
 &lt;br /&gt;
    {{comment|a hat jetzt folgenden Inhalt: 11, 23, 35}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
Die Länge des Feldes wird nicht automatisch übergeben. Dafür ist ggf. ein zusätzlicher Parameter notwendig.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Variable Argumentanzahl==&lt;br /&gt;
== Funktionen indirekt aufrufen ==&lt;br /&gt;
Siehe [[#Zeiger auf Funktionen|Zeiger auf Funktionen]]&lt;br /&gt;
&lt;br /&gt;
=Zeiger II=&lt;br /&gt;
&lt;br /&gt;
Zeiger haben wir bereits weiter oben kennen gelernt. Zeiger sind ein zentrales Konzept in C und sollen hier etwas eingehender behandelt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger-Arithmetik==&lt;br /&gt;
In C kann man den Wert eines Zeigers verändern. Betrachten wir dazu die Funktion &amp;lt;tt&amp;gt;suche_0&amp;lt;/tt&amp;gt;, die einen Zeiger auf einen &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; erhält. Die Funktion soll ab der gegebenen Adresse nach dem ersten long-Wert suchen, der 0 ist, und dessen Adresse zurückgeben:&lt;br /&gt;
 long * suche_0 (long * addr)&lt;br /&gt;
 {&lt;br /&gt;
    while (*addr != 0)&lt;br /&gt;
       addr = addr + 1;&lt;br /&gt;
 &lt;br /&gt;
    return addr;&lt;br /&gt;
 }&lt;br /&gt;
In der Bedingung der while-Schleife wird der Inhalt an der Speicherstelle &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf 0 getestet. Ist der Wert 0, dann wird die Schleife beendet und die Adresse zurückgeliefert. Ist der Wert ungleich 0, dann wird &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf den nächste long gesetzt, &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; also um 4 Bytes weitergezählt. &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ist ja ein Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, und ein &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; ist 4 Bytes lang.&lt;br /&gt;
&lt;br /&gt;
Die Bedeutung von&lt;br /&gt;
 address + n&lt;br /&gt;
ist also, die Adresse um das &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;-fache der Größe des Typs, auf den &amp;lt;tt&amp;gt;address&amp;lt;/tt&amp;gt; zeigt, zu erhöhen. Dabei ist &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; eine ganze Zahl und darf auch negativ sein.&lt;br /&gt;
&lt;br /&gt;
Hier noch ein Beispiel einer Funktion, die nach einer Person mit einer bestimmten ID sucht (für die Definition von &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; siehe [[#Strukturen|Strukturen]]). Der Parameter &amp;lt;tt&amp;gt;person&amp;lt;/tt&amp;gt; ist dabei ein Array von Strukturen. Eine Person mit der gesuchten ID muss existieren, ansonsten hat die Suchfunktion kein definiertes Verhalten.&lt;br /&gt;
 {{comment|Sucht nach einer Person mit der ID person_id}}&lt;br /&gt;
 struct Person * &lt;br /&gt;
 suche_person_id (struct Person * person, int person_id)&lt;br /&gt;
 {&lt;br /&gt;
    while (person-&amp;gt;id != person_id)&lt;br /&gt;
       person++;&lt;br /&gt;
 &lt;br /&gt;
    return person;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:1em; padding:1em; border:solid 2px #FF0040;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- Vorlage:FarbigerRahmen funzt hier net --&amp;gt;&lt;br /&gt;
Beachte, daß es nicht sinnvoll ist, zwei Zeiger zu addieren oder zu multiplizieren. Ausserdem ist das &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt; der Zeiger-Arithmetik nicht kommutativ. Eine Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, der an Adresse 1 im Speicher zeigt, wird man schreiben als&lt;br /&gt;
 (long *) 1&lt;br /&gt;
Addiert man darauf eine ganze Zahl, dann haben die entstehenden Ausdrücke unterschiedliche Werte:&lt;br /&gt;
 (long *) 1 + 2    {{comment|zeigt zu Adresse 9}}&lt;br /&gt;
 (long *) 2 + 1    {{comment|zeigt zu Adresse 6}}&lt;br /&gt;
 (long *) (1 + 2)  {{comment|zeigt zu Adresse 3}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==void-Pointer==&lt;br /&gt;
Eine besondere Art von Zeiger ist der void-Pointer&lt;br /&gt;
 void * addr;&lt;br /&gt;
Ein void-Pointer ist ein &amp;quot;Zeiger auf irgendwas&amp;quot;, dementsprechend kann er nicht dereferenziert werden, Anwenden von &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf einen solchen Zeiger gibt also einen Fehler. Ausserdem ist es nicht möglich, mit einem void-Pointer Zeigerarithmetik zu machen, weil er nicht auf eine definierte Art von Objekt zeigt. Der Vorteil eines void-Pointers ist, daß er jede Art von Zeiger aufnehmen kann.&lt;br /&gt;
&lt;br /&gt;
Dazu betrachten wir die Funktion &amp;lt;tt&amp;gt;send_buf&amp;lt;/tt&amp;gt;, die eine Adresse erhält und ab dieser Adresse &amp;lt;tt&amp;gt;num&amp;lt;/tt&amp;gt; Bytes versenden soll. Wir könnten die Funktion so schreiben:&lt;br /&gt;
 void send_buf (unsigned char * buf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   ...&lt;br /&gt;
Das ist jedoch hässlich, wenn wir damit etwas anderes verschicken wollen als &amp;lt;tt&amp;gt; unsigned char&amp;lt;/tt&amp;gt;, etwa eine Struktur wie &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; (vom Typ &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;):&lt;br /&gt;
 send_buf ((unsigned char*) &amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
Ohne den Cast der Adresse von &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; zu einem Zeiger auf &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt; bekommt man eine Warnung oder gar einen Compilerfehler.&lt;br /&gt;
Dieses Zeiger gecaste ist mühsam und hässlich, es muss bei jedem Aufruf der Funktion explizit hingeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Besser ist es, den ersten Parameter der Funktion als void-Pointer zu definieren und den Cast in der Funktion zu machen:&lt;br /&gt;
 void send_buf (void * vbuf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   unsigned char *buf = (unsigned char*) vbuf;&lt;br /&gt;
   ...&lt;br /&gt;
Durch den Cast in der Funktion kann auf den Inhalt des Zeigers zugegriffen werden. Man muss nur festlegen, ''wie'' man zugreifen will, nämlich als &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Der Aufruf kann jetzt ohne Pointer-Cast erfolgen: &lt;br /&gt;
 send_buf (&amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
&lt;br /&gt;
==Null-Pointer==&lt;br /&gt;
==Zeiger als Parameter==&lt;br /&gt;
Wenn Sie ein Unterprogramm aufrufen, können Sie diesem Parameter übergeben, aber keine Werte zurückgekommen (außer den Funktionswert bei Funktionen). Dies hat einen guten Grund: beim Aufruf werden nicht die aufgerufenen Parameter benutzt, sondern es werden deren Werte in neue Variablen kopiert. Diese Variablen werden am Ende des Unterprogrammes &amp;quot;zerstört&amp;quot;, ohne ihre Werte an die aufrufenden Parameter zu übergeben. Jede Veränderung eines Parameters hat daher keine Auswirkung auf den Parameter.&lt;br /&gt;
&lt;br /&gt;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der C-Compiler legt dann immer noch Kopien an. In dieser Kopie steht aber kein Wert, sondern die Adresse einer Varaiblen. Und auf diese können Sie dann zugreifen. Denken Sie nur an &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; &amp;amp;ndash; da übergeben Sie ja auch die Adresse einer Variablen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void erhoehe (int *zeiger)&lt;br /&gt;
{&lt;br /&gt;
  *zeiger = 1 + *zeiger;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  erhoehe (&amp;amp;zahl);&lt;br /&gt;
  printf (&amp;quot;\nDie erhoehte Zahl lautet: %d\n&amp;quot;, zahl);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Zeiger auf Funktionen==&lt;br /&gt;
&lt;br /&gt;
Stell dir vor, du willst einen Sortieralgorithmus wie Bubble-Sort oder Quick-Sort oder wie sie alle heissen implementieren. Für den Sortieralgorithmus ist eigentlich egal, ''was'' er zu sortieren hat. Ihm ist es egal, ob er Zahlen aufwärts sortieren soll oder Strings in lexikographischer Reihenfolge, ob Objekte nach Größe oder Gewicht, Personen nach Alter oder Adressen nach Postleitzahl. Das einzige, was der Algorithmus wissen muss, ist ''wie'' er zwei Objekte zu vergleichen hat und wann eines davon &amp;quot;kleiner&amp;quot; (im Sinne der Ordnung, nach der sortiert werden soll) ist. &lt;br /&gt;
&lt;br /&gt;
Eine einfache Sortierfunktion, die nur zwei Zahlen sortiert, könnte man also so schreiben: &lt;br /&gt;
 {{comment|Sortiert ein Array von 2 int-Zeigern nach den Inhalten &lt;br /&gt;
  * an den Zeiger-Adressen}}&lt;br /&gt;
 void sort2_a (int * p[])&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Inhalte vergleichen...}}&lt;br /&gt;
    if (*p[0] &amp;gt; *p[1])&lt;br /&gt;
    {&lt;br /&gt;
       {{comment|... und ggf. Dreieckstausch der 2 Zeiger}}&lt;br /&gt;
       int * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Die Funktion bekommt ein Array der Länge&amp;amp;nbsp;2. In diesem Array stehen Zeiger auf die zu sortierenden Zahlen. Ein Array mit Zeigern zu verwenden und nicht ein Array von &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; scheint recht umständlich, und das ist es hier auch. Aber stell dir vor, du willst Strukturen wie &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; sortieren. Das Tauschen zweier Strukturen würde bedeuten, ihre kompletten Inhalte umzukopieren! Das wäre sehr aufwändig. Viel einfacher ist das Kopieren, wenn nur die Adressen zu kopieren sind.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; könnte dann so aussehen:&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void sortiere (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|p[] enthält 2 int-Zeiger: die Adressen von a und b}}&lt;br /&gt;
    int * p[2];&lt;br /&gt;
    p[0] = &amp;amp;a; &lt;br /&gt;
    p[1] = &amp;amp;b; &lt;br /&gt;
 &lt;br /&gt;
    {{comment|Sortiere die Zeiger}} &lt;br /&gt;
    sort2_a (p);&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Sortiert: %d, %d\n&amp;quot;, *p[0], *p[1]);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Für den nächsten Schritt überlegen wir uns, daß das Array in &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; ebensogut void-Pointer enthalten kann. Die einzige Stelle, an der wir auf die endgültigen int-Objekte zugreifen, ist der Vergleich. Diesen Vergleich lagern wir in die Funktion &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; aus:&lt;br /&gt;
 {{comment|Bekommt zwei void-Pointer und vergleicht die Inhalte.&lt;br /&gt;
  * Liefert 0 bei Gleichheit,&lt;br /&gt;
  * -1 wenn der erste Wert kleiner ist als der zweite und&lt;br /&gt;
  * 1  wenn der erste Wert größer ist als der zweite}}&lt;br /&gt;
 int compare_int (void * p0, void * p1)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Um über die Zeiger zugreifen zu können müssen wir diese&lt;br /&gt;
     * erst zu int-Zeigern casten}}&lt;br /&gt;
    int a0 = * (int*) p0;&lt;br /&gt;
    int a1 = * (int*) p1;&lt;br /&gt;
 &lt;br /&gt;
    if (a0 &amp;gt; a1)  return  1;&lt;br /&gt;
    if (a0 &amp;lt; a1)  return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void sort2_b (void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare_int (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Ein Aufruf von &amp;lt;tt&amp;gt;sort2_b&amp;lt;/tt&amp;gt; sieht dann genauso aus wie ein Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt definieren wir uns den neuen Datentyp &amp;lt;tt&amp;gt;comparator_t&amp;lt;/tt&amp;gt;. Dieser ist ein Zeiger auf eine Funktion, die zwei void-Pointer erhält und einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; zurückliefert, also analog arbeitet zu &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; von oben. &lt;br /&gt;
&lt;br /&gt;
Unsere Sortierfunktion bekommt nun neben dem zu sortierenden Zeiger-Array auch eine Vergleichsfunktion &amp;lt;tt&amp;gt;compare&amp;lt;/tt&amp;gt; mitgeliefert, die sie aufruft, wenn sie zwei Objekte vergleichen will&lt;br /&gt;
 {{comment|comparator_t sind Zeiger auf Funktionen, die 2 void-Pointer&lt;br /&gt;
  * erhalten und einen int zurückliefern}}&lt;br /&gt;
 typedef int (*comparator_t) (void*, void*);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Der Sortierer bekommt einen Funktionszeiger auf den Vergleicher.&lt;br /&gt;
  * Der Aufruf vom compare geht so als wäre es eine &amp;quot;normale&amp;quot; Funktion&lt;br /&gt;
  * (ist es im Endeffekt ja auch)}}&lt;br /&gt;
 void sort2_c (comparator_t compare, void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Bei einem Aufruf von &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; muss man dann einen Komparator mit angeben. In einem Beispiel analog zu &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; von oben ist das:&lt;br /&gt;
 sort2_c (compare_int, p);&lt;br /&gt;
Um zwei Strings lexikographisch zu sortieren nehmen wie die Standard-Funktion &amp;lt;tt&amp;gt;strcmp&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void foo()&lt;br /&gt;
 {&lt;br /&gt;
    char * worte[] = { &amp;quot;Wort1&amp;quot;, &amp;quot;Wort2&amp;quot; };&lt;br /&gt;
 &lt;br /&gt;
    sort2_c ((comparator_t) strcmp, (void**) worte);&lt;br /&gt;
 }&lt;br /&gt;
Die Casts sind hier erforderlich. Alternativ könnte man &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; mit reinen void-Pointern versorgen und diese dann dort umcasten.&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
&lt;br /&gt;
Die Syntax zur Definition/Deklaration von Funktionszeigern ist etwas verzwackt. Zur Verdeutlichung ein paar Beispiele. Dabei legt das linke &amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt; jeweils den Return-Typ fest.&lt;br /&gt;
 {{comment|definiert einen neuen Funktionszeiger-Typ}}&lt;br /&gt;
 typedef {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert einen Funktionszeiger}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert ein Array von Funktionszeigern (mit Initializer)}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}[]) ({{type}}, {{type}}, ...) = { wert1, wert2, ... };&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer}}&lt;br /&gt;
 ({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer und ruft die Funktion auf}}&lt;br /&gt;
 (({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}) (arg1, arg2, ...);&lt;br /&gt;
&lt;br /&gt;
=Standard-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==String-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===strcpy===&lt;br /&gt;
Bei vielen Compilern können sie einem String nicht direkt einen Wert (Text) zuweisen. Dazu müssen Sie dann die Prozedur strcpy() benutzen. Diese erwartet als ersten Parameter den Namen einer String-Variablen (ohne eckige Klammern) und als zweiten Parameter den eines (anderen) Strings. Letzterer kann auch ein in doppelten Hochkommas (&amp;quot;) eingeschlossener Text sein. Die Funktion fügt am Ende automatisch ein 0-Zeichen ein. Um diese Funktion nutzen zu können, müssen Sie die Datei string.h includieren! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri1[21], eingabe[21];&lt;br /&gt;
&lt;br /&gt;
  strcpy (stri1, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Der 1. String: %s\n&amp;quot;, stri1);&lt;br /&gt;
  printf (&amp;quot;Bitte geben Sie maximal 20 Zeichen ein: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%s&amp;quot;, eingabe);&lt;br /&gt;
  strcpy (stri1, eingabe);&lt;br /&gt;
  printf (&amp;quot;\n%s = %s&amp;quot;, stri1, eingabe);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis:''' &lt;br /&gt;
Da ein String, wie jedes Feld, eigentlich ein Zeiger ist, dürfen Sie kein &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; bei &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; angeben!&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
Es werden zwei gleich große Strings definiert: &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;eingabe&amp;lt;/tt&amp;gt;, mit je 20 &amp;quot;nutzbaren&amp;quot; Zeichen. &lt;br /&gt;
In &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; wird die Zeichenkette &amp;lt;tt&amp;gt;&amp;quot;hallo&amp;quot;&amp;lt;/tt&amp;gt; hineinkopiert. Das 0-Zeichen am Ende wird automatisch angefügt. &lt;br /&gt;
Der String wird ausgegeben. Als neues &amp;quot;Sonderzeichen&amp;quot; kommt &amp;lt;tt&amp;gt;%s&amp;lt;/tt&amp;gt; ins Spiel. Es hat die gleiche Aufgabe wie &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt;, nur für Strings. &lt;br /&gt;
Sie werden gebeten, eine String einzugeben. &lt;br /&gt;
Dieser String wird danach in die Variable &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; kopiert. &lt;br /&gt;
Beide Strings, die ja nun die gleiche Zeichenkette enthalten, werden ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===strlen===&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;strlen&amp;lt;/tt&amp;gt;, die als Parameter eine String-Variable erwartet, liefert die Länge diese Strings zurück. Sie werden jetzt vermutlich sagen: &amp;quot;Das ist doch klar, wie lang der String ist. Ich habe es ja bei der Deklaratin angegeben&amp;quot;. Das stimmt schon, aber denken Sie noch einmal an die null-terminierten Strings. Das 0-Zeichen steht am Ende des Strings (am Ende der gültigen Zeichenfolge), aber nicht unbedingt am Ende des reservierten Speicherplatzes. Haben Sie eine Variable &amp;quot;char Variable[21];&amp;quot;, und ihr den Wert &amp;quot;hallo&amp;quot; zugewiesen, dann steht das null-Zeichen in Variable[5]. Der &amp;quot;gültige&amp;quot; String ist also 5 Zeichen (0-4) lang. Und genau das (5) würde strlen zurück liefern. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri[21];&lt;br /&gt;
  &lt;br /&gt;
  strcpy (stri, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
  printf (&amp;quot;Der String ist %d Zeichen lang&amp;quot;, strlen (stri));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird vor allem gebraucht, wenn Sie direkt auf den String zugreifen, mittels &amp;lt;tt&amp;gt;stri[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;stri[1]&amp;lt;/tt&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
==Ein- und Ausgabe-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===Bildschirm-Ausgabe===&lt;br /&gt;
Bisher war das Tutorial trotz aller Beispiele reine Theorie. Sie konnten zwar Programme schreiben, aber die Funktion nicht testen. Hier lernen Sie nun, wie Sie etwas am Bildschirm ausgeben.&lt;br /&gt;
&lt;br /&gt;
Die dazu notwendige Funktione heisst &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (das '&amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt;' ist kein Fehler!). Diese Anweisung gibt die ihr übergebenen Parameter auf das Standard-Ausgabegerät aus, in der Regel also auf den Bildschirm. Sie kann beliebig viele Parameter übernehmen. Es müssen jedoch Standard-Datentypen (z.B. &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;...) sein! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
    int zahl1 = 12;&lt;br /&gt;
    char zeichen1 = 'A';&lt;br /&gt;
    &lt;br /&gt;
    printf (&amp;quot;Das ist Text, und er wird als solcher ausgegeben. \n&amp;quot;);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zahl1' ist: %d \n&amp;quot;, zahl1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %c \n&amp;quot;, zeichen1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %d \n&amp;quot;, zeichen1);&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt Text aus. Das Zeichen am Ende (&amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;) bedeutet &amp;quot;New Line&amp;quot;, es bewegt den Cursor an den Anfang der nächsten Zeile. &lt;br /&gt;
&lt;br /&gt;
Der zweite &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt auch Text aus, am Ende befindet sich wieder das &amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;, um einen Zeilenvorschub zu erreichen. Das &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; wird vom Compiler durch den ersten Parameter ersetzt, der nach dem Text angegeben wird. In diesem Fall wird &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; also durch den Wert der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ersetzt. Das &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; im &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; bedeutet &amp;quot;Dezimalzahl&amp;quot;, der Computer gibt also eine ganze Zahl aus. &lt;br /&gt;
&lt;br /&gt;
In der dritten Ausgabe wird ein Zeichen ausgegeben. Diesmal bedeutet &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; &amp;quot;char&amp;quot; (Zeichen). Es wird also &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; durch ein &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt; ersetzt, denn die Variable &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; wird als Character interpretiert. &lt;br /&gt;
&lt;br /&gt;
Die letzte Ausgabe interpretiert den Inhalt von &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; als Zahl, und gibt dager den ASCII-Wert von &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, also 65 aus. Das ist ein typisches Beispiel für das mögliche unterschiedliche Interpretieren einer  Variablen!&lt;br /&gt;
&lt;br /&gt;
===Tastatur-Eingabe===&lt;br /&gt;
&lt;br /&gt;
Um ein &amp;quot;gscheites&amp;quot; Programm schreiben zu können, muß man wissen, wie der Benutzer über die Tastatur Befehle eingeben kann. Die dafür notwendigen Funktionen stelle ich in diesem Kapitel vor.&lt;br /&gt;
Die wichtigste Funktion ist &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt;. Er liest Daten von der Tastatur. Die Syntax entspricht derer von &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int  zahl1;&lt;br /&gt;
char zeichen1;&lt;br /&gt;
&lt;br /&gt;
printf (&amp;quot;Bitte geben Sie eine Zahl ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl1);&lt;br /&gt;
printf (&amp;quot;Geben Sie einen Zeichen ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%c&amp;quot;, &amp;amp;zeichen1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Programm gibt eine Eingabeaufforderung aus. Dann erwartet es vom Benutzer, daß er eine Zahl eingibt, die mit [ENTER] bestätigt wird. Dieser Wert wird in &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; abgespeichert. Danach erfolgt wiederum eine Aufforderung zur Eingabe, diesmal eines einzelnen Zeichens. Dieses kann man nun eingeben und ebenfalls mit [ENTER] bestätigen.&lt;br /&gt;
&lt;br /&gt;
Macht man keine dem Datentyp der erwarteten Variable entsprechende Eingabe, dann bricht das Programm mit einer Fehlermeldung ab (wenn man z.B. &amp;quot;1_T2&amp;quot; eingibt, wenn eine Zahl erwartet wird)!&lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; vor den Parametern ist notwendig. Warum, das erfahren Sie im Kapitel &amp;quot;Unterprogramme&amp;quot;. Für die Profis eine Kurz-Erklärung: Das Unterprogramm &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; bekommt zwar einen Wert übergeben, kann aber keinen zurückliefern (&amp;quot;call by value&amp;quot;). Daher wird kein Wert, sondern ein Zeiger auf eine Variable übergeben. Mit dem &amp;amp; Zeichen bekommen Sie die Adresse einer Variablen (&amp;quot;call by reference&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=Parameter von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;=&lt;br /&gt;
Das Unterprogramm &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; kann, wie jede andere Funktion, Parameter besitzen. Doch keine selbst gewählten, sondern nur bestimmte. Doch warum braucht main Parameter? Denken Sie einmal an alle Betriebssystembefehle:&lt;br /&gt;
&amp;lt;tt&amp;gt;dir *.exe &amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;copy *.* a:&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;ls -la &amp;lt;/tt&amp;gt;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;&amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen!&lt;br /&gt;
&lt;br /&gt;
=Kurzreferenz=&lt;br /&gt;
==Syntax-Bausteine==&lt;br /&gt;
&lt;br /&gt;
Die Erklärung des Aufbaus von C-Befehlen erfolgt neben einfachen Beispielen auch durch ihren prinzipellen Aufbau. In diesen Syntax-Beschreibungen finden sich immer wieder die gleichen Bausteine, die hier näher erklärt werden sollen. Falls die solch ein Syntax-Baustein begegnet, kannst Du ihn anclicken und kommst dann zu seiner Erläuterung. &lt;br /&gt;
&lt;br /&gt;
In den Beispielen selbst gehören auch die spitzen Klammern zu dem Baustein (was daran zu erkennen ist, daß auch die Klammern eingefärbt sind). Die Klammern dürfen in einem konkreten C-Programm daher nicht eingetippt werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bezeichner&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Bezeichner in C dienen dazu, Variablen zu identifizieren und ihnen sprechende Namen zu geben, um die Quelle lesbarer zu machen. Man braucht Bezeichner auch, um selbstdefinierte Datentypen zu benennen und zum Benennen von Struct- und Union-Komponenten sowie als Namen für Funktionen und Sprungmarken (Labels).&lt;br /&gt;
&lt;br /&gt;
Bezeichner dürfen aus den Kleinbuchstaben &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;z&amp;lt;/tt&amp;gt;, den Großbuchstaben &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;Z&amp;lt;/tt&amp;gt;, dem Unterstrich&amp;amp;nbsp;&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt; und den Ziffern &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;9&amp;lt;/tt&amp;gt; aufgebaut werden, wobei an erster Stelle jedoch keine Ziffer stehen darf.&lt;br /&gt;
&lt;br /&gt;
Es wird zwischen Groß- und Kleinschreibung unterschieden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Ausdruck in C ist ein Konstrukt, das einen Wert hat. Ob dieser Wert eine ganze Zahl ist, eine Kommazahl oder ein Zeiger, etc. ist dabei egal. Die einfachsten Ausdrücke sind Konstanten wie&lt;br /&gt;
 2&lt;br /&gt;
oder Variablen wie&lt;br /&gt;
 ein_zahl&lt;br /&gt;
Mehrere Ausdrücke können durch [[#Liste der Operatoren|Operatoren]] zu komplexeren Ausdrücken kombiniert werden, etwa&lt;br /&gt;
 eine_zahl + andere_zahl == 2&lt;br /&gt;
oder &lt;br /&gt;
 eine_zahl = 2&lt;br /&gt;
Letzterer hat den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; und den Nebeneffekt, daß er diesen Wert an &amp;lt;tt&amp;gt;eine_zahl&amp;lt;/tt&amp;gt; zuweist.&lt;br /&gt;
&lt;br /&gt;
Auch der Aufruf einer Funktion, die einen Rückgabewert liefert, ist ein Ausdruck:&lt;br /&gt;
 sin (1.2)&lt;br /&gt;
und kann zum Aufbau komplexerer Ausdrüche verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bedingung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Bedingung ist ein Ausdruck, bei der nur interessiert, ob dieser zu&amp;amp;nbsp;0 (unwahr) auswertet oder zu ungleich&amp;amp;nbsp;0 (wahr). Solche Ausdrücke findet man in if-Anweisungen, in Schleifenbedingungen und bedingten Zuweisungen&lt;br /&gt;
 (ein_wert &amp;lt; 2) || (ein_wert &amp;gt; 40)&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Lvalue ist ein Ausdruck, dem etwas zugewiesen werden kann. Der Name ''Lvalue'' kommt aus dem Englischen. Das ''L'' steht abkürzend für left. Ein Lvalue ist damit ein Ausdruck, der auf der linken Seite eine Zuweisung in C stehen darf. Das &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; in den folgenden Beispiel-Ausdrücken muss ein Lvalue sein:&lt;br /&gt;
 x = y-1&lt;br /&gt;
&lt;br /&gt;
 x++&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Konstante&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Konstante ist ein Ausdruck, dessen Wert dem Compiler bekannt ist. Beispiele für Konstanten sind etwa&lt;br /&gt;
 7&lt;br /&gt;
 'B'&lt;br /&gt;
 -13.98e12&lt;br /&gt;
 1+(2*3)&lt;br /&gt;
und die Werte von [[#Enum|Enum]]s. &lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; aus dem folgenden Codestück definiert jedoch keine Konstante in diesem Sinne&lt;br /&gt;
 const double Pi = 3.14159256;&lt;br /&gt;
denn in einem anderen Quellmodul könnte durch die Deklaration&lt;br /&gt;
 extern const double Pi;&lt;br /&gt;
das Symbol &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; bekannt sein, ohne daß sein Wert bekannt ist!&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Adresse&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Adresse ist ein Ausdruck, der einen Speicherort (physikalisch oder virtuell) halten kann. Adressen erhält man dadurch, daß man einem Bezeichner den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt;voranstellt, Adressen durch Arithmetik berechnet oder Zahlen zu Adressen castet. Folgende Ausdrücke sind Adressen (eine sinnvolle Deklaration der auftretenden Variablen vorausgesetzt)&lt;br /&gt;
 &amp;amp; eine_zahl&lt;br /&gt;
 &amp;amp; ein_array[10]&lt;br /&gt;
 &amp;amp; ein_struct&lt;br /&gt;
 &amp;amp; ein_struct.komponente&lt;br /&gt;
 (int *) 0x1234&lt;br /&gt;
 (int *) eine_zahl&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Deklaration&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Anweisungen sind gewissermassen die Atome (oder Moleküle?), aus denen ein C-Programm besteht. Jedes C-Programm ist eine Abfolge von Deklarationen und Anweisungen. Einfache Anweisungen erhält man, in dem man einen Ausdruck nimmt und einen Strichpunkt dahinter schreibt:&lt;br /&gt;
 {{Ausdruck|}};&lt;br /&gt;
wie in&lt;br /&gt;
 x = x+1;&lt;br /&gt;
&lt;br /&gt;
Andere Anweisungen sind die unten aufgeführten Schleifen und die if- sowie die switch-Anweisung.&lt;br /&gt;
&lt;br /&gt;
Mehrere Deklarationen und Anweisungen können zu einem Block zusammengefasst werden. Dieser Block stellt dann wieder eine einzelne Anweisung dar und kann genau so gehandhabt werden!&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
In diesem Sinne ist auch z.B. die Syntax der if-Anweisung zu verstehen&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
besagt, daß der abhängig ausgeführte Code eine einzelne Anweisung sein darf oder eben ein kompletter Block oder die Verschachtelung mehrerer Blöcke etc.&lt;br /&gt;
&lt;br /&gt;
Eine Anweisung kann auch &amp;quot;leer&amp;quot; sein, also nichts tun. Diese Anweisungen sind der leere Block&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
und der Strichpunkt&lt;br /&gt;
 ;&lt;br /&gt;
die man gelegentlich in Schleifen findet:&lt;br /&gt;
 while (!timeout())&lt;br /&gt;
    {}&lt;br /&gt;
oder hinter Sprungmarken, die sonst direkt vor einer schliessenden Blockklammer stünden:&lt;br /&gt;
 {&lt;br /&gt;
    ...&lt;br /&gt;
    goto ein_label;&lt;br /&gt;
    ...&lt;br /&gt;
    {{Label|ein_label}}:;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Nicht jede Anweisung ist an jeder Stelle eines C-Programms erlaubt, so darf ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; nut innerhalb einer Schleife stehen. Gleiches gilt für &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;, das aber auch innerhalb eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; vorkommen darf.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Dies steht für einen Datentyp. Es kann ein elementarer Typ sein wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;, ein Zeiger darauf wie &amp;lt;tt&amp;gt;char*&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;void*&amp;lt;/tt&amp;gt;, und auch Qualifier enthalten wie das &amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt; im Typ &amp;lt;tt&amp;gt;unsigned long long&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Zu den Typen gehören auch zusammengesetzte Datentypen wie Strukturen und Unions, mit &amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt; selbst definierte Typen und natürlich Zeiger darauf, wie aus dem Abschnitt [[#Datentypen|Datentypen]]:&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person *&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;data32_t&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;&lt;br /&gt;
und Zeiger auf Funktionen.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Parameterliste&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
Die Parameterliste bei einer Funktionsdefinition gibt an, wieviel Übergabeparameter sie bekommt, wie diese heissen und welchen Typs diese sind. Der prinzipielle Aufbau ist&lt;br /&gt;
 {{Type}} {{Bezeichner}}, {{Type}} {{Bezeichner}}, ...&lt;br /&gt;
Falls die Funktion keine Parameter hat, dann ist die Parameterliste leer.&lt;br /&gt;
&lt;br /&gt;
Hier als Beispiel die zweiparametrige Funktion &amp;lt;tt&amp;gt;produkt&amp;lt;/tt&amp;gt;. Der erste Parameter heisst&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und ist ein &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;. Der zweite namens&amp;amp;nbsp;&amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; ist vom Typ &amp;quot;Zeiger auf double&amp;quot;, der Inhalt &amp;lt;tt&amp;gt;*b&amp;lt;/tt&amp;gt; ist also auch ein double.&lt;br /&gt;
&lt;br /&gt;
'''Definition der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b)&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
In älteren C-Quellen findet man noch eine andere Syntax für die Deklaration der Parameter, die aber heute praktisch nicht mehr verwendet wird:&lt;br /&gt;
'''alte Definition der Funktion:'''&lt;br /&gt;
 double produkt (a, b)&lt;br /&gt;
 double a, *b;&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Um die Funktion bekannt zu machen, werdendet man eine Deklaration bzw. den Prototypen, der dem Compiler nur mitteilt, welche Parameter die Funktion bekommt und was sie zurückliefert. Für den Aufruf der Funktion muss der Compiler nur diesen Prototyp kennen, ''was'' die Funktion im Endeffekt macht und wie sie implementiert wurde ist egal, sie wird als BlackBox angesehen.&lt;br /&gt;
&lt;br /&gt;
'''Prototyp der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b);&lt;br /&gt;
Hier dürfen die Bezeichner auch fehlen:&lt;br /&gt;
 double produkt (double, double*);&lt;br /&gt;
&lt;br /&gt;
==if==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==if-else==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==for==&lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Eine for-Schleife entspricht folgendem Konstrukt. Dabei sind die drei Ausdrücke optional. Fehlt die Bedingung, dann wird diese als &amp;quot;wahr&amp;quot; angenommen. Die beiden anderen Ausdrücke wird man als Ausdrücke mit Nebeneffekt wählen wie z.B. &amp;lt;tt&amp;gt;x=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;x=x-2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
 {&lt;br /&gt;
    {{Ausdruck|1}};&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_loop}}:&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
    else&lt;br /&gt;
       goto _break;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_continue}}:&lt;br /&gt;
    {{Ausdruck|2}};&lt;br /&gt;
    goto _loop;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_break}}:;&lt;br /&gt;
 }&lt;br /&gt;
Die Labels &amp;lt;tt&amp;gt;_break&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_continue&amp;lt;/tt&amp;gt; entsprechen den Sprungzielen einer &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Anweisung innerhalb von &amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==do-while==&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while  ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
==while==&lt;br /&gt;
 while  ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==switch==&lt;br /&gt;
 switch  ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    ...&lt;br /&gt;
  &lt;br /&gt;
    default:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#break-Anweisung|&amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Konstanten|&amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#continue-Anweisung|&amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#do-while-Schleife|&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Enum|&amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#for-Schleife|&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#goto-Anweisung|&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#return-Anweisung|&amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Liste der Operatoren|sizeof]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Strukturen|&amp;lt;tt&amp;gt;struct&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Eigene Datentypen|&amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Unions|&amp;lt;tt&amp;gt;union&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#while-Schleife|&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund2}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Arithmetische Operatoren&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Dies sind die &amp;quot;normalen&amp;quot; arithmetischen Operationen, wie man sie aus der Schule kennt. Man kann damit und allen anderen Operatoren auch komplexere Ausdrücke aufbauen. Die Prioritäten sind so, wie man sie kennt, also &amp;quot;Punktrechnung vor Strichrechnung&amp;quot;. Will man dies ändern, dann mit den runden Klammern:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;1+2*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 7&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(1+2)*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 9&amp;lt;br/&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}}&amp;amp;nbsp;+&amp;amp;nbsp;{{Ausdruck|}}&amp;lt;/tt&amp;gt; || Addition&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} - {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Subtraktion&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} * {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Multiplikation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} / {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Division&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} % {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Rest der Division (modulo)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;- {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Vorzeichenumkehr, Zweier-Komplement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Logische Operatoren und Vergleiche&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die logischen und die vergleichenden Operatoren liefern als Ergebnis den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (wahr) oder einen Wert ungleich&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (falsch, um genau zu sein den Wert &amp;lt;tt&amp;gt;!0&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Man kann das Ergebnis zwar einer Variablen zuweisen, in aller Regel wird man solche Ausdrücke jedoch in Bedingungen zu &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder in Abbruch-Bedingungen von Schleifen finden.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;&amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches AND: beides wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124;&amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches OR: mind. eines ist wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;! {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches NOT (0 &amp;amp;harr; ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} == {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} != {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist nicht gleich&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bitweise Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~ {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise NOT (Einser-Komplement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise AND&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise ODER&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} ^ {{Ausdruck|}}&amp;lt;/tt&amp;gt; ||bitweise XOR&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Shift-Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;lt;&amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Bits nach links schieben&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;gt;&amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Schieben nach rechts schieben&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Typen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Ein Cast in C kann dazu verwendet werden, den Typ eines Ausdruckes zu ändern oder den Ausdruck mit einer bestimmten Genauigkeit zu berechnen. Wird z.B. eine Berechnung standardmässig in 16 Bit ausgeführt, dann kann man mit einem Cast &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(long) &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
ausdrücken, daß die Berechnung in 32 Bit erfolgen soll. Des weiteren kann man Zeiger und ganze Zahlen und Gleitkommazahlen ineinander umwandeln.&lt;br /&gt;
&lt;br /&gt;
Casts können ''nicht'' dazu verwendet werden, um z.B. eine Zahl in einen String zu konvertieren, der diese Zahl darstellt! Dafür gibt es spezielle Funktionen wie &amp;lt;tt&amp;gt;itoa&amp;lt;/tt&amp;gt;!&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Type}}) {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Cast, Typwandlung&lt;br /&gt;
|-&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;| &amp;lt;tt&amp;gt;sizeof ({{Type}})&amp;lt;/tt&amp;gt; || Eine Konstante, deren Wert die Größe (in Bytes) des Typs ist. &amp;lt;tt&amp;gt;sizeof&amp;lt;/tt&amp;gt; ist auch auf Objekte anwendbar wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, Arrays bekannter Größe, Strukturen und Unions,  Array-, Struktur- und Union-Komponenten, Pointer, etc. Beispiel:&amp;lt;br/&amp;gt;&lt;br /&gt;
 int i, sum=0, array[] = { 1, -13, 4, 0, sizeof (int*) };&lt;br /&gt;
 &lt;br /&gt;
 for (i=0; i&amp;lt; sizeof (array) / sizeof (array[0]); i++)&lt;br /&gt;
    sum += array[i];&lt;br /&gt;
Alle Elemente des Arrays werden aufaddiert, ohne daß deren Anzahl explizit in der Schleife genannt ist.&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zeiger und Adressen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;* {{Adresse}}&amp;lt;/tt&amp;gt; || der Inhalt an Adresse&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp; {{Lvalue}}&amp;lt;/tt&amp;gt; || Adresse von&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Strukturen, Unions, Arrays&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Struct&amp;gt;}}.{{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Zeiger-auf-Struct&amp;gt;}} -&amp;gt; {{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union, deren Adresse man hat&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Adresse}}&amp;amp;#91;{{Ausdruck|}}&amp;amp;#93;&amp;lt;/tt&amp;gt; || Array-Element&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bedingte Auswertung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Bedingung}}) ? {{Ausdruck|}} : {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Auswahl des Wertes abhängig von der Bedingung&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zuweisung und Operatoren mit Nebeneffekt&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die Unterschiede der post- und pre-Varianten der Increment/Decrement kommen in Konstrukten wie &amp;lt;tt&amp;gt;x = *p++&amp;lt;/tt&amp;gt; zum tragen:&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *p++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; p = p+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *++p;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; p = p+1; x = *p;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = (*p)++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; *p = (*p)+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = ++(*p);&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; *p = (*p)+1; x = *p;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} = {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Zuweisung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++ {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-- {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Decrement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ++&amp;lt;/tt&amp;gt; || Post-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} --&amp;lt;/tt&amp;gt; || Post-Decrement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Kurzschreibweisen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Für ganz Faule gibt es anstatt&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a = a @ b&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
für viele Operatoren (hier dargestellt durch ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;@&amp;lt;/tt&amp;gt;) die abkürzende Schreibweise&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a @= b&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} += {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} -= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} *= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} /= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} %= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ^= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;lt;&amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;gt;&amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Autoren'''&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
* Kernighan und Ritchie - Buch&lt;br /&gt;
* Christian Wirth , C Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://wwwuser.gwdg.de/~kboehm/ebook/inhalt.html C-Programmieren unter Linux]&lt;br /&gt;
* [http://www.gdv.uni-hannover.de/documentation.php Skripte zum Selbststudium: C, C++, Java, etc]&lt;br /&gt;
* [http://info.baeumle.com/ansic.html Einführung in ANSI-C]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Quellcode C|!]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Inrfb2</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10390</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10390"/>
				<updated>2007-03-13T11:06:00Z</updated>
		
		<summary type="html">&lt;p&gt;Inrfb2: /* Reihenfolge der Auswertung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Programmiersprache C wurde 1971 als Gundlage für das Betriebssystem UNIX in den USA entwickelt (UNIX ist zu über 90% in C geschrieben). 1978 wurde von Brian Kernighan und Dennis Ritchie eine eindeutige Sprachdefinition entwickelt. Mittlerweile ist C von ANSI und ISO standardisiert.&lt;br /&gt;
&lt;br /&gt;
Heute sind C und ihr Nachfolger C++ die dominierenden Programmiersprachen. Sehr viele Anwendungen sind in C geschrieben, was inzwischen auch auf eingebettete Systeme zutrifft, die lange in Assembler programmiert werden mussten, da keine ausreichend leistungsfähigen Compiler zur Verfügung standen. &lt;br /&gt;
&lt;br /&gt;
Leider ist C nicht einfach zu lernen &amp;amp;ndash; es wurde weder von noch für Hobby-Programmierer entwickelt &amp;amp;ndash; und eignet sich daher nur bedingt für den Einsteiger. Mit etwas Übung und einem optimierenden Compiler kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
Vom Design her ist C eine Hardware-unabhängig Sprache. Das bedeutet, daß C-Programme mit vertretbarem Aufwand auf ein anderes System portiert werden können. Dazu benötigt man lediglich einen anderen Compiler, und Inline-Assembler-Anweisungen (Assembleranweisungen innerhalb eines C-Programmes) müssen der neuen Hardware (Prozessor) angepasst werden. &lt;br /&gt;
&lt;br /&gt;
==Geschichte==&lt;br /&gt;
;1971: C wird entwickelt&lt;br /&gt;
;1978: Kernighan und Ritchie definieren die Sprache.&lt;br /&gt;
;1983: ANSI und ISO standardisieren C.&lt;br /&gt;
;1992: Bjarne Stroustrup enwickelt die Nachfolgesprache C++.&lt;br /&gt;
&lt;br /&gt;
=Aufbau eines C-Programmes=&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
   C-Programme haben keinen fixen Aufbau wie z.B. Pascal. Es gibt zwar gewisse Regeln, aber sonst sind dem Programmierer alle Freiheiten überlassen. Der folgende &amp;quot;Beispiel-Aufbau&amp;quot; ist daher nicht zwingend und kann durchaus verändert werden.&lt;br /&gt;
&lt;br /&gt;
   Natürlich haben C-Programme einen fixen Aufbau! Ebenso wie Pascal-Programme auch unterliegen sie einer strikten Grammatik! &lt;br /&gt;
Auskommentiert --[[Benutzer:SprinterSB|SprinterSB]] 10:23, 17. Feb 2006 (CET)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Ein einfaches C-Programm könnte folgendermassen aussehen. Das Programm tut eigentlich nichts, aber das Beispiel zeigt den prinzipiellen Aufbau. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 int Zahl1;&lt;br /&gt;
 char Zeichen1;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int zahl2;&lt;br /&gt;
 &lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Beschreibung:'''&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndash; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
 {{comment|void-Definition von main ist nur beim Controller ueblich}}&lt;br /&gt;
 {{comment|spezielle Compilereinstellungen sind noetig, damit bei dieser Definition von main}}&lt;br /&gt;
 {{comment|kein Fehler/Warnung erzeugt wird.}}&lt;br /&gt;
 void main ()&lt;br /&gt;
 {&lt;br /&gt;
     ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
 int main (void)&lt;br /&gt;
 {  {{comment|der Block &amp;quot;main&amp;quot; beginnt}}&lt;br /&gt;
    int zahl;&lt;br /&gt;
    &lt;br /&gt;
    {   {{comment|ein Block beginnt}}&lt;br /&gt;
        {{comment|hier koennen Deklarationen und Anweisungen stehen}}&lt;br /&gt;
    }   {{comment|der Block endet}}&lt;br /&gt;
   &lt;br /&gt;
    return 0;&lt;br /&gt;
 }  {{comment|&amp;quot;main&amp;quot; endet}}&lt;br /&gt;
&lt;br /&gt;
=Datentypen=&lt;br /&gt;
==Elementare Datentypen==&lt;br /&gt;
Der Datentyp einer Variable gibt an, welche Werte eine Variable enthalten kann, welcher Art diese Daten sind und wie sie verarbeitet werden, etwa in arithmetischen Operationen wie einer Addition. So ist es zum Beispiel möglich, in eine Variable vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ganze Zahlen zwischen ca. -32000 und +32000 einzutragen. In einer char-Variable können ASCII-Zeichen gespeichert werden (alles, was Sie mit der Tastatur erzeugen können) oder ganze Zahlen von -128 bis 127.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da C plattformabhängig ist, hängt die Größe eines Datentypes zum Teil von der genutzten Hardware (z.B. 8, 16 oder 32 Bit-Controller) und dem Compiler und dessen Einstellungen ab!&lt;br /&gt;
&lt;br /&gt;
===int, char, short, long (ganze Zahlen)===&lt;br /&gt;
In Variable dieser Typen können Sie ganze Zahlen abspeichern, also z.B. 1, &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;2, 100, 12345. Jeden dieser Typen gibt es in zwei Ausprägungen: als &amp;quot;&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;quot;, also als vorzeichenbehafteten Typ, und als &amp;quot;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&amp;quot;, also ohne Vorzeichen, d.h. das Vorzeichen wird als 0 oder +1 genommen. &lt;br /&gt;
&lt;br /&gt;
Vorzeichenbehaftete Ganzzahl-Typen werden intern im &amp;lt;tt&amp;gt;n-1&amp;lt;/tt&amp;gt;-Komplement dargestellt, das Vorzeichen selbst findet sich also im höchstwertigen Bit. Werden zur Speicherung ''b'' Bits verwendet, dann reicht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;z.B. *zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==Enum==&lt;br /&gt;
&lt;br /&gt;
Über &amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt; können Aufzählungen definiert werden. Die Werte sind &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Werte und beginnen mit&amp;amp;nbsp;0. Der folgende enum hat einen um&amp;amp;nbsp;1 grösseren Wert. Mit einer Zuweisung können auch andere Werte zugeordnet werden. Klarer wird's im Beispiel:&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 enum Farben&lt;br /&gt;
 {&lt;br /&gt;
    ROT,&lt;br /&gt;
    GRUEN,&lt;br /&gt;
    BLAU,&lt;br /&gt;
    BRAUN = 5,&lt;br /&gt;
    SCHWARZ&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
Dies definiert die Konstanten &amp;lt;tt&amp;gt;ROT=0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;GRUEN=1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BLAU=2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BRAUN=5&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;SCHWARZ=6&amp;lt;/tt&amp;gt; und den Typ &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void foo (enum Farben farbe)&lt;br /&gt;
{&lt;br /&gt;
   switch (farbe)&lt;br /&gt;
   {&lt;br /&gt;
      case ROT:&lt;br /&gt;
         ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit kann man anstatt &amp;quot;magischer&amp;quot; Zahlen sprechende Namen im Code verwenden, etwa in Berechnungen und Zuweisungen, Vergleichen oder als Konstante hinter einem &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zusammengesetzte Datentypen==&lt;br /&gt;
===Arrays===&lt;br /&gt;
Oft muß man sehr viele Werte gleichzeitig abspeichern und betrachten, die alle der selben Aufgabe dienen. Man schreibt z.B. ein Programm, das 10 Zahlen einlesen und anschließend wieder ausgeben soll. Man könnte das natürlich mit 10 einzelnen Variablen bewerkstelligen, aber es ist sinnvoller, dabei Arrays &amp;amp;ndash; teilweise auch als ''Felder'' bezeichnet &amp;amp;ndash; zu verwenden.&lt;br /&gt;
&lt;br /&gt;
In einem Array werden mehrere Variablen gleichen Typs zusammengefasst und hintereinander im Speicher abgelegt. So kann man viele tausend Variablen anlegen mit nur einer Zeile Code. Doch es gibt noch größere Vorteile: Sie können das Array mit einer Schleife ganz einfach nach Werten durchsuchen. Stellen Sie sich vor, Sie müssten mit 100 verschiedenen Variablen &amp;lt;tt&amp;gt;Zahl_00&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;Zahl_99&amp;lt;/tt&amp;gt; arbeiten!&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}}&amp;amp;#91;{{Konstante}}&amp;amp;#93;;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 unsigned int werte[100];&lt;br /&gt;
&lt;br /&gt;
Der Name muß natürlich ein gültiger Bezeichner sein, als Datentyp kann jeder Typ genommen werden &amp;amp;ndash; sowohl elementare Datentypen als auch Zeiger, Strukturen, Unions oder selbst definierte Datentypen. In der eckigen Klammer wird die Anzahl der Elemente bekanntgegeben. Ein mit [3] definiertes Array hat Platz für drei Variablen. Da der Index immer bei 0 beginnt, greift man also mit &amp;lt;tt&amp;gt;[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;[1]&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;[2]&amp;lt;/tt&amp;gt; auf den jeweilige Inhalt zu. Um auf eine der im Array enthaltenen Variablen zugreifen zu können, müssen Sie den Variablennamen und in eckigen Klammern den Index (die &amp;quot;Nummer&amp;quot;) der Variablen angeben. Diese Variable verhält sich dann wie eine ganz normale Variable des jeweiligen Datentypes. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #define NZAHLEN 10&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int i;&lt;br /&gt;
    int zahlen[NZAHLEN];  {{comment|zahlen[0] ... zahlen[9]}}&lt;br /&gt;
  &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++)&lt;br /&gt;
    {&lt;br /&gt;
       printf (&amp;quot;Bitte Zahl %d eingeben: &amp;quot;, i);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; zahlen[i]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++) &lt;br /&gt;
       printf (&amp;quot;Zahl %d ist: %d\n&amp;quot;, i, zahlen[i]);&lt;br /&gt;
      &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 10 int-Variablen großes Array angelegt. &lt;br /&gt;
In dieses wird nun der Reihe nach 10 Zahlen eingelesen. &lt;br /&gt;
Anschließend werden alle 10 Zahlen ausgegeben. &lt;br /&gt;
&lt;br /&gt;
Dabei wird die Größe der Arrays und das Schleifenende über das Define &amp;quot;&amp;lt;tt&amp;gt;NZAHLEN&amp;lt;/tt&amp;gt;&amp;quot; angegeben. Dadurch muss nur ''eine Stelle'' im Code geändert werden, wenn die Größe des Arrays einmal einen anderer Wert als 10 haben soll &amp;amp;ndash; dies vermeidet Fehler die dadurch entstehen, wenn man beim Anpassen der Array-Größe eine Codestelle vergisst, zudem wird der Code lesbarer als wenn irgendwo die Zahl &amp;quot;10&amp;quot; auftaucht.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
:Wird ein ungültiger Index angeben (einer, der in der Deklaration nicht enthalten ist) können  undefinierte Dinge passieren, wenn dadurch andere Variableninhalte oder Programmcode überschrieben wird, der hinter oder vor dem Array im Speicher liegt. Schlimmstenfalls kann sogar der Computer/Controller abstürzen. Also darauf achten, daß keine ungültigen Werte als Index auftreten!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Strings (Zeichenketten)===&lt;br /&gt;
Ein String ist nichts anderes als ein Array, das aus einzelnen Zeichen (&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;) gebildet wird. Die Ausgabe auf dem Bildschirm funktioniert am einfachsten mittels Strings.&lt;br /&gt;
&lt;br /&gt;
Die Definition eines Strings erfolgt also genauso wie bei Arrays:&lt;br /&gt;
 char string[21];&lt;br /&gt;
&lt;br /&gt;
Nun haben Sie eine String, in dem Sie 21 Zeichen speichern können. Ganz richtig ist das jedoch nicht. C arbeitet mit &amp;quot;null-terminierten Strings&amp;quot;. Das beudeutet, dass die Länge des Strings nicht abgespeichert wird, sondern das Zeichen mit dem ASCII-Wert 0 das Stringende kennzeichnet. Daher auch die Bezeichnung  &amp;quot;null terminiert&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Das letzte Zeichen eines Strings muß daher immer das ASCII-Zeichen Nr. 0 sein. Ist es das nicht, hat der String kein definiertes Ende, und wenn Sie versuchen, ihn durch eine Standard-Funktion auszugeben zu lassen, könnte es eine Weile dauern, bis sich im Speicher zufällig irgendwo eine 0 befindet. Es stehen ihnen daher bei dem Beispiel nur 20 Zeichen zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
===Mehrdimensionale Arrays===&lt;br /&gt;
Manchmal benötigt man mehr als nur ein eindimensionales Array, wie Sie es bisher kennengelernt haben. Auch dies ist kein Problem. In der Deklaration geben Sie einfach mehrere eckige Klammern hintereinander an. Aber Vorsicht: der Speicherplatz ist begrenzt, ein &amp;quot;&amp;lt;tt&amp;gt;char feld[1024][1024]&amp;lt;/tt&amp;gt;&amp;quot; hat die Speicherplatzgrenzen vermutlich bereits weit überschritten, und der Compiler wird einen (bei gewissen Einstellung auch keinen) Fehler liefern.&lt;br /&gt;
Beim Zugriff auf mehrdimensionale Felder müssen auch mehrere Indizes angeben werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  int x,y;&lt;br /&gt;
  int feld[3][5];&lt;br /&gt;
 &lt;br /&gt;
  for (x=0; x&amp;lt;3; x++) &lt;br /&gt;
  {&lt;br /&gt;
     for (y=0; y&amp;lt;5; y++)&lt;br /&gt;
     {&lt;br /&gt;
       printf (&amp;quot;Feldwert x: %d,  y: %d &amp;quot;, x, y);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; feld[x][y]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  for(x=0; x&amp;lt;3; x++) &lt;br /&gt;
     for (y=0; y&amp;lt;5; y++) &lt;br /&gt;
        printf (&amp;quot;Wert: feld[%d][%d] = %d\n&amp;quot;, x, y, feld[x][y]);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 3 mal 5 &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array angelegt. &lt;br /&gt;
Dann werden die Werte eingegeben: zuerst &amp;lt;tt&amp;gt;feld[0][0]&amp;lt;/tt&amp;gt;, dann &amp;lt;tt&amp;gt;feld[0][1]&amp;lt;/tt&amp;gt;, usw. bis &amp;lt;tt&amp;gt;feld[2][4]&amp;lt;/tt&amp;gt;. &lt;br /&gt;
Zum Schluß werden alle Werte noch einmal ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===Strukturen===&lt;br /&gt;
In C können Sie sogenannte &amp;quot;Strukturen&amp;quot; definieren. Dabei handelt es sich um eine Zusammenfassung mehrerer Datentypen zu einem größeren. Im Unterschied zu Feldern können in Strukturen unterschiedliche Datentypen zusammengestellt und gespeichert werden: &lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 struct {{Bezeichner}}&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur 'Person'}}&lt;br /&gt;
 struct Person &lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;lt;tt&amp;gt;struct Person {&amp;lt;/tt&amp;gt;&amp;quot; leitet die Definition der Struktur mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;Person&amp;lt;/tt&amp;gt;&amp;quot; ein. &lt;br /&gt;
Dann werden in dieser Struktur fünf Komponenten definiert: drei Strings und zwei &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. &lt;br /&gt;
mit &amp;lt;tt&amp;gt;}&amp;lt;/tt&amp;gt; wird die Definition abgeschlossen. Sie haben damit einen Datentyp erstellt. Um eine Variable des Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach an&lt;br /&gt;
 struct Person {{Bezeichner}};&lt;br /&gt;
&lt;br /&gt;
Zum Zugriff auf eine Komponente der Struktur gibt man den Namen der Struktur-Variablen an (im folgenden Beispiel also &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;klaus&amp;lt;/tt&amp;gt;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
 {{comment|Definition zweier Struktur-Variablen}}&lt;br /&gt;
 struct Person hubert, klaus;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Zugriff auf Struktur-Komponenten}}&lt;br /&gt;
 hubert.alter = 32;&lt;br /&gt;
 klaus.alter = hubert.alter + 1;&lt;br /&gt;
&lt;br /&gt;
===Unions===&lt;br /&gt;
Eine Union wird ganz analog zu einer Struktur deklariert und verwendet. Sie unterscheidet sich von einer Struktur jedoch dadurch, daß ihre Elemente nicht nacheinander im Speicher abgelegt werden, sondern sich überlagern. Auf die in einer Union enthaltenen Daten gibt es also verschiedene Sichten: je nachdem, welche Sicht bzw. Interpretation der Daten man gerne hätte, wählt man den gewünschten Zugriff.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
union Daten &lt;br /&gt;
{&lt;br /&gt;
   int id;&lt;br /&gt;
&lt;br /&gt;
   struct Person u_person;&lt;br /&gt;
&lt;br /&gt;
   struct u_double&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      double wert;&lt;br /&gt;
   };&lt;br /&gt;
&lt;br /&gt;
   struct u_pointer&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      union Daten * p1;&lt;br /&gt;
      union Daten * p2;&lt;br /&gt;
   };&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
union Daten data;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies definiert eine Union mit den vier Zugriffsmöglichkeiten &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_double&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Größe der Union richtet sich dabei nach der grössten Komponente. In diesem Beispiel sind alle Komponenten so angelegt worden, daß sie an erster Stelle ein &amp;lt;tt&amp;gt;int id&amp;lt;/tt&amp;gt; enthalten. In &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; könnte man sich also merken, wie die Daten in der Union zu interpretieren sind. Würde &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; nicht dieses &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; enthalten, so würde sich &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; mit &amp;lt;tt&amp;gt;data.u_person.vname&amp;lt;/tt&amp;gt; überlagern. Ein Ändern der ersten Buchstaben von &amp;lt;tt&amp;gt;vname&amp;lt;/tt&amp;gt; hätte also ein Ändern von &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; zur Folge, und man könnte es nicht mehr als Merker verwenden. Mit diesem Feld überlagert das &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; die &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;-Felder der anderen Sichten, z.B. ist &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; der selbe Zugriff wie auf &amp;lt;tt&amp;gt;data.u_person.id&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein anderes Beispiel ist eine Union, die es ermöglicht, auf die einzelnen Bytes eines &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; zuzugreifen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef union&lt;br /&gt;
{&lt;br /&gt;
   unsigned long  as_long;&lt;br /&gt;
   unsignen short as_short[2];&lt;br /&gt;
   unsignen char  as_byte[4];&lt;br /&gt;
} data32_t;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies überlagert einen &amp;lt;tt&amp;gt;unsigned long&amp;lt;/tt&amp;gt; &amp;amp;ndash; also eine 32-Bit-Zahl &amp;amp;ndash; mit vier Bytes bzw. zwei Shorts.&lt;br /&gt;
 data32_t wert;&lt;br /&gt;
 &lt;br /&gt;
 wert.as_long = 0x12345678;&lt;br /&gt;
 wert.as_byte[0] = 0xab;&lt;br /&gt;
 {{comment|nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform)}}&lt;br /&gt;
&lt;br /&gt;
==Eigene Datentypen==&lt;br /&gt;
&lt;br /&gt;
=Variablen=&lt;br /&gt;
Eine Variable ist ein Synonym (=anderer Name) für eine Speicherstelle in einem Computer. Einfacher gesagt, eine Variable bietet Raum, um Daten wie Zahlen oder Zeichen zu speichern und wieder zu lesen.&lt;br /&gt;
&lt;br /&gt;
==Variablennamen==&lt;br /&gt;
Ein Variablenname kann zusammengesetzt werden aus den Buchstaben &amp;lt;tt&amp;gt;'''A'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''Z'''&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;'''a'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''z'''&amp;lt;/tt&amp;gt;, den Ziffern &amp;lt;tt&amp;gt;'''0'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''9'''&amp;lt;/tt&amp;gt;, sowie dem Sonderzeichen &amp;quot;Unterstrich&amp;quot; (underscore) &amp;lt;tt&amp;gt;'''_'''&amp;lt;/tt&amp;gt;. Dabei darf an erster Stelle keine Ziffer stehen. Die Bezeichner &amp;lt;tt&amp;gt;hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALLO&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALL0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;_123&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_HALLO&amp;lt;/tt&amp;gt; sind also alle gültige und unterschiedliche Variablennamen.&lt;br /&gt;
&lt;br /&gt;
==Anlegen von Variablen==&lt;br /&gt;
Um eine Variable verwenden zu können, muss sie zuerst vereinbart (&amp;quot;erzeugt&amp;quot;) werden. Dies wird auch als &amp;quot;''Definition der Variablen''&amp;quot; bezeichnet und geht so: Schreiben Sie zuerst den Datentyp, dann den Namen der Variablen. Zum Schluß kommt noch der Strichpunkt, wie nach jeder C-Anweisung oder Deklaration. Und nicht vergessen: C unterscheidet zwischen  Groß- und Kleinschreibung! &lt;br /&gt;
 int Zahl1, Zahl2;&lt;br /&gt;
 char Zeichen;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    float gleitZahl;&lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:'''&lt;br /&gt;
In einer Zeile können auch mehrere Variablen gleichen Types vereinbart werden, wenn man ein Komma dazwischen setzt. Variablen können in jedem Block vereinbart werden. Siehe [[#Gültigkeitsbereich|Gültigkeitsbereich]].&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen==&lt;br /&gt;
Man kann einer vereinbarten Variable Werte [[#Zuweisungen|zuweisen]]. Dazu schreibt man zuerst den Variablennamen, ein Gleichheitszeichen &amp;quot;&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;&amp;quot; und anschliessend den zuzuweisenden [[#Ausdrücke|Ausdruck]]. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, zahl2 = 12;&lt;br /&gt;
  char zeichen1 = 'A';&lt;br /&gt;
&lt;br /&gt;
  zahl1 = 52;&lt;br /&gt;
  zeichen1 = zeichen1 + 1; &lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Zuerst werden drei Variablen angelegt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;: wird gleich bei der Vereinbarung der Wert 12 zugewiesen. &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl1 = 52&amp;lt;/tt&amp;gt;: Hier wird der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; der Wert 52 zugewiesen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;: wird um 1 erhöht. Da in der Variablen &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; gespeichert ist, gibt sich ihr neuer Wert aus &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt;. Weil &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; dem Wert 65 entspricht, ist &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt; gleich 66, was dem Wert für &amp;lt;tt&amp;gt;'B'&amp;lt;/tt&amp;gt; entspricht.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei float==&lt;br /&gt;
Das funktioniert genau wie bei normale Zuweisungen. Nachkommastellen werden durch einen Punkt abgegrenzt: &lt;br /&gt;
 floatVariable = 3.14;&lt;br /&gt;
Zusätzlich kann eine Zehnerpotenz angegeben werden:&lt;br /&gt;
 floatVariable2 = -1.234E-6;&lt;br /&gt;
Dadurch wird der erst Wert mit 10&amp;lt;sup&amp;gt;&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;6&amp;lt;/sup&amp;gt; multipliziert, der Wert der Variablen ist also &lt;br /&gt;
:&amp;lt;math&amp;gt;-1{,}234\cdot10^{-6} = -0.000001234&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei logischen Variablen==&lt;br /&gt;
Wie bereits erwähnt, besitzt C keinen logischen Datentyp. Es müssen also &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; dafür genutzt werden. Die Zuweisung entpricht der Standard-Zuweisung. Wird der Wert 0 zugewiesen, dann ist die Variable &amp;quot;unwahr&amp;quot;, ansonsten ist sie &amp;quot;wahr&amp;quot;. &lt;br /&gt;
 intVariable = !0;   /* entspricht &amp;quot;wahr&amp;quot;   */&lt;br /&gt;
 intVariable = 0;    /* entspricht &amp;quot;unwahr&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
==Konstanten==&lt;br /&gt;
Konstanten können als Variable angesehen werden, die nicht beschrieben, sondern nur gelesen werden können. Ein typisches Beispiel dafür ist die Zahl &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; (rund 3,141592654). Niemand würde in der realen Welt versuchen, ihr einen anderen Wert zuzuweisen. Würde man &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; jedoch wie eine normale Variable anlegen, wäre dies ohne weiteres möglich. Um dies zu verhindern, gibt es das Schlüsselwort &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in C:&lt;br /&gt;
 const {{Type}} {{Bezeichner}} = {{Konstante}};  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Wichtig dabei ist, dass man Konstanten nur bei der Vereinbarung einen Wert zuweisen kann. &lt;br /&gt;
Da Konstanten gewöhnlich im gesamten Programm, zumindest einer Quelldatei genutzt werden, definiert man diese allerdings gewöhnlich außerhalb des main-Blockes entweder am Anfang eines Programmes, oder in einer sogenannten Header-Datei, die per &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; eingebunden wird.&lt;br /&gt;
 const float PI = 3.141592;  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Es sei jedoch erwähnt, daß auch einer Konstanten nachträglich ein anderer Wert zugewieden werden kann. Im obigen Beispiel könnte mit&lt;br /&gt;
 * ((float*) &amp;amp;PI) = 2;&lt;br /&gt;
der Wert von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; im Nachhinein verändert werden. Es wird die Adresse von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; genommen und diese Adresse durch den Cast in eine ganz normale &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;-Adresse umgewandelt, über welche der Wert geändert wird. Die sei der Vollständigkeit halber erwähnt.&lt;br /&gt;
&lt;br /&gt;
Je nachdem, an welcher Stelle sich das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; bei einer Pointer-Deklaration befindet, markiert es den Pointer als konstant oder das Objekt, auf das dieser Pointer zeigt. Eine häufige Parameterdeklaration in Ausgabe-Funktionen, die einen String erhalten, ist&lt;br /&gt;
 void foo (const char * str, ...);&lt;br /&gt;
Dadurch ist &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; der Zeiger auf eine Zeichenkette, die innerhalt der Funktion nicht verändert wird bzw. verändert werden darf. Eine Zuweisung wie &amp;lt;tt&amp;gt;*str = 'a'&amp;lt;/tt&amp;gt; ergibt also einen Fehler. &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; selbst kann aber sehr wohl verändert werden, etwa mit &amp;lt;tt&amp;gt;str++&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Soll ausgedrückt werden, daß &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; unveränderlich ist, dann so:&lt;br /&gt;
 void foo (char * const str, ...);&lt;br /&gt;
Jetzt wäre eine Änderung des Strings in Ordnung, etwa durch &amp;lt;tt&amp;gt;str[10] = 'a'&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Um sich zu merken, worauf das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; wirkt, trennt man die Deklaration in Gedanken beim&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf: Steht das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; links vom&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, dann gehört es zum &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, steht es rechts davon, dann gehört es zum Pointer. Natürlich ist es auch denkbar, beides &amp;amp;ndash; also den Zeiger und sein Ziel &amp;amp;ndash; als konstant zu markieren.&lt;br /&gt;
&lt;br /&gt;
==Gültigkeitsbereich==&lt;br /&gt;
In C können mehrere Variablen den gleichen Namen haben, solange eindeutig ist, welche in welchen Block gültig ist. Dabei gelten folgende Regeln: &lt;br /&gt;
&lt;br /&gt;
;Lokale Variablen: sind Variablen, die innerhalb eines Blockes definiert werden. Jede Variable ist nur in dem Block gültig, in dem sie vereinbart wurde, sowie in allen darin enthaltenen Blöcken; es sei denn, in einem Unter-Block wird eine Variable gleichen Namens definiert. Dann bezieht sich in diesem Unter-Block der Bezeichner auf die im Unter-Block angelegte Variable.&lt;br /&gt;
;Globale Variablen: werden ausserhalb jedes Blockes definiert und gelten ab der Stelle, an der sie deklariert werden, siehe auch [[#Deklaration und Definition|Deklaration und Definition]]. Wird jedoch in einem Block eine Variable gleichen Namens angelegt, gilt ab hier bis zum Ende des Blocks nicht mehr die globale Variable, sondern die im Block deklarierte. Das Spiel kann man weiterspielen: wird in einem Unter-Block wieder eine namensgleiche Variable angelegt, gilt diese in dem Unterblock.&lt;br /&gt;
&lt;br /&gt;
==Speicherklassen==&lt;br /&gt;
Jede Variable in C gehört zu einer bestimmten Speicherklasse&lt;br /&gt;
;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;: Lokale Variablen sind in aller Regal sogenannte ''automatische Variablen''. Das bedeutet, sie werden automatisch angelegt, wenn ein Block bzw. eine Funktion betreten wird und danach wieder entfernt. Das Schlüsselwort &amp;quot;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;&amp;quot; wird praktisch nie hingeschrieben, denn lokale Variablen ohne die ausdrückliche Angabe einer Speicherklasse, sind automatisch automatische Variablen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;: Eine externes Symbol ist im ganzen Programm bekannt bzw. in dem Block, in der die Deklaration steht. In unterschiedlichen Blöcken stehende Deklarationen beziehen sich auf das gleiche Symbol! Obgleich das Datum global zugreifbar ist, ist der Gültigkeitsbereich auf den deklarierenden Block begrenzt bzw. auf das deklarierende Quell-Modul, sofern das Symbol ausserhalb jedes Blocks des Moduls deklariert wird. Siehe auch [[#Deklaration und Definition|Deklaration und Definition]].&lt;br /&gt;
;&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;: Die Variable ist im Block gültig bzw. im Quell-Modul (also in der C-Datei, in der die angelegt wurde), wenn sie nicht innerhalb eines Blockes angelegt wurde. Statische Variablen werden nicht in Registern oder im Frame der Funktion angelegt, sondern im selben Speicherbereich, in dem auch die globalen Variablen liegen; Konstanten evtl. auch im Flash. Eine lokale Variable, die als &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; angelegt wird, &amp;quot;überlebt&amp;quot; also das Verlassen des Blocks und hat beim neuerlichen Betreten des Blockes ihren bisherigen Wert. In unterschiedlichen Blöcken angelegte lokale statische Variablen beziehen sich auf unterschiedliche Speicherstellen, genau wie bei lokalen Variablen auch.&lt;br /&gt;
;&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;: Durch diese Speicherklasse wird eine Variable &amp;amp;ndash; falls möglich &amp;amp;ndash; als Registervariable angelegt, also in einem Maschinenregister des Computer/Controllers gehalten. Dadurch kann auf solche Variablen besonders schnell zugegriffen werden. Dieses Schlüsselwort ist bei modernen Compilern weitgehend überflüssig, da die entsprechenden Optimierungen selbständig vorgenommen werden, wenn ausreichend Register vorhanden sind. Auch globale Variablen können als Register angelegt werden, davon ist dem Anfänger aber dringend abzuraten, weil leicht schwerauffindbare Fehler und Abstürze auftreten, wenn man nicht genau weiss, welche Implikationen in einer solchen Definition stecken!&lt;br /&gt;
;&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;: (FIXME: volatile ist ein Qualifier und keine Speicherklasse) Dies ist das genaue Gegenteil von &amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt; und bewirkt, dass die Variable auf keinen Fall in einem Register zwischengespeichert werden darf, sondern immer aus dem RAM gelesen und ins RAM geschrieben werden soll. &amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt; müssen alle ''globalen'' Variablen markiert werden, die in [[ISR | Interrupt-Handlern]] verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Ausdrücke=&lt;br /&gt;
Eine Variable oder eine Konstante in C stellen einfache Ausdrücke dar.&lt;br /&gt;
Diese elementaren Ausdrücke können durch Operatoren miteinander verknüpft werden und so zu neuen, komplexeren Ausdrücken zusammen gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Einfache Beispiele für Ausdrücke sind also z.B.:&lt;br /&gt;
 1&lt;br /&gt;
 a&lt;br /&gt;
 'a'&lt;br /&gt;
 1 + a&lt;br /&gt;
 a == 1&lt;br /&gt;
&lt;br /&gt;
Auch Funktionen können einen Wert zurückliefern und in Ausdrücken weiter benutzt werden.&lt;br /&gt;
In den folgenden Abschnitten wird gezeigt, welche Operatoren in C vorhanden sind,&lt;br /&gt;
und wei man damit neue Ausdrücke aufbauen kann.&lt;br /&gt;
&lt;br /&gt;
==Lvalues==&lt;br /&gt;
&lt;br /&gt;
Ein Lvalue in C ist ein Ausdruck, dem ein anderer Ausdruck zugewiesen werden kann, dessen Wert also durch eine Zuweisung verändert werden kann.&lt;br /&gt;
das 'L' leitet sich ab von 'left' bwz. 'links' und das 'value' bedeutet Wert: Ein Lvalue ist ein Ausdruck, der auf der linken Seite einer Zuweisung stehen darf. Ein Lvalue ist also immer auch ein gültiger Ausdruck, aber die Umkehrung gilt in alles Regel nicht.&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für einen Lvalue ist eine &amp;quot;normale&amp;quot; Variable, die nicht mit &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; als Konstante markiert ist:&lt;br /&gt;
 a = 1;&lt;br /&gt;
Hingegen ist der Ausdruck &amp;lt;tt&amp;gt;a+1&amp;lt;/tt&amp;gt; kein Lvalue, denn eine Zuweisung wie&lt;br /&gt;
 a+1 = 2;&lt;br /&gt;
die mathematisch durchaus sinnvoll ist, erzeugt einen Compilerfehler, der etwa lauten könnte &amp;quot;illegal lvalue in assignment&amp;quot;:&lt;br /&gt;
&amp;quot;ungültiger Wert in Zuweisung&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Andere Beipiele für Lvalues sind die Komponenten von (nicht-konstanten) [[#Strukturen|Strukturen]] und [[#Unions|Unions]], [[#Arrays|Array]]-Elemente und die Dereferenzierungen von Pointern: Die Konstante&amp;amp;nbsp;4 wird durch den Cast in eine Adresse umgewandelt. Über die Dereferenzierung&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; wird an die Adresse&amp;amp;nbsp;4 im Speicher eine&amp;amp;nbsp;3 geschrieben. Ob das erlaubt bzw. sinnvoll ist, ist abhängig von der jeweiligen Architektur.&lt;br /&gt;
 * ((unsigned int *) 4) = 3;&lt;br /&gt;
Hier ist der gesamte &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;-Ausdruck ein Lvalue&lt;br /&gt;
&lt;br /&gt;
==Logische (boolsche) Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp;amp;&amp;amp;amp; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr oder &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; || gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; || ungleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;= b&amp;lt;/tt&amp;gt; || kleiner oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt; b&amp;lt;/tt&amp;gt; || kleiner als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt;= b&amp;lt;/tt&amp;gt; || glösser oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt; b&amp;lt;/tt&amp;gt; || grösser als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; nicht wahr und vice versa&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine interessante Eigenschaft der Operatoren &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;amp;amp;&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; ist, dass&lt;br /&gt;
sie die Auswertung abbrechen, sobald das Ergebnis feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet. Ein oft anzutreffendes Codestück sieht so aus, dabei sei &amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
  if (p &amp;amp;&amp;amp; *p == 5)&lt;br /&gt;
  {&lt;br /&gt;
     {{comment|mach was}}&lt;br /&gt;
  }&lt;br /&gt;
Zuerst wird in der Bedinung geprüft, ob Zeiger&amp;amp;nbsp;&amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; einen Wert ungleich Null hat, also ob er überhaupt einen gültigen Wert enthält. Es ist weit verbreitete Konvention in C, daß Zeiger, die keinen gültigen Wert haben, die Adresse&amp;amp;nbsp;0 enthalten. '''Nur dann, wenn ein Zeiger nicht ein Null-Pointer ist, darf überhaupt ein Zugriff über ihn erfolgen!'''&lt;br /&gt;
&lt;br /&gt;
==Vergleich von Variablen==&lt;br /&gt;
Skalare Variablen (also ganze Zahlen, Gleitkommazahlen, Zeiger) können miteinander verglichen werden. Dazu gibt es die folgenden Operatoren in C: &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; || ist nicht gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;=&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;=&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das Ergebnis der Auswertung ist eine ganze Zahl. Ist die Bedingung erfüllt, dann ist der Wert ungleich&amp;amp;nbsp;0. Ist die Bedingung nicht erfüllt, dann ist ihr Wert gleich&amp;amp;nbsp;0.&lt;br /&gt;
Meistens wird man diese Operatoren in &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Konstrukten finden wie zum Beispiel&lt;br /&gt;
 if (x &amp;gt;= 10)&lt;br /&gt;
    x = 10;&lt;br /&gt;
oder in Abbruchbedingungen von Schleifen, wie sie weiter unten erklärt werden.&lt;br /&gt;
&lt;br /&gt;
Es ist auch möglich, das Ergebnis der Auswertung in einer &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Variablen zu speichern:&lt;br /&gt;
 int i;&lt;br /&gt;
 int z1, z2;&lt;br /&gt;
 &lt;br /&gt;
 z1 = 5;&lt;br /&gt;
 z2 = 100;&lt;br /&gt;
 i = z1 &amp;lt;= z2;  {{comment|Ein Vergleich. i wird &amp;quot;wahr&amp;quot;, da z1 kleinergleich z2 ist}}&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich&amp;amp;nbsp;0 (&amp;quot;wahr&amp;quot;), wenn &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; kleiner oder gleich &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt; ist. Ist &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; jedoch größer als &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt;, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich&amp;amp;nbsp;0 (&amp;quot;unwahr&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
==Arithmetische Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a + b&amp;lt;/tt&amp;gt; || Summe (Addition)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a - b&amp;lt;/tt&amp;gt; || Differenz (Subtraktion)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a * b&amp;lt;/tt&amp;gt; || Produkt (Multiplikation)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a / b&amp;lt;/tt&amp;gt; || Quotient (Division, evtl. mit Rest)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a % b&amp;lt;/tt&amp;gt; || Rest bei Division (Modulo)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;-a&amp;lt;/tt&amp;gt; || Vorzeichenumkehr (Zweierkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Bit-Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp; b&amp;lt;/tt&amp;gt; || bitweise und (and)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || bitweise oder (or)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a ^ b&amp;lt;/tt&amp;gt; || bitweise exclusiv-oder (xor, exor)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;~a&amp;lt;/tt&amp;gt; || jedes Bit in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; invertieren (not, Einerkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Index-Operator bei Arrays==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a[b]&amp;lt;/tt&amp;gt; || das (b+1)ste Element des Feldes a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Folgendes gilt es bei der Verwendung des Indexoperators zu beachten:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; muss ein [[C-Tutorial#Felder | Feld]] oder [[C-Tutorial#Zeiger | Zeiger]] sein&lt;br /&gt;
# &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; muss ein Integer sein oder ein Datentyp, der sich in einen int umwandeln läßt (z.B. char)&lt;br /&gt;
# Es wird nicht geprüft, ob der Index &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; im Feld &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gültig ist!&lt;br /&gt;
# Der erste Index eines Feldes ist immer 0. Daher ''(b+1)stes Element'' in der Beschreibung&lt;br /&gt;
&lt;br /&gt;
==Komponenten-Auswahl bei Structs und Unions==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a.b&amp;lt;/tt&amp;gt; || Element b der [[C-Tutorial#Strukturen | Struktur]] oder des Unions a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adress-Operator und Dereferenzierung==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&amp;amp;amp;a&amp;lt;/tt&amp;gt; || Speicheradresse der Variablen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;*a&amp;lt;/tt&amp;gt; || Wert, der an der Adresse &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a-&amp;amp;gt;b&amp;lt;/tt&amp;gt; || Wert des Elements &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; der Struktur, deren Adresse in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Adressoperator &amp;amp; kann auf Variablen angewendet werden und&lt;br /&gt;
gibt die Startadresse der Variablen im Speicher zurück.&lt;br /&gt;
&lt;br /&gt;
Handelt es sich bei einer Variable um einen [[C-Tutorial#Zeiger | Zeiger]], so enthält&lt;br /&gt;
sie eine Speicheradresse. Um an den '''Wert''' zu gelangen, der&lt;br /&gt;
an dieser Adresse steht, wird der Operator * vorangestellt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
&lt;br /&gt;
 {{comment|x ist eine Integervariable und hat den Wert 5}}&lt;br /&gt;
 int x = 5;&lt;br /&gt;
     &lt;br /&gt;
 {{comment|z ist ein Zeiger auf eine Integer-Variable und enthaelt somit}}&lt;br /&gt;
 {{comment|die Speicheradresse einer Integer-Variablen}}&lt;br /&gt;
 int *z;       &lt;br /&gt;
  &lt;br /&gt;
 {{comment|Verwendung des Adress-Operators: weist an z die Adresse von x zu}}&lt;br /&gt;
 z = &amp;amp;x;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Verwendung der Dereferenzierung}}&lt;br /&gt;
 {{comment|erhoehe den Wert, der bei Adresse z steht, um eins}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|da z auf x zeigt, hat x jetzt den Wert 6}}&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff auf Struktir- und Union-Elemente eine abkürzende Schreibweise möglich:&lt;br /&gt;
&lt;br /&gt;
Statt &lt;br /&gt;
  (*strukturZeiger).element&lt;br /&gt;
kann geschrieben werden&lt;br /&gt;
  strukturZeiger-&amp;gt;element&lt;br /&gt;
Beide Schreibweisen sind absolut gleichbedeutend, die Klammern bei der ersteren sind notwendig.&lt;br /&gt;
&lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
:Bei der Dereferenzierung durch &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; findet keine Prüfung statt, ob der Zeiger auch auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu einer Änderung '''irgendeiner''' Speicherstelle!&lt;br /&gt;
&lt;br /&gt;
 int *z; {{comment|z ist ein Zeiger auf einen int}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.}}&lt;br /&gt;
 {{comment|z enthaelt irgendeine ungueltige Adresse!!}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|&amp;quot;Erhoehe einen Integer _irgendwo_ im Speicher um 1&amp;quot; -&amp;gt; CRASH !!!}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
&lt;br /&gt;
==Cast-Operator==&lt;br /&gt;
&lt;br /&gt;
Der Cast Operator dient dazu, den Datentyp eines Wertes zu ändern. Dafür wird einfach der neue Datentyp in Klammern vor den Wert geschrieben.&lt;br /&gt;
&lt;br /&gt;
Um zum Beispiel aus einem Float ein Integer zu machen:&lt;br /&gt;
 var  = (int) 5.60;&lt;br /&gt;
Dabei wird der Wert aber auch gerundet, und es findet somit ein Informationsverlust statt.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Umwandeln einer ganzen Zahl in eine Adresse:&lt;br /&gt;
 int * addr;&lt;br /&gt;
 addr = (int*) 0x1234;&lt;br /&gt;
Damit ist &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; an Adresse 0x1234.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
Der Cast-Operator selbst führt ''keine Konvertierung'' von Darstellungen durch, etwa die Umwandlung der ganzen Zahl 123 ein den String &amp;lt;tt&amp;gt;&amp;quot;123&amp;quot;&amp;lt;/tt&amp;gt;, der diese Zahl darstellt! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
  int main(int argc, char ** argv)&lt;br /&gt;
  {&lt;br /&gt;
        char text[] = &amp;quot;5.6&amp;quot;;&lt;br /&gt;
        int zahl = (int) text;&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, zahl);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Anfangsadresse des Strings &amp;lt;tt&amp;gt;&amp;quot;5.6&amp;quot;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Komma-Operator==&lt;br /&gt;
Mit einem &amp;lt;tt&amp;gt;,&amp;lt;/tt&amp;gt; können mehrere Ausdrücke nacheinander ausgewertet werden.&lt;br /&gt;
Die Auswertung erfolgt von links nach rechts.&lt;br /&gt;
&lt;br /&gt;
Solche Konstrukte sieht man manchmal in Abfragen wie&lt;br /&gt;
 FILE  *file;&lt;br /&gt;
 if (file = fopen (&amp;quot;foo.exe&amp;quot;, &amp;quot;r&amp;quot;), file != NULL)&lt;br /&gt;
was erst an &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; einen Wert zuweist und den &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Block nur betritt,&lt;br /&gt;
wenn &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; nicht der Nullpointer ist.&lt;br /&gt;
&lt;br /&gt;
Bequem kann das auch in einer [[#for-Schleife|for-Schleife]] sein, wenn man zwei (oder mehr) Laufvariablen hat oder so:&lt;br /&gt;
 for (i=0, j=0; i &amp;lt; 10; i++, j += 2)&lt;br /&gt;
    &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Zuweisung===&lt;br /&gt;
=== ++ und -- ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; stellen einfachere Schreibweisen dar zum Addieren bzw. Subtrahieren von&amp;amp;nbsp;1.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; (Inkrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo++; &lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo + 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; 3}}&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; (Dekrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo--;&lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo - 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; -1}}&lt;br /&gt;
&lt;br /&gt;
Die beiden Operatoren können sowohl in der Präfix-Schreibweise (vor der Variablen) als auch als Postfix-Schreibweise (hinter der Variablen) notiert werden. &lt;br /&gt;
Der Unterschied liegt darin, dass beim Präfix der Wert zuerst neu berechnet wird und die Variable dann verwendet wird. Beim Postfix wird die Variable zuerst verwendet und erst nach Auswertung des Ausdrucks, in dem sie enthalten ist, neu berechnet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 int ausgabe1, ausgabe2, var1 = 10, var2 = 10;&lt;br /&gt;
 ausgabe1 = 3 * ++var1; {{comment|ausgabe1 &amp;amp;#61; 33; var1 &amp;amp;#61; 11;}}&lt;br /&gt;
 ausgabe2 = 3 * var2++; {{comment|ausgabe2 &amp;amp;#61; 30; var2 &amp;amp;#61; 11;}}&lt;br /&gt;
&lt;br /&gt;
Für Zeiger arbeiten diese Operatoren etwas anders, siehe dazu [[#Zeiger-Arithmetik|Zeiger-Arithmetik]].&lt;br /&gt;
&lt;br /&gt;
===Bedingter Ausdruck===&lt;br /&gt;
 ({{Bedingung}}) ? {{Ausdruck|1}} : {{Ausdruck|2}}&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; erfüllt ist, dann wertet dieser Ausdruck aus zu &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt;. Ist er nicht erfüllt, dann wertet er aus zu &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 x = (x &amp;gt;= 3) ? 0 : x+1;&lt;br /&gt;
Startet man &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; mit dem Wert 0, dann nimmt es bei mehrfacher Anwendung dieser Zeile (z.B. in einer Schleife) nacheinander die folgende Werte an:&lt;br /&gt;
:&amp;lt;tt&amp;gt;1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, ...&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Priorität ||Operator||Assoziativität&lt;br /&gt;
|-&lt;br /&gt;
  &lt;br /&gt;
|&amp;lt;tt&amp;gt;15&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; ( ) [ ] -&amp;gt; . &amp;lt;/code&amp;gt;                      ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;14&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; ! ~ ++ -- + - (TYP) * &amp;amp; sizeof &amp;lt;/code&amp;gt;    ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;13&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; * / % (Rechenoperationen) &amp;lt;/code&amp;gt;         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;12&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; + - (binär) &amp;lt;/code&amp;gt;                       ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;11&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; &amp;lt;&amp;lt; &amp;gt;&amp;gt; &amp;lt;/code&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;10&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; &amp;lt; &amp;lt;= &amp;gt; &amp;gt;= &amp;lt;/code&amp;gt;                         ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 9&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; == != &amp;lt;/code&amp;gt;                             ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 8&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; &amp;amp; (AND-Operator)&amp;lt;/code&amp;gt;                   ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 7&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; ^ (XOR-Operator)&amp;lt;/code&amp;gt;                   ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 6&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; | (OR-Operator)&amp;lt;/code&amp;gt;                    ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 5&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; &amp;amp;&amp;amp; &amp;lt;/code&amp;gt;                                ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 4&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; || &amp;lt;/code&amp;gt;                                ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 3&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; ?: &amp;lt;/code&amp;gt;                                ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 2&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; = += -= /= *= %= &amp;gt;&amp;gt;= &amp;lt;&amp;lt;= &amp;amp;= |= ^= &amp;lt;/code&amp;gt; ||von rechts nach links&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt; 1&amp;lt;/tt&amp;gt; ||&amp;lt;code&amp;gt; , (Sequenz-Operator) &amp;lt;/code&amp;gt;              ||von links nach rechts&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
Eine Kontrollanweisung ist eine Anweisung, die Einfluss auf den Programmfluss hat. Normalerweise werden Anweisungen so ausgeführt, wie sie in der Quelldatei stehen: Von links nach rechts (falls mehrere Anweisungen in einer Zeile stehen sollten, wovon i.A. abzuraten ist) und von oben nach unten. Mit einer Kontrollanweisung kann dieser lineare Programmfluss durchbrochen werden: Die Codeausführung kann kann abhängig von einer Bedingung gemacht werden (&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;), kann wiederholt werden (Schleife) oder an einer anderen Stelle der Funktion fortgesetzt werden (&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==if-Anweisung==&lt;br /&gt;
Mit Hilfe des if-Befehls kann man Codeteile abhängig davon einer Bedingung ausführen lassen:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
oder mit else-Teil&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 if (x &amp;gt; 100)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;gt; 100 ist: Fehlerausgabe}}&lt;br /&gt;
    printf (&amp;quot;x = %d ist zu gross fuer die Berechnung!\n&amp;quot;, x);&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;lt;&amp;amp;#61; 100 ist: Berechne Summe der Zahlen 1...x}}&lt;br /&gt;
    {{comment|Die lokale Variable x2 lebt nur innerhalb dieses alse-Blocks}}&lt;br /&gt;
    int x2 = x;&lt;br /&gt;
 &lt;br /&gt;
    for (x = 0; x2 &amp;gt; 0; x2--)&lt;br /&gt;
       x += x2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Wenn die Bedingung wahr ist (&amp;lt;tt&amp;gt;x &amp;gt; 100&amp;lt;/tt&amp;gt;), dann wird eine Meldung ausgegeben; danach ist die if-Anweisung beendet. Der else-Block wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung nicht erfüllt (&amp;lt;tt&amp;gt;x &amp;amp;le; 100&amp;lt;/tt&amp;gt;), dann wird gleich zum else-Teil gesprungen, und nach dessen Ausführung der if-Befehl beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Ein häufiger Fehler ist es, statt &amp;lt;tt&amp;gt;if (a &amp;amp;#61;&amp;amp;#61; 23)&amp;lt;/tt&amp;gt; etwas wie &amp;lt;tt&amp;gt;if (a &amp;amp;#61; 23)&amp;lt;/tt&amp;gt; zu schreiben. &lt;br /&gt;
Dann wird allerdings nicht geprüft, ob die Variable&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gleich 23 ist, sondern der Variablen&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wird der Wert 23 zugewiesen. Der Ausdruck &amp;lt;tt&amp;gt;a &amp;amp;#61; 23&amp;lt;/tt&amp;gt; hat den Wert&amp;amp;nbsp;23 und ist damit immer &amp;quot;wahr&amp;quot;! Daher ist diese if-Bedingung immer erfüllt!&lt;br /&gt;
&lt;br /&gt;
Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken sondern bestenfalls eine Warnung. Damit ist dieser Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise &amp;lt;tt&amp;gt;if (23 &amp;amp;#61;&amp;amp;#61; a)&amp;lt;/tt&amp;gt;. Wenn man dort anstatt des Vergleichsoperators '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;amp;#61;&amp;lt;/tt&amp;gt;' den Zuweisungsoperator '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;lt;/tt&amp;gt;' verwendet, spuckt der Compiler sehr wohl einen Fehler aus! Ist die Zuweisung jedoch erwünscht und eine Compiler-Warnung lästig, dann wählt man eine Schreibweise wie &amp;lt;tt&amp;gt;if ((a &amp;amp;#61; b))&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;if (a &amp;amp;#61; b, a)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist zu schreiben &amp;lt;tt&amp;gt;if (Bedingung);&amp;lt;/tt&amp;gt; Richtig muss es heissen &amp;quot;&amp;lt;tt&amp;gt;if(Bedingung)&amp;lt;/tt&amp;gt;&amp;quot; Das Semikolon im ersten Fall ist eine leere Anweisung, die im if-Falle ausgeführt wird &amp;amp;ndash; sie bleibt also ohne Resultet. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt; ein auf das Semikolon folgende Anweisung die eigentlich zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören soll wird immer ausgeführt, die sie nicht mehr zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; dazu gehört.&lt;br /&gt;
}}&lt;br /&gt;
Bei verschachtelten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Konstrukten gehört ein &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zu letzten &amp;quot;freien&amp;quot; &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;. Soll in einer &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Folge das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zum ersten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören, dann ist das so zu hinzuschreiben:&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Ohne die geschweiften Klammern um das zweite &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehörte das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; dort hinzu.&lt;br /&gt;
&lt;br /&gt;
==switch-Anweisung==&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
&lt;br /&gt;
 switch ({{Ausdruck|}}) &lt;br /&gt;
 {&lt;br /&gt;
     case konstante1:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
    &lt;br /&gt;
     case konstante2:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 &lt;br /&gt;
     {{comment|weitere case-Marken}}&lt;br /&gt;
 &lt;br /&gt;
     default:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 } {{comment|Ende von switch}} &lt;br /&gt;
&lt;br /&gt;
Der Ausdruck muss ein skalarer Typ sein, er wird in die nächste ganze Zahl gewandelt und mit den Werten hinter den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Marken verglichen. Bei einer Übereinstimmung werden alle Befehle ab dem zutreffenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; ausgeführt. Stimmt der Ausdruck mit keinem der Werte überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt falls vorhanden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der nachfolgenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;- und des &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitts werden ausgeführt, wenn die Anweisungen des &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitts nicht mit dem Befehl &amp;lt;tt&amp;gt;break;&amp;lt;/tt&amp;gt; beendet werden!&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es dürfen beliebig viele &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitte angegeben werden, pro Vergleichswert jedoch nur einer.&lt;br /&gt;
Der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ist optional. Die Reihenfolge, in der &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt; angegeben werden, ist unerheblich.&lt;br /&gt;
&lt;br /&gt;
==Schleifen==&lt;br /&gt;
Um Anweisungen mehrmals hintereinander auszuführen, benötigt man Schleifen. Diese führen Anweisungen aus, bis oder solange Bedingungen erfüllt sind.&amp;lt;br&amp;gt; &lt;br /&gt;
Wichtig ist also, ob die Bedingung '''vor''' oder '''nach''' den Schleifen-Anweisungen geprüft wird. &lt;br /&gt;
&lt;br /&gt;
===while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 while ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Die while-Schleife wird solange durchlaufen, wie die Bedingung erfüllt ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Die Anweisung kann natürlich auch ein Block sein, der aus mehreren Deklarationen und Anweisungen besteht. &lt;br /&gt;
&lt;br /&gt;
 int zahl1 = 0;&lt;br /&gt;
 int zahl2 = 1;&lt;br /&gt;
 &lt;br /&gt;
 while (zahl1 &amp;lt; 3)&lt;br /&gt;
 {&lt;br /&gt;
    zahl1 = zahl1 + 1;&lt;br /&gt;
    zahl2 = zahl2 * 2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife drei mal durchlaufen. Zu Beginn des vierten Durchlaufs ist die Bedingung nicht mehr erfüllt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
&lt;br /&gt;
===do-while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
Die do-while-Schleife wird auf jeden Fall einmal durchlaufen und dann solange wiederholt, wie die Bedingung erfüllt ist.&lt;br /&gt;
 int i = 2;&lt;br /&gt;
 &lt;br /&gt;
 do &lt;br /&gt;
 {&lt;br /&gt;
     i = i*i;   {{comment|i quadrieren}}&lt;br /&gt;
     printf (&amp;quot;i = %d\n&amp;quot;, i);&lt;br /&gt;
 }&lt;br /&gt;
 while (i &amp;lt; 20);&lt;br /&gt;
&lt;br /&gt;
Die Schleife wird durchlaufen und wiederholt, solange &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; kleiner als 20 ist. Es werden also nacheinander die Werte 2, 4 und 16 ausgegeben. Nach der Schleife hat&amp;amp;nbsp;&amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; den Wert 256.&lt;br /&gt;
&lt;br /&gt;
===for-Schleife===&lt;br /&gt;
'''Syntax:''' &lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Bei den Ausdrücken wird es sich um einen Ausdrücke mit Nebeneffekt handeln wie etwa &amp;lt;tt&amp;gt;i=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;i=i+2&amp;lt;/tt&amp;gt;. Es werden folgende Aktionen ausgeführt:&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# falls die Bedingung wahr ist, dann führe &amp;lt;tt&amp;gt;Anweisung&amp;lt;/tt&amp;gt; aus.&lt;br /&gt;
# falls die Bedingung unwahr ist, dann sprinte zu 7 (Ende).&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# gehe zu 2&lt;br /&gt;
# nächste Anweisung nach der for-Schleife&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int lauf, summe;&lt;br /&gt;
 &lt;br /&gt;
 for (lauf=1, summe=0; lauf &amp;lt;= 10; lauf += 2) &lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel ist &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; ein [[#Komma-Operator|Komma-Ausdruck]], der zwei Anweisungen kombiniert und daher sogar zwei Nebeneffente hat: er setzt &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;1 und &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;0.&lt;br /&gt;
&lt;br /&gt;
Das Äquivalent als while-Schleife:&lt;br /&gt;
&lt;br /&gt;
 int lauf  = 1;                 {{comment|Anfangswerte}}&lt;br /&gt;
 int summe = 0;&lt;br /&gt;
 &lt;br /&gt;
 while (lauf &amp;lt;= 10)             {{comment|Bedingung}}&lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
    lauf  += 2;                 {{comment|Inkrement}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; in jedem Schleifendurchlauf um die Laufvariable &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; erhöht. Da &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nacheinander die ungeraden Werte von&amp;amp;nbsp;1 bis&amp;amp;nbsp;10 annimmt, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von&amp;amp;nbsp;1 bis kleinergleich 10 gespeichert, also der Wert&amp;amp;nbsp;25. &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; hat nach der Schleife den Wert&amp;amp;nbsp;11.&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf = 1&amp;lt;/tt&amp;gt; bedeutet, dass der Variablen &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; vor dem ersten Schleifendurchlauf der Wert&amp;amp;nbsp;1 zugewiesen wird. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf &amp;lt;= 10&amp;lt;/tt&amp;gt; ist die Schleifenbedingung; ist sie nicht erfüllt, wird die Schleife beendet. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf += 2&amp;lt;/tt&amp;gt; bedeutet, dass &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nach jedem Durchlauf um&amp;amp;nbsp;2 erhöht wird.&lt;br /&gt;
&lt;br /&gt;
===continue-Anweisung===&lt;br /&gt;
Innerhalb einer Schleife darf die &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die nachfolgenden Anweisungen übersprungen werden und mit dem nächsten Schleifendurchlauf fortgesetzt wird &amp;amp;ndash; vorausgesetzt die Schleifenbedingung ist noch erfüllt. Ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; etc. stehen, wenn dieses innerhalb einer Schleife steht.&lt;br /&gt;
&lt;br /&gt;
==break-Anweisung==&lt;br /&gt;
Innerhalb einer Schleife oder eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; darf die &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die Schleifen-/Switch-Anweisung sofort verlassen wird und das Programm dahinter weiter macht. Bei mehrfach geschachtelten Schleifen wird nur die innere verlassen. Ein &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; stehen, wenn dieses innerhalb einer Schleife/Switch-Anweisung steht.&lt;br /&gt;
&lt;br /&gt;
==goto-Anweisung==&lt;br /&gt;
&lt;br /&gt;
Innerhalb ein und derselben Funktion kann mit &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; an eine andere Stelle gesprungen werden. Dazu gibt man hinter dem &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einen Bezeichner an, der dadurch als Label fungiert:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 goto {{Bezeichner}};&lt;br /&gt;
Die Bezeichner selbst steht irgendwo in der Funktion und wird dadurch zur Sprungmarke (Label), daß er von einem Doppelpunkt (und mindestens einer C-Anweisung, die auch leer sein darf) gefolgt wird.&lt;br /&gt;
&lt;br /&gt;
Das Beispiel durchsucht das 2-dimensionale &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array &amp;lt;tt&amp;gt;feld&amp;lt;/tt&amp;gt; mit den &amp;lt;tt&amp;gt;SIZE_X &amp;amp;times; SIZE_Y&amp;lt;/tt&amp;gt; Werten nach dem Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;. Wird er gefunden, dann wird die 2-fach geschachtelte Suchschleife verlassen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int x, y;&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y; y++)&lt;br /&gt;
       if (feld[x][y] == 0)&lt;br /&gt;
          goto done;&lt;br /&gt;
 {{Label|done:}};&lt;br /&gt;
&lt;br /&gt;
Der folgende Code hat die gleiche Funktion, arbeitet jedoch ohne &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int x, y;&lt;br /&gt;
 int found = 0; {{comment|FALSE}}&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X &amp;amp;&amp;amp; !found; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y &amp;amp;&amp;amp; !found; y++)&lt;br /&gt;
       found = (0 == feld[x][y]);&lt;br /&gt;
Der Nachteil der &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-losen Variante ist, daß man eine Variable, die merkt, ob das Suchziel gefunden wurde, mitschleppen und in ''jedem'' Schleifendurchlauf abtesten muss. Dies bedeutet einen höheren Programmier- und Laufzeitaufwand und ist nicht so klar formuliert wie das &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-Beispiel.&lt;br /&gt;
&lt;br /&gt;
Gleichwohl sei angemerkt, daß die Verwendung von &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einem gewissen Dogmatismus unterliegt, der sich wie folgt subsummieren liesse:&lt;br /&gt;
:''goto ist böse und sollte keinesfalls verwendet werden! Wer es dennoch tut, offenbart dadurch seinen schlechten Geschmach sowie mangelhafte C-Kenntnis.'' &amp;lt;div align=&amp;quot;right&amp;quot;&amp;gt;http://www.roboternetz.de/phpBB2/images/smiles/icon_wink.gif&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Funktionen=&lt;br /&gt;
Stellen Dir vor, Du hast eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben &amp;amp;ndash; was Dich Zeit beim Erstellen des Programms und Speicherplatz im ausführbaren Programm kostet &amp;amp;ndash; kannst Du den Code-Abschnitt in eine Funktion schreiben und diese von jeder Stelle des Programms aus verwenden. Die Hauptgründe, um Funktionen zu verwenden, sind:&lt;br /&gt;
;Wiederverwendung von Code: Mehrfach verwendete Codestücke müssen nicht mehrfach implementiert werden. Oft unterscheiden sich die Codesequenzen nur in Kleinigkeiten, die man der Funktion über Parameter mitteilen kann.&lt;br /&gt;
;Übersichtlichkeit: Ein gut gegliedertes C-Programm implementiert klar umrissene Aufgaben in einer Funktion, auch wenn diese Funktion nur einmal im Code aufgerufen wird! Dadurch bleibt der Code um die Aufrufstelle besser verständlich, und man kann auf verschiedenen &amp;quot;Ebenen&amp;quot; denken. Eine Funktion wie &amp;quot;Datei öffnen&amp;quot; kann recht komplex sein. Auf höherer Ebene interessieren die Innereien nicht mehr, man möchte sich um andere Dinge kümmern und will den Code an der Stelle garnicht sehen...&lt;br /&gt;
;Rekursive Funktionen: Eine Funktion kann sich auch selbst aufrufen. In dem Falle nennt man die Funktion ''rekursiv''. Zwar lässt sich das, was eine rekursive Funktion tut, auch mit anderen Mitteln formulieren, die keine rekursiven Funktionen brauchen, aber oft ist der rekursive Weg knackiger und klarer formulierbar als eine nicht-rekursiven Ansatz, auch wenn es etwas mehr Resourcen verbraucht.&lt;br /&gt;
;Modulare Programmierung: Funktionen können anhand ihres Aufgabenbereichs auf verschiedene C-Quellen &amp;amp;ndash; sogenannte ''Module'' &amp;amp;ndash; verteilt werden. Funktionen, die etwas mit dem USB-Bus anstellen, werden in einem anderen Modul sein als mathematische Funktionen. Dies erhöht die Übersichtlichkeit und vereinfacht die Entwicklung im Team.&lt;br /&gt;
;Bibliotheken: Standard-Funktionen wie das hier oft auftauchende &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; sind in Bibliotheken gespeichert. Wenn das eigene Programm übersetzt wird, dann müssen nicht mehr alle Standard-Funktionen übersetzt werden, sondern werden nur noch aus der Bibliothek gelesen und ihr Code zum Programm dazugelinkt. Die Bibliotheks-Funktionen wurden schon zu einem früheren Zeitpunkt compiliert und liegen in dieser compilerten Form in der Bibliothek. Das spart mächtig Entwicklungszeit. Man kann auch selbst solche Bibliotheken erstellen und in diversen Projekten wiederverwenden.&lt;br /&gt;
;Generische Programmierung: In C ist es möglich, einer Funktion eine andere Funktion zu übergeben. (Damit ist nicht gemeint, ihr deren ''Rückgabewert'' zu übergeben (was auch ginge), sondern ''die Funktion selbst'' wird als Parameter übergeben und kann aufgerufen werden.) Ein typisches Beispiel dafür sind Sortieralgorithmen. Einem Sortieralgorithmus kann es egal sein, ''was'' er sortiert. Er muss lediglich wissen, ''wie'' er das Zeug zu sortieren hat: aufsteigend, absteigend, als Zahl, in lexikographischer Ordnung, nach der Quersumme, Körper nach Oberfläche, Durchmesser, Gewicht oder Volumen... Diese Vergleichsfunktion, die für zwei Objekte entscheidet, welches davon &amp;quot;kleiner&amp;quot; ist, kann man dem Sortierer übergeben. Will er zwei Werte vergleichen, dann muss er nur die Vergleichsfunktion aufrufen, ohne zu wissen, was diese tut. Damit kann der Sortieralgorithmus unanhängig von den Objekten gehalten werden, mit denen er hantieren soll.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Definition==&lt;br /&gt;
&lt;br /&gt;
In der ''Definition'' der Funktion wird gesagt, welche Werte sie liefern kann, wie sie heisst (Bezeichner) und wieviele und welche Parameter sie hat. Danach folgt ihre Implementierung:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}} ({{Parameterliste}})&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 &lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
Für Funktionen, die keinen Wert zurückliefern, gibt es den speziellen Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der besagt, daß die Funktion nichts zurückgibt. Die einfachste denkbare Funktion ist eine solch void-Funktion. Sie bekommt keine Parameter, gibt nicht zurück und ihr Body ist leer:&lt;br /&gt;
 void dummy()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==return-Anweisung==&lt;br /&gt;
An jeder Stelle des Programmflusses einer Funktion kann diese mit &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; beendet werden.&lt;br /&gt;
&lt;br /&gt;
'''bei void-Funktionen:'''&lt;br /&gt;
 return;&lt;br /&gt;
'''Funktionen mit Rückgabe-Wert:'''&lt;br /&gt;
 return {{Ausdruck|}};&lt;br /&gt;
Die zweite Variante gibt an, welcher Wert zurückgegeben wird.&lt;br /&gt;
 int main (int argc, char * argv[])&lt;br /&gt;
 {&lt;br /&gt;
    if (argc &amp;lt; 2)&lt;br /&gt;
       return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
Falls die letzte Anweisung einer void-Funktion ein &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; ist, kann es auch weggelassen werden wie oben bei der Funktion &amp;lt;tt&amp;gt;dummy&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Aufruf==&lt;br /&gt;
Um die Funktion aufzurufen gibt man ihren Namen an, gefolgt von den durch Komma getrennten Argumenten in runden Klammern wie im Beispiel unten das&lt;br /&gt;
 quadrat (5) &lt;br /&gt;
Da &amp;lt;tt&amp;gt;quadrat&amp;lt;/tt&amp;gt; einen Wert liefert, kann man damit weiter rechnen wie mit einem normalen Ausdruck:&lt;br /&gt;
 if (quadrat (a) + quadrat (b) == quadrat (c))&lt;br /&gt;
    c = quadrat (quadrat (a)); {{comment|c &amp;amp;#61; a hoch 4}}&lt;br /&gt;
&lt;br /&gt;
==Rekursive Funktionen==&lt;br /&gt;
Eine Funktion die sich selbst &amp;amp;ndash; möglicheweise auch über andere Zwischenfunktionen &amp;amp;ndash; wieder selbst aufruft, wird als ''rekursive Funktion'' bezeichnet. In der Definition ist nichts besonderes zu beachten. Ist die Verschachtelungstiefe im laufenden Programm zu tief, dann gibt das natürlich Probleme, aber das gilt bei tief verschachtelten 'normalen' Funktionen abenso...&lt;br /&gt;
&lt;br /&gt;
Das Beispiel berechnet den Größten Gemeinsamen Teiler zweier Zahlen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int ggT (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
     if (0 == a)&lt;br /&gt;
        return b;&lt;br /&gt;
 &lt;br /&gt;
    return ggT (b % a, a);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Ein komplettes kleines Programm:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int quadrat (int param1)&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  zahl = param1 * param1;&lt;br /&gt;
  return zahl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl, ergebnis;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Bitte Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = quadrat (zahl);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, zahl, ergebnis);&lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, 5, quadrat (5));&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur ausserhalb von Blöcken. Geschachtelte Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen beim Aufruf die Klammern angeben werden:&lt;br /&gt;
 dummy();&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Prototypen==&lt;br /&gt;
Wie oben erwähnt, kann ein Unterprogramm an jeder beliebigen Stelle im Programm stehen. Damit ist jedoch eine Bedingung verknüpft: Das Unterprogramm muß in der Datei oberhalb des ersten Aufrufes definiert worden sein. Wenn Sie ein Unterprogramm in Zeile 10 zum ersten mal aufrufen, müssen Sie die Deklaration davor erledigt haben. Verstanden?&lt;br /&gt;
Um dies zu erreichen, gibt es zwei Möglichkeiten: &lt;br /&gt;
&lt;br /&gt;
Entweder Sie schreiben alle Unterprogramme vor &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; in die Datei. Dies muß jedoch wiederum so geschehen, dass Funktionen zum Zeitpunkt ihres Aufrufes bereits bekannt sind! &lt;br /&gt;
Wo dies nicht möglich ist (z.B. sich gegenseitig aufrufende Unterprogramme), oder wenn Sie das stört, müssen Sie Prototypen verwenden. &lt;br /&gt;
Wie definiert man nun Prototypen? Sie kopieren einfach die erste Zeile des Unterprogrammes (z.B. &amp;quot;&amp;lt;tt&amp;gt;void ausgeben (int zahl)&amp;lt;/tt&amp;gt;&amp;quot;), fügen einen Strichpunkt&amp;amp;nbsp;&amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;an und fügen es an einer geeigneten Stelle ein (so, dass alle Aufrufe später in der Datei kommen). &lt;br /&gt;
Solche Definitionen stehen gewöhnlich am Anfang der Quelldatei oder in einer Header-Datei, die eingebunden wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl);  /* Der Prototyp */&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
   ausgeben (12);&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl)   /* Die eigentliche Prozedur */&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Ausgabe: %d\n&amp;quot;, zahl);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Parameterübergabe==&lt;br /&gt;
&lt;br /&gt;
Alle Werte, die an Prozeduren und Funktionen übergeben werden, werden grundsätzlich '''kopiert'''.&lt;br /&gt;
Das hat folgende Auswirkungen:&lt;br /&gt;
&lt;br /&gt;
# Änderungen an einem Parameter in einer Funktion erscheinen ''nicht'' beim Aufrufer!&lt;br /&gt;
# Möchte man, dass eine Funktion einen Wert trotzdem dauerhaft ändern soll, so muss die Adresse des Wertes via [[#Zeiger|Zeiger]] übergeben werden.&lt;br /&gt;
# Werden [[#Strukturen|Strukturen]] übergeben, so wird von ihnen eine Kopie erstellt, was bei großen Strukturen viel Zeit und Arbeitsspeicher kostet. Deshalb wird häufig nur die Adresse von Strukturen übergeben, da die Adresse viel schneller und platzsparender als die Struktur selbst kopiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele:'''&lt;br /&gt;
 void erhoehe (int x)&lt;br /&gt;
 {&lt;br /&gt;
    x = x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe(a);&lt;br /&gt;
    {{comment|a ist immer noch 0}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Beim Aufruf von &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; wird eine Kopie des Wertes von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; (im Beispiel also 0) erstellt und der Prozedur als Parameter &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; übergeben. Weil dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat dies keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|erhoehe den Wert an der Adresse x um eins}}&lt;br /&gt;
    *x = *x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe (&amp;amp;a);&lt;br /&gt;
    {{comment|a ist jetzt 1}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Jetzt wird im Hauptprogramm mittels [[#Adress-Operator und Dereferenzierung|Adress-Operator]] &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; die Speicheradresse von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; bestimmt. Dann wird eine ''Kopie der Adresse'' an das Unterprogramm &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; übergeben. Jetzt kennt das Unterprogramm die&lt;br /&gt;
Adresse des Originals &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und kann direkt mit dem Inhalts-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&lt;br /&gt;
'''Besonderheit bei Feldern'''&lt;br /&gt;
&lt;br /&gt;
Bei der Übergabe von [[#Felder|Feldern]] gibt es eine Besonderheit. Schreibt man nämlich den Namen eines Feldes, so ist das nichts anderes als die '''Speicheradresse des ersten Elements'''.&lt;br /&gt;
Bei der Übergabe eines Feldes wird also eine Kopie der Startadresse übergeben. Somit kann das Unterprogramm auf den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 void erhoehe (int x[])&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
   int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
   erhoehe (a);&lt;br /&gt;
   {{comment|a hat jetzt folgenden Inhalte: 11, 23, 35}}&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Dass die Übergabe einer Adresse erfolgt, sieht man an folgendem Beispiel, das von der Funktionsweise '''absolut identisch''' mit dem vorhergehenden ist:&lt;br /&gt;
&lt;br /&gt;
 {{comment|Bei Parametern gibt es keinen Unterschied zwischen Zeiger und Feld}}&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
    int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
    erhoehe (a);&lt;br /&gt;
 &lt;br /&gt;
    {{comment|a hat jetzt folgenden Inhalt: 11, 23, 35}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
Die Länge des Feldes wird nicht automatisch übergeben. Dafür ist ggf. ein zusätzlicher Parameter notwendig.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Variable Argumentanzahl==&lt;br /&gt;
== Funktionen indirekt aufrufen ==&lt;br /&gt;
Siehe [[#Zeiger auf Funktionen|Zeiger auf Funktionen]]&lt;br /&gt;
&lt;br /&gt;
=Zeiger II=&lt;br /&gt;
&lt;br /&gt;
Zeiger haben wir bereits weiter oben kennen gelernt. Zeiger sind ein zentrales Konzept in C und sollen hier etwas eingehender behandelt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger-Arithmetik==&lt;br /&gt;
In C kann man den Wert eines Zeigers verändern. Betrachten wir dazu die Funktion &amp;lt;tt&amp;gt;suche_0&amp;lt;/tt&amp;gt;, die einen Zeiger auf einen &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; erhält. Die Funktion soll ab der gegebenen Adresse nach dem ersten long-Wert suchen, der 0 ist, und dessen Adresse zurückgeben:&lt;br /&gt;
 long * suche_0 (long * addr)&lt;br /&gt;
 {&lt;br /&gt;
    while (*addr != 0)&lt;br /&gt;
       addr = addr + 1;&lt;br /&gt;
 &lt;br /&gt;
    return addr;&lt;br /&gt;
 }&lt;br /&gt;
In der Bedingung der while-Schleife wird der Inhalt an der Speicherstelle &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf 0 getestet. Ist der Wert 0, dann wird die Schleife beendet und die Adresse zurückgeliefert. Ist der Wert ungleich 0, dann wird &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf den nächste long gesetzt, &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; also um 4 Bytes weitergezählt. &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ist ja ein Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, und ein &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; ist 4 Bytes lang.&lt;br /&gt;
&lt;br /&gt;
Die Bedeutung von&lt;br /&gt;
 address + n&lt;br /&gt;
ist also, die Adresse um das &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;-fache der Größe des Typs, auf den &amp;lt;tt&amp;gt;address&amp;lt;/tt&amp;gt; zeigt, zu erhöhen. Dabei ist &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; eine ganze Zahl und darf auch negativ sein.&lt;br /&gt;
&lt;br /&gt;
Hier noch ein Beispiel einer Funktion, die nach einer Person mit einer bestimmten ID sucht (für die Definition von &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; siehe [[#Strukturen|Strukturen]]). Der Parameter &amp;lt;tt&amp;gt;person&amp;lt;/tt&amp;gt; ist dabei ein Array von Strukturen. Eine Person mit der gesuchten ID muss existieren, ansonsten hat die Suchfunktion kein definiertes Verhalten.&lt;br /&gt;
 {{comment|Sucht nach einer Person mit der ID person_id}}&lt;br /&gt;
 struct Person * &lt;br /&gt;
 suche_person_id (struct Person * person, int person_id)&lt;br /&gt;
 {&lt;br /&gt;
    while (person-&amp;gt;id != person_id)&lt;br /&gt;
       person++;&lt;br /&gt;
 &lt;br /&gt;
    return person;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:1em; padding:1em; border:solid 2px #FF0040;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- Vorlage:FarbigerRahmen funzt hier net --&amp;gt;&lt;br /&gt;
Beachte, daß es nicht sinnvoll ist, zwei Zeiger zu addieren oder zu multiplizieren. Ausserdem ist das &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt; der Zeiger-Arithmetik nicht kommutativ. Eine Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, der an Adresse 1 im Speicher zeigt, wird man schreiben als&lt;br /&gt;
 (long *) 1&lt;br /&gt;
Addiert man darauf eine ganze Zahl, dann haben die entstehenden Ausdrücke unterschiedliche Werte:&lt;br /&gt;
 (long *) 1 + 2    {{comment|zeigt zu Adresse 9}}&lt;br /&gt;
 (long *) 2 + 1    {{comment|zeigt zu Adresse 6}}&lt;br /&gt;
 (long *) (1 + 2)  {{comment|zeigt zu Adresse 3}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==void-Pointer==&lt;br /&gt;
Eine besondere Art von Zeiger ist der void-Pointer&lt;br /&gt;
 void * addr;&lt;br /&gt;
Ein void-Pointer ist ein &amp;quot;Zeiger auf irgendwas&amp;quot;, dementsprechend kann er nicht dereferenziert werden, Anwenden von &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf einen solchen Zeiger gibt also einen Fehler. Ausserdem ist es nicht möglich, mit einem void-Pointer Zeigerarithmetik zu machen, weil er nicht auf eine definierte Art von Objekt zeigt. Der Vorteil eines void-Pointers ist, daß er jede Art von Zeiger aufnehmen kann.&lt;br /&gt;
&lt;br /&gt;
Dazu betrachten wir die Funktion &amp;lt;tt&amp;gt;send_buf&amp;lt;/tt&amp;gt;, die eine Adresse erhält und ab dieser Adresse &amp;lt;tt&amp;gt;num&amp;lt;/tt&amp;gt; Bytes versenden soll. Wir könnten die Funktion so schreiben:&lt;br /&gt;
 void send_buf (unsigned char * buf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   ...&lt;br /&gt;
Das ist jedoch hässlich, wenn wir damit etwas anderes verschicken wollen als &amp;lt;tt&amp;gt; unsigned char&amp;lt;/tt&amp;gt;, etwa eine Struktur wie &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; (vom Typ &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;):&lt;br /&gt;
 send_buf ((unsigned char*) &amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
Ohne den Cast der Adresse von &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; zu einem Zeiger auf &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt; bekommt man eine Warnung oder gar einen Compilerfehler.&lt;br /&gt;
Dieses Zeiger gecaste ist mühsam und hässlich, es muss bei jedem Aufruf der Funktion explizit hingeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Besser ist es, den ersten Parameter der Funktion als void-Pointer zu definieren und den Cast in der Funktion zu machen:&lt;br /&gt;
 void send_buf (void * vbuf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   unsigned char *buf = (unsigned char*) vbuf;&lt;br /&gt;
   ...&lt;br /&gt;
Durch den Cast in der Funktion kann auf den Inhalt des Zeigers zugegriffen werden. Man muss nur festlegen, ''wie'' man zugreifen will, nämlich als &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Der Aufruf kann jetzt ohne Pointer-Cast erfolgen: &lt;br /&gt;
 send_buf (&amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
&lt;br /&gt;
==Null-Pointer==&lt;br /&gt;
==Zeiger als Parameter==&lt;br /&gt;
Wenn Sie ein Unterprogramm aufrufen, können Sie diesem Parameter übergeben, aber keine Werte zurückgekommen (außer den Funktionswert bei Funktionen). Dies hat einen guten Grund: beim Aufruf werden nicht die aufgerufenen Parameter benutzt, sondern es werden deren Werte in neue Variablen kopiert. Diese Variablen werden am Ende des Unterprogrammes &amp;quot;zerstört&amp;quot;, ohne ihre Werte an die aufrufenden Parameter zu übergeben. Jede Veränderung eines Parameters hat daher keine Auswirkung auf den Parameter.&lt;br /&gt;
&lt;br /&gt;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der C-Compiler legt dann immer noch Kopien an. In dieser Kopie steht aber kein Wert, sondern die Adresse einer Varaiblen. Und auf diese können Sie dann zugreifen. Denken Sie nur an &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; &amp;amp;ndash; da übergeben Sie ja auch die Adresse einer Variablen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void erhoehe (int *zeiger)&lt;br /&gt;
{&lt;br /&gt;
  *zeiger = 1 + *zeiger;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  erhoehe (&amp;amp;zahl);&lt;br /&gt;
  printf (&amp;quot;\nDie erhoehte Zahl lautet: %d\n&amp;quot;, zahl);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Zeiger auf Funktionen==&lt;br /&gt;
&lt;br /&gt;
Stell dir vor, du willst einen Sortieralgorithmus wie Bubble-Sort oder Quick-Sort oder wie sie alle heissen implementieren. Für den Sortieralgorithmus ist eigentlich egal, ''was'' er zu sortieren hat. Ihm ist es egal, ob er Zahlen aufwärts sortieren soll oder Strings in lexikographischer Reihenfolge, ob Objekte nach Größe oder Gewicht, Personen nach Alter oder Adressen nach Postleitzahl. Das einzige, was der Algorithmus wissen muss, ist ''wie'' er zwei Objekte zu vergleichen hat und wann eines davon &amp;quot;kleiner&amp;quot; (im Sinne der Ordnung, nach der sortiert werden soll) ist. &lt;br /&gt;
&lt;br /&gt;
Eine einfache Sortierfunktion, die nur zwei Zahlen sortiert, könnte man also so schreiben: &lt;br /&gt;
 {{comment|Sortiert ein Array von 2 int-Zeigern nach den Inhalten &lt;br /&gt;
  * an den Zeiger-Adressen}}&lt;br /&gt;
 void sort2_a (int * p[])&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Inhalte vergleichen...}}&lt;br /&gt;
    if (*p[0] &amp;gt; *p[1])&lt;br /&gt;
    {&lt;br /&gt;
       {{comment|... und ggf. Dreieckstausch der 2 Zeiger}}&lt;br /&gt;
       int * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Die Funktion bekommt ein Array der Länge&amp;amp;nbsp;2. In diesem Array stehen Zeiger auf die zu sortierenden Zahlen. Ein Array mit Zeigern zu verwenden und nicht ein Array von &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; scheint recht umständlich, und das ist es hier auch. Aber stell dir vor, du willst Strukturen wie &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; sortieren. Das Tauschen zweier Strukturen würde bedeuten, ihre kompletten Inhalte umzukopieren! Das wäre sehr aufwändig. Viel einfacher ist das Kopieren, wenn nur die Adressen zu kopieren sind.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; könnte dann so aussehen:&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void sortiere (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|p[] enthält 2 int-Zeiger: die Adressen von a und b}}&lt;br /&gt;
    int * p[2];&lt;br /&gt;
    p[0] = &amp;amp;a; &lt;br /&gt;
    p[1] = &amp;amp;b; &lt;br /&gt;
 &lt;br /&gt;
    {{comment|Sortiere die Zeiger}} &lt;br /&gt;
    sort2_a (p);&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Sortiert: %d, %d\n&amp;quot;, *p[0], *p[1]);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Für den nächsten Schritt überlegen wir uns, daß das Array in &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; ebensogut void-Pointer enthalten kann. Die einzige Stelle, an der wir auf die endgültigen int-Objekte zugreifen, ist der Vergleich. Diesen Vergleich lagern wir in die Funktion &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; aus:&lt;br /&gt;
 {{comment|Bekommt zwei void-Pointer und vergleicht die Inhalte.&lt;br /&gt;
  * Liefert 0 bei Gleichheit,&lt;br /&gt;
  * -1 wenn der erste Wert kleiner ist als der zweite und&lt;br /&gt;
  * 1  wenn der erste Wert größer ist als der zweite}}&lt;br /&gt;
 int compare_int (void * p0, void * p1)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Um über die Zeiger zugreifen zu können müssen wir diese&lt;br /&gt;
     * erst zu int-Zeigern casten}}&lt;br /&gt;
    int a0 = * (int*) p0;&lt;br /&gt;
    int a1 = * (int*) p1;&lt;br /&gt;
 &lt;br /&gt;
    if (a0 &amp;gt; a1)  return  1;&lt;br /&gt;
    if (a0 &amp;lt; a1)  return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void sort2_b (void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare_int (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Ein Aufruf von &amp;lt;tt&amp;gt;sort2_b&amp;lt;/tt&amp;gt; sieht dann genauso aus wie ein Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt definieren wir uns den neuen Datentyp &amp;lt;tt&amp;gt;comparator_t&amp;lt;/tt&amp;gt;. Dieser ist ein Zeiger auf eine Funktion, die zwei void-Pointer erhält und einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; zurückliefert, also analog arbeitet zu &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; von oben. &lt;br /&gt;
&lt;br /&gt;
Unsere Sortierfunktion bekommt nun neben dem zu sortierenden Zeiger-Array auch eine Vergleichsfunktion &amp;lt;tt&amp;gt;compare&amp;lt;/tt&amp;gt; mitgeliefert, die sie aufruft, wenn sie zwei Objekte vergleichen will&lt;br /&gt;
 {{comment|comparator_t sind Zeiger auf Funktionen, die 2 void-Pointer&lt;br /&gt;
  * erhalten und einen int zurückliefern}}&lt;br /&gt;
 typedef int (*comparator_t) (void*, void*);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Der Sortierer bekommt einen Funktionszeiger auf den Vergleicher.&lt;br /&gt;
  * Der Aufruf vom compare geht so als wäre es eine &amp;quot;normale&amp;quot; Funktion&lt;br /&gt;
  * (ist es im Endeffekt ja auch)}}&lt;br /&gt;
 void sort2_c (comparator_t compare, void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Bei einem Aufruf von &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; muss man dann einen Komparator mit angeben. In einem Beispiel analog zu &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; von oben ist das:&lt;br /&gt;
 sort2_c (compare_int, p);&lt;br /&gt;
Um zwei Strings lexikographisch zu sortieren nehmen wie die Standard-Funktion &amp;lt;tt&amp;gt;strcmp&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void foo()&lt;br /&gt;
 {&lt;br /&gt;
    char * worte[] = { &amp;quot;Wort1&amp;quot;, &amp;quot;Wort2&amp;quot; };&lt;br /&gt;
 &lt;br /&gt;
    sort2_c ((comparator_t) strcmp, (void**) worte);&lt;br /&gt;
 }&lt;br /&gt;
Die Casts sind hier erforderlich. Alternativ könnte man &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; mit reinen void-Pointern versorgen und diese dann dort umcasten.&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
&lt;br /&gt;
Die Syntax zur Definition/Deklaration von Funktionszeigern ist etwas verzwackt. Zur Verdeutlichung ein paar Beispiele. Dabei legt das linke &amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt; jeweils den Return-Typ fest.&lt;br /&gt;
 {{comment|definiert einen neuen Funktionszeiger-Typ}}&lt;br /&gt;
 typedef {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert einen Funktionszeiger}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert ein Array von Funktionszeigern (mit Initializer)}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}[]) ({{type}}, {{type}}, ...) = { wert1, wert2, ... };&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer}}&lt;br /&gt;
 ({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer und ruft die Funktion auf}}&lt;br /&gt;
 (({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}) (arg1, arg2, ...);&lt;br /&gt;
&lt;br /&gt;
=Standard-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==String-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===strcpy===&lt;br /&gt;
Bei vielen Compilern können sie einem String nicht direkt einen Wert (Text) zuweisen. Dazu müssen Sie dann die Prozedur strcpy() benutzen. Diese erwartet als ersten Parameter den Namen einer String-Variablen (ohne eckige Klammern) und als zweiten Parameter den eines (anderen) Strings. Letzterer kann auch ein in doppelten Hochkommas (&amp;quot;) eingeschlossener Text sein. Die Funktion fügt am Ende automatisch ein 0-Zeichen ein. Um diese Funktion nutzen zu können, müssen Sie die Datei string.h includieren! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri1[21], eingabe[21];&lt;br /&gt;
&lt;br /&gt;
  strcpy (stri1, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Der 1. String: %s\n&amp;quot;, stri1);&lt;br /&gt;
  printf (&amp;quot;Bitte geben Sie maximal 20 Zeichen ein: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%s&amp;quot;, eingabe);&lt;br /&gt;
  strcpy (stri1, eingabe);&lt;br /&gt;
  printf (&amp;quot;\n%s = %s&amp;quot;, stri1, eingabe);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis:''' &lt;br /&gt;
Da ein String, wie jedes Feld, eigentlich ein Zeiger ist, dürfen Sie kein &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; bei &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; angeben!&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
Es werden zwei gleich große Strings definiert: &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;eingabe&amp;lt;/tt&amp;gt;, mit je 20 &amp;quot;nutzbaren&amp;quot; Zeichen. &lt;br /&gt;
In &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; wird die Zeichenkette &amp;lt;tt&amp;gt;&amp;quot;hallo&amp;quot;&amp;lt;/tt&amp;gt; hineinkopiert. Das 0-Zeichen am Ende wird automatisch angefügt. &lt;br /&gt;
Der String wird ausgegeben. Als neues &amp;quot;Sonderzeichen&amp;quot; kommt &amp;lt;tt&amp;gt;%s&amp;lt;/tt&amp;gt; ins Spiel. Es hat die gleiche Aufgabe wie &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt;, nur für Strings. &lt;br /&gt;
Sie werden gebeten, eine String einzugeben. &lt;br /&gt;
Dieser String wird danach in die Variable &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; kopiert. &lt;br /&gt;
Beide Strings, die ja nun die gleiche Zeichenkette enthalten, werden ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===strlen===&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;strlen&amp;lt;/tt&amp;gt;, die als Parameter eine String-Variable erwartet, liefert die Länge diese Strings zurück. Sie werden jetzt vermutlich sagen: &amp;quot;Das ist doch klar, wie lang der String ist. Ich habe es ja bei der Deklaratin angegeben&amp;quot;. Das stimmt schon, aber denken Sie noch einmal an die null-terminierten Strings. Das 0-Zeichen steht am Ende des Strings (am Ende der gültigen Zeichenfolge), aber nicht unbedingt am Ende des reservierten Speicherplatzes. Haben Sie eine Variable &amp;quot;char Variable[21];&amp;quot;, und ihr den Wert &amp;quot;hallo&amp;quot; zugewiesen, dann steht das null-Zeichen in Variable[5]. Der &amp;quot;gültige&amp;quot; String ist also 5 Zeichen (0-4) lang. Und genau das (5) würde strlen zurück liefern. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri[21];&lt;br /&gt;
  &lt;br /&gt;
  strcpy (stri, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
  printf (&amp;quot;Der String ist %d Zeichen lang&amp;quot;, strlen (stri));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird vor allem gebraucht, wenn Sie direkt auf den String zugreifen, mittels &amp;lt;tt&amp;gt;stri[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;stri[1]&amp;lt;/tt&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
==Ein- und Ausgabe-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===Bildschirm-Ausgabe===&lt;br /&gt;
Bisher war das Tutorial trotz aller Beispiele reine Theorie. Sie konnten zwar Programme schreiben, aber die Funktion nicht testen. Hier lernen Sie nun, wie Sie etwas am Bildschirm ausgeben.&lt;br /&gt;
&lt;br /&gt;
Die dazu notwendige Funktione heisst &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (das '&amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt;' ist kein Fehler!). Diese Anweisung gibt die ihr übergebenen Parameter auf das Standard-Ausgabegerät aus, in der Regel also auf den Bildschirm. Sie kann beliebig viele Parameter übernehmen. Es müssen jedoch Standard-Datentypen (z.B. &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;...) sein! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
    int zahl1 = 12;&lt;br /&gt;
    char zeichen1 = 'A';&lt;br /&gt;
    &lt;br /&gt;
    printf (&amp;quot;Das ist Text, und er wird als solcher ausgegeben. \n&amp;quot;);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zahl1' ist: %d \n&amp;quot;, zahl1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %c \n&amp;quot;, zeichen1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %d \n&amp;quot;, zeichen1);&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt Text aus. Das Zeichen am Ende (&amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;) bedeutet &amp;quot;New Line&amp;quot;, es bewegt den Cursor an den Anfang der nächsten Zeile. &lt;br /&gt;
&lt;br /&gt;
Der zweite &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt auch Text aus, am Ende befindet sich wieder das &amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;, um einen Zeilenvorschub zu erreichen. Das &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; wird vom Compiler durch den ersten Parameter ersetzt, der nach dem Text angegeben wird. In diesem Fall wird &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; also durch den Wert der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ersetzt. Das &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; im &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; bedeutet &amp;quot;Dezimalzahl&amp;quot;, der Computer gibt also eine ganze Zahl aus. &lt;br /&gt;
&lt;br /&gt;
In der dritten Ausgabe wird ein Zeichen ausgegeben. Diesmal bedeutet &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; &amp;quot;char&amp;quot; (Zeichen). Es wird also &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; durch ein &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt; ersetzt, denn die Variable &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; wird als Character interpretiert. &lt;br /&gt;
&lt;br /&gt;
Die letzte Ausgabe interpretiert den Inhalt von &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; als Zahl, und gibt dager den ASCII-Wert von &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, also 65 aus. Das ist ein typisches Beispiel für das mögliche unterschiedliche Interpretieren einer  Variablen!&lt;br /&gt;
&lt;br /&gt;
===Tastatur-Eingabe===&lt;br /&gt;
&lt;br /&gt;
Um ein &amp;quot;gscheites&amp;quot; Programm schreiben zu können, muß man wissen, wie der Benutzer über die Tastatur Befehle eingeben kann. Die dafür notwendigen Funktionen stelle ich in diesem Kapitel vor.&lt;br /&gt;
Die wichtigste Funktion ist &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt;. Er liest Daten von der Tastatur. Die Syntax entspricht derer von &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int  zahl1;&lt;br /&gt;
char zeichen1;&lt;br /&gt;
&lt;br /&gt;
printf (&amp;quot;Bitte geben Sie eine Zahl ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl1);&lt;br /&gt;
printf (&amp;quot;Geben Sie einen Zeichen ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%c&amp;quot;, &amp;amp;zeichen1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Programm gibt eine Eingabeaufforderung aus. Dann erwartet es vom Benutzer, daß er eine Zahl eingibt, die mit [ENTER] bestätigt wird. Dieser Wert wird in &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; abgespeichert. Danach erfolgt wiederum eine Aufforderung zur Eingabe, diesmal eines einzelnen Zeichens. Dieses kann man nun eingeben und ebenfalls mit [ENTER] bestätigen.&lt;br /&gt;
&lt;br /&gt;
Macht man keine dem Datentyp der erwarteten Variable entsprechende Eingabe, dann bricht das Programm mit einer Fehlermeldung ab (wenn man z.B. &amp;quot;1_T2&amp;quot; eingibt, wenn eine Zahl erwartet wird)!&lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; vor den Parametern ist notwendig. Warum, das erfahren Sie im Kapitel &amp;quot;Unterprogramme&amp;quot;. Für die Profis eine Kurz-Erklärung: Das Unterprogramm &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; bekommt zwar einen Wert übergeben, kann aber keinen zurückliefern (&amp;quot;call by value&amp;quot;). Daher wird kein Wert, sondern ein Zeiger auf eine Variable übergeben. Mit dem &amp;amp; Zeichen bekommen Sie die Adresse einer Variablen (&amp;quot;call by reference&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=Parameter von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;=&lt;br /&gt;
Das Unterprogramm &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; kann, wie jede andere Funktion, Parameter besitzen. Doch keine selbst gewählten, sondern nur bestimmte. Doch warum braucht main Parameter? Denken Sie einmal an alle Betriebssystembefehle:&lt;br /&gt;
&amp;lt;tt&amp;gt;dir *.exe &amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;copy *.* a:&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;ls -la &amp;lt;/tt&amp;gt;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;&amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen!&lt;br /&gt;
&lt;br /&gt;
=Kurzreferenz=&lt;br /&gt;
==Syntax-Bausteine==&lt;br /&gt;
&lt;br /&gt;
Die Erklärung des Aufbaus von C-Befehlen erfolgt neben einfachen Beispielen auch durch ihren prinzipellen Aufbau. In diesen Syntax-Beschreibungen finden sich immer wieder die gleichen Bausteine, die hier näher erklärt werden sollen. Falls die solch ein Syntax-Baustein begegnet, kannst Du ihn anclicken und kommst dann zu seiner Erläuterung. &lt;br /&gt;
&lt;br /&gt;
In den Beispielen selbst gehören auch die spitzen Klammern zu dem Baustein (was daran zu erkennen ist, daß auch die Klammern eingefärbt sind). Die Klammern dürfen in einem konkreten C-Programm daher nicht eingetippt werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bezeichner&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Bezeichner in C dienen dazu, Variablen zu identifizieren und ihnen sprechende Namen zu geben, um die Quelle lesbarer zu machen. Man braucht Bezeichner auch, um selbstdefinierte Datentypen zu benennen und zum Benennen von Struct- und Union-Komponenten sowie als Namen für Funktionen und Sprungmarken (Labels).&lt;br /&gt;
&lt;br /&gt;
Bezeichner dürfen aus den Kleinbuchstaben &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;z&amp;lt;/tt&amp;gt;, den Großbuchstaben &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;Z&amp;lt;/tt&amp;gt;, dem Unterstrich&amp;amp;nbsp;&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt; und den Ziffern &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;9&amp;lt;/tt&amp;gt; aufgebaut werden, wobei an erster Stelle jedoch keine Ziffer stehen darf.&lt;br /&gt;
&lt;br /&gt;
Es wird zwischen Groß- und Kleinschreibung unterschieden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Ausdruck in C ist ein Konstrukt, das einen Wert hat. Ob dieser Wert eine ganze Zahl ist, eine Kommazahl oder ein Zeiger, etc. ist dabei egal. Die einfachsten Ausdrücke sind Konstanten wie&lt;br /&gt;
 2&lt;br /&gt;
oder Variablen wie&lt;br /&gt;
 ein_zahl&lt;br /&gt;
Mehrere Ausdrücke können durch [[#Liste der Operatoren|Operatoren]] zu komplexeren Ausdrücken kombiniert werden, etwa&lt;br /&gt;
 eine_zahl + andere_zahl == 2&lt;br /&gt;
oder &lt;br /&gt;
 eine_zahl = 2&lt;br /&gt;
Letzterer hat den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; und den Nebeneffekt, daß er diesen Wert an &amp;lt;tt&amp;gt;eine_zahl&amp;lt;/tt&amp;gt; zuweist.&lt;br /&gt;
&lt;br /&gt;
Auch der Aufruf einer Funktion, die einen Rückgabewert liefert, ist ein Ausdruck:&lt;br /&gt;
 sin (1.2)&lt;br /&gt;
und kann zum Aufbau komplexerer Ausdrüche verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bedingung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Bedingung ist ein Ausdruck, bei der nur interessiert, ob dieser zu&amp;amp;nbsp;0 (unwahr) auswertet oder zu ungleich&amp;amp;nbsp;0 (wahr). Solche Ausdrücke findet man in if-Anweisungen, in Schleifenbedingungen und bedingten Zuweisungen&lt;br /&gt;
 (ein_wert &amp;lt; 2) || (ein_wert &amp;gt; 40)&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Lvalue ist ein Ausdruck, dem etwas zugewiesen werden kann. Der Name ''Lvalue'' kommt aus dem Englischen. Das ''L'' steht abkürzend für left. Ein Lvalue ist damit ein Ausdruck, der auf der linken Seite eine Zuweisung in C stehen darf. Das &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; in den folgenden Beispiel-Ausdrücken muss ein Lvalue sein:&lt;br /&gt;
 x = y-1&lt;br /&gt;
&lt;br /&gt;
 x++&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Konstante&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Konstante ist ein Ausdruck, dessen Wert dem Compiler bekannt ist. Beispiele für Konstanten sind etwa&lt;br /&gt;
 7&lt;br /&gt;
 'B'&lt;br /&gt;
 -13.98e12&lt;br /&gt;
 1+(2*3)&lt;br /&gt;
und die Werte von [[#Enum|Enum]]s. &lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; aus dem folgenden Codestück definiert jedoch keine Konstante in diesem Sinne&lt;br /&gt;
 const double Pi = 3.14159256;&lt;br /&gt;
denn in einem anderen Quellmodul könnte durch die Deklaration&lt;br /&gt;
 extern const double Pi;&lt;br /&gt;
das Symbol &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; bekannt sein, ohne daß sein Wert bekannt ist!&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Adresse&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Adresse ist ein Ausdruck, der einen Speicherort (physikalisch oder virtuell) halten kann. Adressen erhält man dadurch, daß man einem Bezeichner den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt;voranstellt, Adressen durch Arithmetik berechnet oder Zahlen zu Adressen castet. Folgende Ausdrücke sind Adressen (eine sinnvolle Deklaration der auftretenden Variablen vorausgesetzt)&lt;br /&gt;
 &amp;amp; eine_zahl&lt;br /&gt;
 &amp;amp; ein_array[10]&lt;br /&gt;
 &amp;amp; ein_struct&lt;br /&gt;
 &amp;amp; ein_struct.komponente&lt;br /&gt;
 (int *) 0x1234&lt;br /&gt;
 (int *) eine_zahl&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Deklaration&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Anweisungen sind gewissermassen die Atome (oder Moleküle?), aus denen ein C-Programm besteht. Jedes C-Programm ist eine Abfolge von Deklarationen und Anweisungen. Einfache Anweisungen erhält man, in dem man einen Ausdruck nimmt und einen Strichpunkt dahinter schreibt:&lt;br /&gt;
 {{Ausdruck|}};&lt;br /&gt;
wie in&lt;br /&gt;
 x = x+1;&lt;br /&gt;
&lt;br /&gt;
Andere Anweisungen sind die unten aufgeführten Schleifen und die if- sowie die switch-Anweisung.&lt;br /&gt;
&lt;br /&gt;
Mehrere Deklarationen und Anweisungen können zu einem Block zusammengefasst werden. Dieser Block stellt dann wieder eine einzelne Anweisung dar und kann genau so gehandhabt werden!&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
In diesem Sinne ist auch z.B. die Syntax der if-Anweisung zu verstehen&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
besagt, daß der abhängig ausgeführte Code eine einzelne Anweisung sein darf oder eben ein kompletter Block oder die Verschachtelung mehrerer Blöcke etc.&lt;br /&gt;
&lt;br /&gt;
Eine Anweisung kann auch &amp;quot;leer&amp;quot; sein, also nichts tun. Diese Anweisungen sind der leere Block&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
und der Strichpunkt&lt;br /&gt;
 ;&lt;br /&gt;
die man gelegentlich in Schleifen findet:&lt;br /&gt;
 while (!timeout())&lt;br /&gt;
    {}&lt;br /&gt;
oder hinter Sprungmarken, die sonst direkt vor einer schliessenden Blockklammer stünden:&lt;br /&gt;
 {&lt;br /&gt;
    ...&lt;br /&gt;
    goto ein_label;&lt;br /&gt;
    ...&lt;br /&gt;
    {{Label|ein_label}}:;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Nicht jede Anweisung ist an jeder Stelle eines C-Programms erlaubt, so darf ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; nut innerhalb einer Schleife stehen. Gleiches gilt für &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;, das aber auch innerhalb eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; vorkommen darf.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Dies steht für einen Datentyp. Es kann ein elementarer Typ sein wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;, ein Zeiger darauf wie &amp;lt;tt&amp;gt;char*&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;void*&amp;lt;/tt&amp;gt;, und auch Qualifier enthalten wie das &amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt; im Typ &amp;lt;tt&amp;gt;unsigned long long&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Zu den Typen gehören auch zusammengesetzte Datentypen wie Strukturen und Unions, mit &amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt; selbst definierte Typen und natürlich Zeiger darauf, wie aus dem Abschnitt [[#Datentypen|Datentypen]]:&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person *&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;data32_t&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;&lt;br /&gt;
und Zeiger auf Funktionen.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Parameterliste&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
Die Parameterliste bei einer Funktionsdefinition gibt an, wieviel Übergabeparameter sie bekommt, wie diese heissen und welchen Typs diese sind. Der prinzipielle Aufbau ist&lt;br /&gt;
 {{Type}} {{Bezeichner}}, {{Type}} {{Bezeichner}}, ...&lt;br /&gt;
Falls die Funktion keine Parameter hat, dann ist die Parameterliste leer.&lt;br /&gt;
&lt;br /&gt;
Hier als Beispiel die zweiparametrige Funktion &amp;lt;tt&amp;gt;produkt&amp;lt;/tt&amp;gt;. Der erste Parameter heisst&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und ist ein &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;. Der zweite namens&amp;amp;nbsp;&amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; ist vom Typ &amp;quot;Zeiger auf double&amp;quot;, der Inhalt &amp;lt;tt&amp;gt;*b&amp;lt;/tt&amp;gt; ist also auch ein double.&lt;br /&gt;
&lt;br /&gt;
'''Definition der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b)&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
In älteren C-Quellen findet man noch eine andere Syntax für die Deklaration der Parameter, die aber heute praktisch nicht mehr verwendet wird:&lt;br /&gt;
'''alte Definition der Funktion:'''&lt;br /&gt;
 double produkt (a, b)&lt;br /&gt;
 double a, *b;&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Um die Funktion bekannt zu machen, werdendet man eine Deklaration bzw. den Prototypen, der dem Compiler nur mitteilt, welche Parameter die Funktion bekommt und was sie zurückliefert. Für den Aufruf der Funktion muss der Compiler nur diesen Prototyp kennen, ''was'' die Funktion im Endeffekt macht und wie sie implementiert wurde ist egal, sie wird als BlackBox angesehen.&lt;br /&gt;
&lt;br /&gt;
'''Prototyp der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b);&lt;br /&gt;
Hier dürfen die Bezeichner auch fehlen:&lt;br /&gt;
 double produkt (double, double*);&lt;br /&gt;
&lt;br /&gt;
==if==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==if-else==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==for==&lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Eine for-Schleife entspricht folgendem Konstrukt. Dabei sind die drei Ausdrücke optional. Fehlt die Bedingung, dann wird diese als &amp;quot;wahr&amp;quot; angenommen. Die beiden anderen Ausdrücke wird man als Ausdrücke mit Nebeneffekt wählen wie z.B. &amp;lt;tt&amp;gt;x=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;x=x-2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
 {&lt;br /&gt;
    {{Ausdruck|1}};&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_loop}}:&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
    else&lt;br /&gt;
       goto _break;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_continue}}:&lt;br /&gt;
    {{Ausdruck|2}};&lt;br /&gt;
    goto _loop;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_break}}:;&lt;br /&gt;
 }&lt;br /&gt;
Die Labels &amp;lt;tt&amp;gt;_break&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_continue&amp;lt;/tt&amp;gt; entsprechen den Sprungzielen einer &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Anweisung innerhalb von &amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==do-while==&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while  ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
==while==&lt;br /&gt;
 while  ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==switch==&lt;br /&gt;
 switch  ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    ...&lt;br /&gt;
  &lt;br /&gt;
    default:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#break-Anweisung|&amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Konstanten|&amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#continue-Anweisung|&amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#do-while-Schleife|&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Enum|&amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#for-Schleife|&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#goto-Anweisung|&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#return-Anweisung|&amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Liste der Operatoren|sizeof]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Strukturen|&amp;lt;tt&amp;gt;struct&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Eigene Datentypen|&amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Unions|&amp;lt;tt&amp;gt;union&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#while-Schleife|&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund2}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Arithmetische Operatoren&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Dies sind die &amp;quot;normalen&amp;quot; arithmetischen Operationen, wie man sie aus der Schule kennt. Man kann damit und allen anderen Operatoren auch komplexere Ausdrücke aufbauen. Die Prioritäten sind so, wie man sie kennt, also &amp;quot;Punktrechnung vor Strichrechnung&amp;quot;. Will man dies ändern, dann mit den runden Klammern:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;1+2*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 7&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(1+2)*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 9&amp;lt;br/&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}}&amp;amp;nbsp;+&amp;amp;nbsp;{{Ausdruck|}}&amp;lt;/tt&amp;gt; || Addition&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} - {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Subtraktion&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} * {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Multiplikation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} / {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Division&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} % {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Rest der Division (modulo)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;- {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Vorzeichenumkehr, Zweier-Komplement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Logische Operatoren und Vergleiche&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die logischen und die vergleichenden Operatoren liefern als Ergebnis den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (wahr) oder einen Wert ungleich&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (falsch, um genau zu sein den Wert &amp;lt;tt&amp;gt;!0&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Man kann das Ergebnis zwar einer Variablen zuweisen, in aller Regel wird man solche Ausdrücke jedoch in Bedingungen zu &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder in Abbruch-Bedingungen von Schleifen finden.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;&amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches AND: beides wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124;&amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches OR: mind. eines ist wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;! {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches NOT (0 &amp;amp;harr; ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} == {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} != {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist nicht gleich&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bitweise Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~ {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise NOT (Einser-Komplement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise AND&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise ODER&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} ^ {{Ausdruck|}}&amp;lt;/tt&amp;gt; ||bitweise XOR&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Shift-Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;lt;&amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Bits nach links schieben&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;gt;&amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Schieben nach rechts schieben&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Typen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Ein Cast in C kann dazu verwendet werden, den Typ eines Ausdruckes zu ändern oder den Ausdruck mit einer bestimmten Genauigkeit zu berechnen. Wird z.B. eine Berechnung standardmässig in 16 Bit ausgeführt, dann kann man mit einem Cast &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(long) &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
ausdrücken, daß die Berechnung in 32 Bit erfolgen soll. Des weiteren kann man Zeiger und ganze Zahlen und Gleitkommazahlen ineinander umwandeln.&lt;br /&gt;
&lt;br /&gt;
Casts können ''nicht'' dazu verwendet werden, um z.B. eine Zahl in einen String zu konvertieren, der diese Zahl darstellt! Dafür gibt es spezielle Funktionen wie &amp;lt;tt&amp;gt;itoa&amp;lt;/tt&amp;gt;!&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Type}}) {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Cast, Typwandlung&lt;br /&gt;
|-&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;| &amp;lt;tt&amp;gt;sizeof ({{Type}})&amp;lt;/tt&amp;gt; || Eine Konstante, deren Wert die Größe (in Bytes) des Typs ist. &amp;lt;tt&amp;gt;sizeof&amp;lt;/tt&amp;gt; ist auch auf Objekte anwendbar wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, Arrays bekannter Größe, Strukturen und Unions,  Array-, Struktur- und Union-Komponenten, Pointer, etc. Beispiel:&amp;lt;br/&amp;gt;&lt;br /&gt;
 int i, sum=0, array[] = { 1, -13, 4, 0, sizeof (int*) };&lt;br /&gt;
 &lt;br /&gt;
 for (i=0; i&amp;lt; sizeof (array) / sizeof (array[0]); i++)&lt;br /&gt;
    sum += array[i];&lt;br /&gt;
Alle Elemente des Arrays werden aufaddiert, ohne daß deren Anzahl explizit in der Schleife genannt ist.&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zeiger und Adressen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;* {{Adresse}}&amp;lt;/tt&amp;gt; || der Inhalt an Adresse&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp; {{Lvalue}}&amp;lt;/tt&amp;gt; || Adresse von&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Strukturen, Unions, Arrays&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Struct&amp;gt;}}.{{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Zeiger-auf-Struct&amp;gt;}} -&amp;gt; {{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union, deren Adresse man hat&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Adresse}}&amp;amp;#91;{{Ausdruck|}}&amp;amp;#93;&amp;lt;/tt&amp;gt; || Array-Element&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bedingte Auswertung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Bedingung}}) ? {{Ausdruck|}} : {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Auswahl des Wertes abhängig von der Bedingung&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zuweisung und Operatoren mit Nebeneffekt&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die Unterschiede der post- und pre-Varianten der Increment/Decrement kommen in Konstrukten wie &amp;lt;tt&amp;gt;x = *p++&amp;lt;/tt&amp;gt; zum tragen:&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *p++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; p = p+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *++p;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; p = p+1; x = *p;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = (*p)++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; *p = (*p)+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = ++(*p);&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; *p = (*p)+1; x = *p;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} = {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Zuweisung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++ {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-- {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Decrement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ++&amp;lt;/tt&amp;gt; || Post-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} --&amp;lt;/tt&amp;gt; || Post-Decrement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Kurzschreibweisen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Für ganz Faule gibt es anstatt&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a = a @ b&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
für viele Operatoren (hier dargestellt durch ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;@&amp;lt;/tt&amp;gt;) die abkürzende Schreibweise&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a @= b&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} += {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} -= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} *= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} /= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} %= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ^= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;lt;&amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;gt;&amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Autoren'''&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
* Kernighan und Ritchie - Buch&lt;br /&gt;
* Christian Wirth , C Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://wwwuser.gwdg.de/~kboehm/ebook/inhalt.html C-Programmieren unter Linux]&lt;br /&gt;
* [http://www.gdv.uni-hannover.de/documentation.php Skripte zum Selbststudium: C, C++, Java, etc]&lt;br /&gt;
* [http://info.baeumle.com/ansic.html Einführung in ANSI-C]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Quellcode C|!]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Inrfb2</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10389</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10389"/>
				<updated>2007-03-13T10:44:11Z</updated>
		
		<summary type="html">&lt;p&gt;Inrfb2: /* Arrays */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Programmiersprache C wurde 1971 als Gundlage für das Betriebssystem UNIX in den USA entwickelt (UNIX ist zu über 90% in C geschrieben). 1978 wurde von Brian Kernighan und Dennis Ritchie eine eindeutige Sprachdefinition entwickelt. Mittlerweile ist C von ANSI und ISO standardisiert.&lt;br /&gt;
&lt;br /&gt;
Heute sind C und ihr Nachfolger C++ die dominierenden Programmiersprachen. Sehr viele Anwendungen sind in C geschrieben, was inzwischen auch auf eingebettete Systeme zutrifft, die lange in Assembler programmiert werden mussten, da keine ausreichend leistungsfähigen Compiler zur Verfügung standen. &lt;br /&gt;
&lt;br /&gt;
Leider ist C nicht einfach zu lernen &amp;amp;ndash; es wurde weder von noch für Hobby-Programmierer entwickelt &amp;amp;ndash; und eignet sich daher nur bedingt für den Einsteiger. Mit etwas Übung und einem optimierenden Compiler kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
Vom Design her ist C eine Hardware-unabhängig Sprache. Das bedeutet, daß C-Programme mit vertretbarem Aufwand auf ein anderes System portiert werden können. Dazu benötigt man lediglich einen anderen Compiler, und Inline-Assembler-Anweisungen (Assembleranweisungen innerhalb eines C-Programmes) müssen der neuen Hardware (Prozessor) angepasst werden. &lt;br /&gt;
&lt;br /&gt;
==Geschichte==&lt;br /&gt;
;1971: C wird entwickelt&lt;br /&gt;
;1978: Kernighan und Ritchie definieren die Sprache.&lt;br /&gt;
;1983: ANSI und ISO standardisieren C.&lt;br /&gt;
;1992: Bjarne Stroustrup enwickelt die Nachfolgesprache C++.&lt;br /&gt;
&lt;br /&gt;
=Aufbau eines C-Programmes=&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
   C-Programme haben keinen fixen Aufbau wie z.B. Pascal. Es gibt zwar gewisse Regeln, aber sonst sind dem Programmierer alle Freiheiten überlassen. Der folgende &amp;quot;Beispiel-Aufbau&amp;quot; ist daher nicht zwingend und kann durchaus verändert werden.&lt;br /&gt;
&lt;br /&gt;
   Natürlich haben C-Programme einen fixen Aufbau! Ebenso wie Pascal-Programme auch unterliegen sie einer strikten Grammatik! &lt;br /&gt;
Auskommentiert --[[Benutzer:SprinterSB|SprinterSB]] 10:23, 17. Feb 2006 (CET)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Ein einfaches C-Programm könnte folgendermassen aussehen. Das Programm tut eigentlich nichts, aber das Beispiel zeigt den prinzipiellen Aufbau. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 int Zahl1;&lt;br /&gt;
 char Zeichen1;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int zahl2;&lt;br /&gt;
 &lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Beschreibung:'''&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndash; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
 {{comment|void-Definition von main ist nur beim Controller ueblich}}&lt;br /&gt;
 {{comment|spezielle Compilereinstellungen sind noetig, damit bei dieser Definition von main}}&lt;br /&gt;
 {{comment|kein Fehler/Warnung erzeugt wird.}}&lt;br /&gt;
 void main ()&lt;br /&gt;
 {&lt;br /&gt;
     ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
 int main (void)&lt;br /&gt;
 {  {{comment|der Block &amp;quot;main&amp;quot; beginnt}}&lt;br /&gt;
    int zahl;&lt;br /&gt;
    &lt;br /&gt;
    {   {{comment|ein Block beginnt}}&lt;br /&gt;
        {{comment|hier koennen Deklarationen und Anweisungen stehen}}&lt;br /&gt;
    }   {{comment|der Block endet}}&lt;br /&gt;
   &lt;br /&gt;
    return 0;&lt;br /&gt;
 }  {{comment|&amp;quot;main&amp;quot; endet}}&lt;br /&gt;
&lt;br /&gt;
=Datentypen=&lt;br /&gt;
==Elementare Datentypen==&lt;br /&gt;
Der Datentyp einer Variable gibt an, welche Werte eine Variable enthalten kann, welcher Art diese Daten sind und wie sie verarbeitet werden, etwa in arithmetischen Operationen wie einer Addition. So ist es zum Beispiel möglich, in eine Variable vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ganze Zahlen zwischen ca. -32000 und +32000 einzutragen. In einer char-Variable können ASCII-Zeichen gespeichert werden (alles, was Sie mit der Tastatur erzeugen können) oder ganze Zahlen von -128 bis 127.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da C plattformabhängig ist, hängt die Größe eines Datentypes zum Teil von der genutzten Hardware (z.B. 8, 16 oder 32 Bit-Controller) und dem Compiler und dessen Einstellungen ab!&lt;br /&gt;
&lt;br /&gt;
===int, char, short, long (ganze Zahlen)===&lt;br /&gt;
In Variable dieser Typen können Sie ganze Zahlen abspeichern, also z.B. 1, &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;2, 100, 12345. Jeden dieser Typen gibt es in zwei Ausprägungen: als &amp;quot;&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;quot;, also als vorzeichenbehafteten Typ, und als &amp;quot;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&amp;quot;, also ohne Vorzeichen, d.h. das Vorzeichen wird als 0 oder +1 genommen. &lt;br /&gt;
&lt;br /&gt;
Vorzeichenbehaftete Ganzzahl-Typen werden intern im &amp;lt;tt&amp;gt;n-1&amp;lt;/tt&amp;gt;-Komplement dargestellt, das Vorzeichen selbst findet sich also im höchstwertigen Bit. Werden zur Speicherung ''b'' Bits verwendet, dann reicht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;z.B. *zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==Enum==&lt;br /&gt;
&lt;br /&gt;
Über &amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt; können Aufzählungen definiert werden. Die Werte sind &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Werte und beginnen mit&amp;amp;nbsp;0. Der folgende enum hat einen um&amp;amp;nbsp;1 grösseren Wert. Mit einer Zuweisung können auch andere Werte zugeordnet werden. Klarer wird's im Beispiel:&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 enum Farben&lt;br /&gt;
 {&lt;br /&gt;
    ROT,&lt;br /&gt;
    GRUEN,&lt;br /&gt;
    BLAU,&lt;br /&gt;
    BRAUN = 5,&lt;br /&gt;
    SCHWARZ&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
Dies definiert die Konstanten &amp;lt;tt&amp;gt;ROT=0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;GRUEN=1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BLAU=2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BRAUN=5&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;SCHWARZ=6&amp;lt;/tt&amp;gt; und den Typ &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void foo (enum Farben farbe)&lt;br /&gt;
{&lt;br /&gt;
   switch (farbe)&lt;br /&gt;
   {&lt;br /&gt;
      case ROT:&lt;br /&gt;
         ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit kann man anstatt &amp;quot;magischer&amp;quot; Zahlen sprechende Namen im Code verwenden, etwa in Berechnungen und Zuweisungen, Vergleichen oder als Konstante hinter einem &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zusammengesetzte Datentypen==&lt;br /&gt;
===Arrays===&lt;br /&gt;
Oft muß man sehr viele Werte gleichzeitig abspeichern und betrachten, die alle der selben Aufgabe dienen. Man schreibt z.B. ein Programm, das 10 Zahlen einlesen und anschließend wieder ausgeben soll. Man könnte das natürlich mit 10 einzelnen Variablen bewerkstelligen, aber es ist sinnvoller, dabei Arrays &amp;amp;ndash; teilweise auch als ''Felder'' bezeichnet &amp;amp;ndash; zu verwenden.&lt;br /&gt;
&lt;br /&gt;
In einem Array werden mehrere Variablen gleichen Typs zusammengefasst und hintereinander im Speicher abgelegt. So kann man viele tausend Variablen anlegen mit nur einer Zeile Code. Doch es gibt noch größere Vorteile: Sie können das Array mit einer Schleife ganz einfach nach Werten durchsuchen. Stellen Sie sich vor, Sie müssten mit 100 verschiedenen Variablen &amp;lt;tt&amp;gt;Zahl_00&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;Zahl_99&amp;lt;/tt&amp;gt; arbeiten!&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}}&amp;amp;#91;{{Konstante}}&amp;amp;#93;;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 unsigned int werte[100];&lt;br /&gt;
&lt;br /&gt;
Der Name muß natürlich ein gültiger Bezeichner sein, als Datentyp kann jeder Typ genommen werden &amp;amp;ndash; sowohl elementare Datentypen als auch Zeiger, Strukturen, Unions oder selbst definierte Datentypen. In der eckigen Klammer wird die Anzahl der Elemente bekanntgegeben. Ein mit [3] definiertes Array hat Platz für drei Variablen. Da der Index immer bei 0 beginnt, greift man also mit &amp;lt;tt&amp;gt;[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;[1]&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;[2]&amp;lt;/tt&amp;gt; auf den jeweilige Inhalt zu. Um auf eine der im Array enthaltenen Variablen zugreifen zu können, müssen Sie den Variablennamen und in eckigen Klammern den Index (die &amp;quot;Nummer&amp;quot;) der Variablen angeben. Diese Variable verhält sich dann wie eine ganz normale Variable des jeweiligen Datentypes. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #define NZAHLEN 10&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int i;&lt;br /&gt;
    int zahlen[NZAHLEN];  {{comment|zahlen[0] ... zahlen[9]}}&lt;br /&gt;
  &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++)&lt;br /&gt;
    {&lt;br /&gt;
       printf (&amp;quot;Bitte Zahl %d eingeben: &amp;quot;, i);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; zahlen[i]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++) &lt;br /&gt;
       printf (&amp;quot;Zahl %d ist: %d\n&amp;quot;, i, zahlen[i]);&lt;br /&gt;
      &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 10 int-Variablen großes Array angelegt. &lt;br /&gt;
In dieses wird nun der Reihe nach 10 Zahlen eingelesen. &lt;br /&gt;
Anschließend werden alle 10 Zahlen ausgegeben. &lt;br /&gt;
&lt;br /&gt;
Dabei wird die Größe der Arrays und das Schleifenende über das Define &amp;quot;&amp;lt;tt&amp;gt;NZAHLEN&amp;lt;/tt&amp;gt;&amp;quot; angegeben. Dadurch muss nur ''eine Stelle'' im Code geändert werden, wenn die Größe des Arrays einmal einen anderer Wert als 10 haben soll &amp;amp;ndash; dies vermeidet Fehler die dadurch entstehen, wenn man beim Anpassen der Array-Größe eine Codestelle vergisst, zudem wird der Code lesbarer als wenn irgendwo die Zahl &amp;quot;10&amp;quot; auftaucht.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
:Wird ein ungültiger Index angeben (einer, der in der Deklaration nicht enthalten ist) können  undefinierte Dinge passieren, wenn dadurch andere Variableninhalte oder Programmcode überschrieben wird, der hinter oder vor dem Array im Speicher liegt. Schlimmstenfalls kann sogar der Computer/Controller abstürzen. Also darauf achten, daß keine ungültigen Werte als Index auftreten!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Strings (Zeichenketten)===&lt;br /&gt;
Ein String ist nichts anderes als ein Array, das aus einzelnen Zeichen (&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;) gebildet wird. Die Ausgabe auf dem Bildschirm funktioniert am einfachsten mittels Strings.&lt;br /&gt;
&lt;br /&gt;
Die Definition eines Strings erfolgt also genauso wie bei Arrays:&lt;br /&gt;
 char string[21];&lt;br /&gt;
&lt;br /&gt;
Nun haben Sie eine String, in dem Sie 21 Zeichen speichern können. Ganz richtig ist das jedoch nicht. C arbeitet mit &amp;quot;null-terminierten Strings&amp;quot;. Das beudeutet, dass die Länge des Strings nicht abgespeichert wird, sondern das Zeichen mit dem ASCII-Wert 0 das Stringende kennzeichnet. Daher auch die Bezeichnung  &amp;quot;null terminiert&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Das letzte Zeichen eines Strings muß daher immer das ASCII-Zeichen Nr. 0 sein. Ist es das nicht, hat der String kein definiertes Ende, und wenn Sie versuchen, ihn durch eine Standard-Funktion auszugeben zu lassen, könnte es eine Weile dauern, bis sich im Speicher zufällig irgendwo eine 0 befindet. Es stehen ihnen daher bei dem Beispiel nur 20 Zeichen zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
===Mehrdimensionale Arrays===&lt;br /&gt;
Manchmal benötigt man mehr als nur ein eindimensionales Array, wie Sie es bisher kennengelernt haben. Auch dies ist kein Problem. In der Deklaration geben Sie einfach mehrere eckige Klammern hintereinander an. Aber Vorsicht: der Speicherplatz ist begrenzt, ein &amp;quot;&amp;lt;tt&amp;gt;char feld[1024][1024]&amp;lt;/tt&amp;gt;&amp;quot; hat die Speicherplatzgrenzen vermutlich bereits weit überschritten, und der Compiler wird einen (bei gewissen Einstellung auch keinen) Fehler liefern.&lt;br /&gt;
Beim Zugriff auf mehrdimensionale Felder müssen auch mehrere Indizes angeben werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  int x,y;&lt;br /&gt;
  int feld[3][5];&lt;br /&gt;
 &lt;br /&gt;
  for (x=0; x&amp;lt;3; x++) &lt;br /&gt;
  {&lt;br /&gt;
     for (y=0; y&amp;lt;5; y++)&lt;br /&gt;
     {&lt;br /&gt;
       printf (&amp;quot;Feldwert x: %d,  y: %d &amp;quot;, x, y);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; feld[x][y]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  for(x=0; x&amp;lt;3; x++) &lt;br /&gt;
     for (y=0; y&amp;lt;5; y++) &lt;br /&gt;
        printf (&amp;quot;Wert: feld[%d][%d] = %d\n&amp;quot;, x, y, feld[x][y]);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 3 mal 5 &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array angelegt. &lt;br /&gt;
Dann werden die Werte eingegeben: zuerst &amp;lt;tt&amp;gt;feld[0][0]&amp;lt;/tt&amp;gt;, dann &amp;lt;tt&amp;gt;feld[0][1]&amp;lt;/tt&amp;gt;, usw. bis &amp;lt;tt&amp;gt;feld[2][4]&amp;lt;/tt&amp;gt;. &lt;br /&gt;
Zum Schluß werden alle Werte noch einmal ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===Strukturen===&lt;br /&gt;
In C können Sie sogenannte &amp;quot;Strukturen&amp;quot; definieren. Dabei handelt es sich um eine Zusammenfassung mehrerer Datentypen zu einem größeren. Im Unterschied zu Feldern können in Strukturen unterschiedliche Datentypen zusammengestellt und gespeichert werden: &lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 struct {{Bezeichner}}&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur 'Person'}}&lt;br /&gt;
 struct Person &lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;lt;tt&amp;gt;struct Person {&amp;lt;/tt&amp;gt;&amp;quot; leitet die Definition der Struktur mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;Person&amp;lt;/tt&amp;gt;&amp;quot; ein. &lt;br /&gt;
Dann werden in dieser Struktur fünf Komponenten definiert: drei Strings und zwei &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. &lt;br /&gt;
mit &amp;lt;tt&amp;gt;}&amp;lt;/tt&amp;gt; wird die Definition abgeschlossen. Sie haben damit einen Datentyp erstellt. Um eine Variable des Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach an&lt;br /&gt;
 struct Person {{Bezeichner}};&lt;br /&gt;
&lt;br /&gt;
Zum Zugriff auf eine Komponente der Struktur gibt man den Namen der Struktur-Variablen an (im folgenden Beispiel also &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;klaus&amp;lt;/tt&amp;gt;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
 {{comment|Definition zweier Struktur-Variablen}}&lt;br /&gt;
 struct Person hubert, klaus;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Zugriff auf Struktur-Komponenten}}&lt;br /&gt;
 hubert.alter = 32;&lt;br /&gt;
 klaus.alter = hubert.alter + 1;&lt;br /&gt;
&lt;br /&gt;
===Unions===&lt;br /&gt;
Eine Union wird ganz analog zu einer Struktur deklariert und verwendet. Sie unterscheidet sich von einer Struktur jedoch dadurch, daß ihre Elemente nicht nacheinander im Speicher abgelegt werden, sondern sich überlagern. Auf die in einer Union enthaltenen Daten gibt es also verschiedene Sichten: je nachdem, welche Sicht bzw. Interpretation der Daten man gerne hätte, wählt man den gewünschten Zugriff.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
union Daten &lt;br /&gt;
{&lt;br /&gt;
   int id;&lt;br /&gt;
&lt;br /&gt;
   struct Person u_person;&lt;br /&gt;
&lt;br /&gt;
   struct u_double&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      double wert;&lt;br /&gt;
   };&lt;br /&gt;
&lt;br /&gt;
   struct u_pointer&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      union Daten * p1;&lt;br /&gt;
      union Daten * p2;&lt;br /&gt;
   };&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
union Daten data;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies definiert eine Union mit den vier Zugriffsmöglichkeiten &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_double&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Größe der Union richtet sich dabei nach der grössten Komponente. In diesem Beispiel sind alle Komponenten so angelegt worden, daß sie an erster Stelle ein &amp;lt;tt&amp;gt;int id&amp;lt;/tt&amp;gt; enthalten. In &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; könnte man sich also merken, wie die Daten in der Union zu interpretieren sind. Würde &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; nicht dieses &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; enthalten, so würde sich &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; mit &amp;lt;tt&amp;gt;data.u_person.vname&amp;lt;/tt&amp;gt; überlagern. Ein Ändern der ersten Buchstaben von &amp;lt;tt&amp;gt;vname&amp;lt;/tt&amp;gt; hätte also ein Ändern von &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; zur Folge, und man könnte es nicht mehr als Merker verwenden. Mit diesem Feld überlagert das &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; die &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;-Felder der anderen Sichten, z.B. ist &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; der selbe Zugriff wie auf &amp;lt;tt&amp;gt;data.u_person.id&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein anderes Beispiel ist eine Union, die es ermöglicht, auf die einzelnen Bytes eines &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; zuzugreifen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef union&lt;br /&gt;
{&lt;br /&gt;
   unsigned long  as_long;&lt;br /&gt;
   unsignen short as_short[2];&lt;br /&gt;
   unsignen char  as_byte[4];&lt;br /&gt;
} data32_t;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies überlagert einen &amp;lt;tt&amp;gt;unsigned long&amp;lt;/tt&amp;gt; &amp;amp;ndash; also eine 32-Bit-Zahl &amp;amp;ndash; mit vier Bytes bzw. zwei Shorts.&lt;br /&gt;
 data32_t wert;&lt;br /&gt;
 &lt;br /&gt;
 wert.as_long = 0x12345678;&lt;br /&gt;
 wert.as_byte[0] = 0xab;&lt;br /&gt;
 {{comment|nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform)}}&lt;br /&gt;
&lt;br /&gt;
==Eigene Datentypen==&lt;br /&gt;
&lt;br /&gt;
=Variablen=&lt;br /&gt;
Eine Variable ist ein Synonym (=anderer Name) für eine Speicherstelle in einem Computer. Einfacher gesagt, eine Variable bietet Raum, um Daten wie Zahlen oder Zeichen zu speichern und wieder zu lesen.&lt;br /&gt;
&lt;br /&gt;
==Variablennamen==&lt;br /&gt;
Ein Variablenname kann zusammengesetzt werden aus den Buchstaben &amp;lt;tt&amp;gt;'''A'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''Z'''&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;'''a'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''z'''&amp;lt;/tt&amp;gt;, den Ziffern &amp;lt;tt&amp;gt;'''0'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''9'''&amp;lt;/tt&amp;gt;, sowie dem Sonderzeichen &amp;quot;Unterstrich&amp;quot; (underscore) &amp;lt;tt&amp;gt;'''_'''&amp;lt;/tt&amp;gt;. Dabei darf an erster Stelle keine Ziffer stehen. Die Bezeichner &amp;lt;tt&amp;gt;hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALLO&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALL0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;_123&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_HALLO&amp;lt;/tt&amp;gt; sind also alle gültige und unterschiedliche Variablennamen.&lt;br /&gt;
&lt;br /&gt;
==Anlegen von Variablen==&lt;br /&gt;
Um eine Variable verwenden zu können, muss sie zuerst vereinbart (&amp;quot;erzeugt&amp;quot;) werden. Dies wird auch als &amp;quot;''Definition der Variablen''&amp;quot; bezeichnet und geht so: Schreiben Sie zuerst den Datentyp, dann den Namen der Variablen. Zum Schluß kommt noch der Strichpunkt, wie nach jeder C-Anweisung oder Deklaration. Und nicht vergessen: C unterscheidet zwischen  Groß- und Kleinschreibung! &lt;br /&gt;
 int Zahl1, Zahl2;&lt;br /&gt;
 char Zeichen;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    float gleitZahl;&lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:'''&lt;br /&gt;
In einer Zeile können auch mehrere Variablen gleichen Types vereinbart werden, wenn man ein Komma dazwischen setzt. Variablen können in jedem Block vereinbart werden. Siehe [[#Gültigkeitsbereich|Gültigkeitsbereich]].&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen==&lt;br /&gt;
Man kann einer vereinbarten Variable Werte [[#Zuweisungen|zuweisen]]. Dazu schreibt man zuerst den Variablennamen, ein Gleichheitszeichen &amp;quot;&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;&amp;quot; und anschliessend den zuzuweisenden [[#Ausdrücke|Ausdruck]]. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, zahl2 = 12;&lt;br /&gt;
  char zeichen1 = 'A';&lt;br /&gt;
&lt;br /&gt;
  zahl1 = 52;&lt;br /&gt;
  zeichen1 = zeichen1 + 1; &lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Zuerst werden drei Variablen angelegt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;: wird gleich bei der Vereinbarung der Wert 12 zugewiesen. &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl1 = 52&amp;lt;/tt&amp;gt;: Hier wird der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; der Wert 52 zugewiesen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;: wird um 1 erhöht. Da in der Variablen &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; gespeichert ist, gibt sich ihr neuer Wert aus &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt;. Weil &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; dem Wert 65 entspricht, ist &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt; gleich 66, was dem Wert für &amp;lt;tt&amp;gt;'B'&amp;lt;/tt&amp;gt; entspricht.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei float==&lt;br /&gt;
Das funktioniert genau wie bei normale Zuweisungen. Nachkommastellen werden durch einen Punkt abgegrenzt: &lt;br /&gt;
 floatVariable = 3.14;&lt;br /&gt;
Zusätzlich kann eine Zehnerpotenz angegeben werden:&lt;br /&gt;
 floatVariable2 = -1.234E-6;&lt;br /&gt;
Dadurch wird der erst Wert mit 10&amp;lt;sup&amp;gt;&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;6&amp;lt;/sup&amp;gt; multipliziert, der Wert der Variablen ist also &lt;br /&gt;
:&amp;lt;math&amp;gt;-1{,}234\cdot10^{-6} = -0.000001234&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei logischen Variablen==&lt;br /&gt;
Wie bereits erwähnt, besitzt C keinen logischen Datentyp. Es müssen also &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; dafür genutzt werden. Die Zuweisung entpricht der Standard-Zuweisung. Wird der Wert 0 zugewiesen, dann ist die Variable &amp;quot;unwahr&amp;quot;, ansonsten ist sie &amp;quot;wahr&amp;quot;. &lt;br /&gt;
 intVariable = !0;   /* entspricht &amp;quot;wahr&amp;quot;   */&lt;br /&gt;
 intVariable = 0;    /* entspricht &amp;quot;unwahr&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
==Konstanten==&lt;br /&gt;
Konstanten können als Variable angesehen werden, die nicht beschrieben, sondern nur gelesen werden können. Ein typisches Beispiel dafür ist die Zahl &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; (rund 3,141592654). Niemand würde in der realen Welt versuchen, ihr einen anderen Wert zuzuweisen. Würde man &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; jedoch wie eine normale Variable anlegen, wäre dies ohne weiteres möglich. Um dies zu verhindern, gibt es das Schlüsselwort &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in C:&lt;br /&gt;
 const {{Type}} {{Bezeichner}} = {{Konstante}};  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Wichtig dabei ist, dass man Konstanten nur bei der Vereinbarung einen Wert zuweisen kann. &lt;br /&gt;
Da Konstanten gewöhnlich im gesamten Programm, zumindest einer Quelldatei genutzt werden, definiert man diese allerdings gewöhnlich außerhalb des main-Blockes entweder am Anfang eines Programmes, oder in einer sogenannten Header-Datei, die per &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; eingebunden wird.&lt;br /&gt;
 const float PI = 3.141592;  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Es sei jedoch erwähnt, daß auch einer Konstanten nachträglich ein anderer Wert zugewieden werden kann. Im obigen Beispiel könnte mit&lt;br /&gt;
 * ((float*) &amp;amp;PI) = 2;&lt;br /&gt;
der Wert von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; im Nachhinein verändert werden. Es wird die Adresse von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; genommen und diese Adresse durch den Cast in eine ganz normale &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;-Adresse umgewandelt, über welche der Wert geändert wird. Die sei der Vollständigkeit halber erwähnt.&lt;br /&gt;
&lt;br /&gt;
Je nachdem, an welcher Stelle sich das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; bei einer Pointer-Deklaration befindet, markiert es den Pointer als konstant oder das Objekt, auf das dieser Pointer zeigt. Eine häufige Parameterdeklaration in Ausgabe-Funktionen, die einen String erhalten, ist&lt;br /&gt;
 void foo (const char * str, ...);&lt;br /&gt;
Dadurch ist &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; der Zeiger auf eine Zeichenkette, die innerhalt der Funktion nicht verändert wird bzw. verändert werden darf. Eine Zuweisung wie &amp;lt;tt&amp;gt;*str = 'a'&amp;lt;/tt&amp;gt; ergibt also einen Fehler. &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; selbst kann aber sehr wohl verändert werden, etwa mit &amp;lt;tt&amp;gt;str++&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Soll ausgedrückt werden, daß &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; unveränderlich ist, dann so:&lt;br /&gt;
 void foo (char * const str, ...);&lt;br /&gt;
Jetzt wäre eine Änderung des Strings in Ordnung, etwa durch &amp;lt;tt&amp;gt;str[10] = 'a'&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Um sich zu merken, worauf das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; wirkt, trennt man die Deklaration in Gedanken beim&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf: Steht das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; links vom&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, dann gehört es zum &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, steht es rechts davon, dann gehört es zum Pointer. Natürlich ist es auch denkbar, beides &amp;amp;ndash; also den Zeiger und sein Ziel &amp;amp;ndash; als konstant zu markieren.&lt;br /&gt;
&lt;br /&gt;
==Gültigkeitsbereich==&lt;br /&gt;
In C können mehrere Variablen den gleichen Namen haben, solange eindeutig ist, welche in welchen Block gültig ist. Dabei gelten folgende Regeln: &lt;br /&gt;
&lt;br /&gt;
;Lokale Variablen: sind Variablen, die innerhalb eines Blockes definiert werden. Jede Variable ist nur in dem Block gültig, in dem sie vereinbart wurde, sowie in allen darin enthaltenen Blöcken; es sei denn, in einem Unter-Block wird eine Variable gleichen Namens definiert. Dann bezieht sich in diesem Unter-Block der Bezeichner auf die im Unter-Block angelegte Variable.&lt;br /&gt;
;Globale Variablen: werden ausserhalb jedes Blockes definiert und gelten ab der Stelle, an der sie deklariert werden, siehe auch [[#Deklaration und Definition|Deklaration und Definition]]. Wird jedoch in einem Block eine Variable gleichen Namens angelegt, gilt ab hier bis zum Ende des Blocks nicht mehr die globale Variable, sondern die im Block deklarierte. Das Spiel kann man weiterspielen: wird in einem Unter-Block wieder eine namensgleiche Variable angelegt, gilt diese in dem Unterblock.&lt;br /&gt;
&lt;br /&gt;
==Speicherklassen==&lt;br /&gt;
Jede Variable in C gehört zu einer bestimmten Speicherklasse&lt;br /&gt;
;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;: Lokale Variablen sind in aller Regal sogenannte ''automatische Variablen''. Das bedeutet, sie werden automatisch angelegt, wenn ein Block bzw. eine Funktion betreten wird und danach wieder entfernt. Das Schlüsselwort &amp;quot;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;&amp;quot; wird praktisch nie hingeschrieben, denn lokale Variablen ohne die ausdrückliche Angabe einer Speicherklasse, sind automatisch automatische Variablen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;: Eine externes Symbol ist im ganzen Programm bekannt bzw. in dem Block, in der die Deklaration steht. In unterschiedlichen Blöcken stehende Deklarationen beziehen sich auf das gleiche Symbol! Obgleich das Datum global zugreifbar ist, ist der Gültigkeitsbereich auf den deklarierenden Block begrenzt bzw. auf das deklarierende Quell-Modul, sofern das Symbol ausserhalb jedes Blocks des Moduls deklariert wird. Siehe auch [[#Deklaration und Definition|Deklaration und Definition]].&lt;br /&gt;
;&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;: Die Variable ist im Block gültig bzw. im Quell-Modul (also in der C-Datei, in der die angelegt wurde), wenn sie nicht innerhalb eines Blockes angelegt wurde. Statische Variablen werden nicht in Registern oder im Frame der Funktion angelegt, sondern im selben Speicherbereich, in dem auch die globalen Variablen liegen; Konstanten evtl. auch im Flash. Eine lokale Variable, die als &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; angelegt wird, &amp;quot;überlebt&amp;quot; also das Verlassen des Blocks und hat beim neuerlichen Betreten des Blockes ihren bisherigen Wert. In unterschiedlichen Blöcken angelegte lokale statische Variablen beziehen sich auf unterschiedliche Speicherstellen, genau wie bei lokalen Variablen auch.&lt;br /&gt;
;&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;: Durch diese Speicherklasse wird eine Variable &amp;amp;ndash; falls möglich &amp;amp;ndash; als Registervariable angelegt, also in einem Maschinenregister des Computer/Controllers gehalten. Dadurch kann auf solche Variablen besonders schnell zugegriffen werden. Dieses Schlüsselwort ist bei modernen Compilern weitgehend überflüssig, da die entsprechenden Optimierungen selbständig vorgenommen werden, wenn ausreichend Register vorhanden sind. Auch globale Variablen können als Register angelegt werden, davon ist dem Anfänger aber dringend abzuraten, weil leicht schwerauffindbare Fehler und Abstürze auftreten, wenn man nicht genau weiss, welche Implikationen in einer solchen Definition stecken!&lt;br /&gt;
;&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;: (FIXME: volatile ist ein Qualifier und keine Speicherklasse) Dies ist das genaue Gegenteil von &amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt; und bewirkt, dass die Variable auf keinen Fall in einem Register zwischengespeichert werden darf, sondern immer aus dem RAM gelesen und ins RAM geschrieben werden soll. &amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt; müssen alle ''globalen'' Variablen markiert werden, die in [[ISR | Interrupt-Handlern]] verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Ausdrücke=&lt;br /&gt;
Eine Variable oder eine Konstante in C stellen einfache Ausdrücke dar.&lt;br /&gt;
Diese elementaren Ausdrücke können durch Operatoren miteinander verknüpft werden und so zu neuen, komplexeren Ausdrücken zusammen gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Einfache Beispiele für Ausdrücke sind also z.B.:&lt;br /&gt;
 1&lt;br /&gt;
 a&lt;br /&gt;
 'a'&lt;br /&gt;
 1 + a&lt;br /&gt;
 a == 1&lt;br /&gt;
&lt;br /&gt;
Auch Funktionen können einen Wert zurückliefern und in Ausdrücken weiter benutzt werden.&lt;br /&gt;
In den folgenden Abschnitten wird gezeigt, welche Operatoren in C vorhanden sind,&lt;br /&gt;
und wei man damit neue Ausdrücke aufbauen kann.&lt;br /&gt;
&lt;br /&gt;
==Lvalues==&lt;br /&gt;
&lt;br /&gt;
Ein Lvalue in C ist ein Ausdruck, dem ein anderer Ausdruck zugewiesen werden kann, dessen Wert also durch eine Zuweisung verändert werden kann.&lt;br /&gt;
das 'L' leitet sich ab von 'left' bwz. 'links' und das 'value' bedeutet Wert: Ein Lvalue ist ein Ausdruck, der auf der linken Seite einer Zuweisung stehen darf. Ein Lvalue ist also immer auch ein gültiger Ausdruck, aber die Umkehrung gilt in alles Regel nicht.&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für einen Lvalue ist eine &amp;quot;normale&amp;quot; Variable, die nicht mit &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; als Konstante markiert ist:&lt;br /&gt;
 a = 1;&lt;br /&gt;
Hingegen ist der Ausdruck &amp;lt;tt&amp;gt;a+1&amp;lt;/tt&amp;gt; kein Lvalue, denn eine Zuweisung wie&lt;br /&gt;
 a+1 = 2;&lt;br /&gt;
die mathematisch durchaus sinnvoll ist, erzeugt einen Compilerfehler, der etwa lauten könnte &amp;quot;illegal lvalue in assignment&amp;quot;:&lt;br /&gt;
&amp;quot;ungültiger Wert in Zuweisung&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Andere Beipiele für Lvalues sind die Komponenten von (nicht-konstanten) [[#Strukturen|Strukturen]] und [[#Unions|Unions]], [[#Arrays|Array]]-Elemente und die Dereferenzierungen von Pointern: Die Konstante&amp;amp;nbsp;4 wird durch den Cast in eine Adresse umgewandelt. Über die Dereferenzierung&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; wird an die Adresse&amp;amp;nbsp;4 im Speicher eine&amp;amp;nbsp;3 geschrieben. Ob das erlaubt bzw. sinnvoll ist, ist abhängig von der jeweiligen Architektur.&lt;br /&gt;
 * ((unsigned int *) 4) = 3;&lt;br /&gt;
Hier ist der gesamte &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;-Ausdruck ein Lvalue&lt;br /&gt;
&lt;br /&gt;
==Logische (boolsche) Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp;amp;&amp;amp;amp; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr oder &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; || gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; || ungleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;= b&amp;lt;/tt&amp;gt; || kleiner oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt; b&amp;lt;/tt&amp;gt; || kleiner als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt;= b&amp;lt;/tt&amp;gt; || glösser oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt; b&amp;lt;/tt&amp;gt; || grösser als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; nicht wahr und vice versa&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine interessante Eigenschaft der Operatoren &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;amp;amp;&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; ist, dass&lt;br /&gt;
sie die Auswertung abbrechen, sobald das Ergebnis feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet. Ein oft anzutreffendes Codestück sieht so aus, dabei sei &amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
  if (p &amp;amp;&amp;amp; *p == 5)&lt;br /&gt;
  {&lt;br /&gt;
     {{comment|mach was}}&lt;br /&gt;
  }&lt;br /&gt;
Zuerst wird in der Bedinung geprüft, ob Zeiger&amp;amp;nbsp;&amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; einen Wert ungleich Null hat, also ob er überhaupt einen gültigen Wert enthält. Es ist weit verbreitete Konvention in C, daß Zeiger, die keinen gültigen Wert haben, die Adresse&amp;amp;nbsp;0 enthalten. '''Nur dann, wenn ein Zeiger nicht ein Null-Pointer ist, darf überhaupt ein Zugriff über ihn erfolgen!'''&lt;br /&gt;
&lt;br /&gt;
==Vergleich von Variablen==&lt;br /&gt;
Skalare Variablen (also ganze Zahlen, Gleitkommazahlen, Zeiger) können miteinander verglichen werden. Dazu gibt es die folgenden Operatoren in C: &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; || ist nicht gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;=&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;=&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das Ergebnis der Auswertung ist eine ganze Zahl. Ist die Bedingung erfüllt, dann ist der Wert ungleich&amp;amp;nbsp;0. Ist die Bedingung nicht erfüllt, dann ist ihr Wert gleich&amp;amp;nbsp;0.&lt;br /&gt;
Meistens wird man diese Operatoren in &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Konstrukten finden wie zum Beispiel&lt;br /&gt;
 if (x &amp;gt;= 10)&lt;br /&gt;
    x = 10;&lt;br /&gt;
oder in Abbruchbedingungen von Schleifen, wie sie weiter unten erklärt werden.&lt;br /&gt;
&lt;br /&gt;
Es ist auch möglich, das Ergebnis der Auswertung in einer &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Variablen zu speichern:&lt;br /&gt;
 int i;&lt;br /&gt;
 int z1, z2;&lt;br /&gt;
 &lt;br /&gt;
 z1 = 5;&lt;br /&gt;
 z2 = 100;&lt;br /&gt;
 i = z1 &amp;lt;= z2;  {{comment|Ein Vergleich. i wird &amp;quot;wahr&amp;quot;, da z1 kleinergleich z2 ist}}&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich&amp;amp;nbsp;0 (&amp;quot;wahr&amp;quot;), wenn &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; kleiner oder gleich &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt; ist. Ist &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; jedoch größer als &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt;, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich&amp;amp;nbsp;0 (&amp;quot;unwahr&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
==Arithmetische Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a + b&amp;lt;/tt&amp;gt; || Summe (Addition)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a - b&amp;lt;/tt&amp;gt; || Differenz (Subtraktion)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a * b&amp;lt;/tt&amp;gt; || Produkt (Multiplikation)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a / b&amp;lt;/tt&amp;gt; || Quotient (Division, evtl. mit Rest)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a % b&amp;lt;/tt&amp;gt; || Rest bei Division (Modulo)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;-a&amp;lt;/tt&amp;gt; || Vorzeichenumkehr (Zweierkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Bit-Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp; b&amp;lt;/tt&amp;gt; || bitweise und (and)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || bitweise oder (or)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a ^ b&amp;lt;/tt&amp;gt; || bitweise exclusiv-oder (xor, exor)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;~a&amp;lt;/tt&amp;gt; || jedes Bit in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; invertieren (not, Einerkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Index-Operator bei Arrays==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a[b]&amp;lt;/tt&amp;gt; || das (b+1)ste Element des Feldes a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Folgendes gilt es bei der Verwendung des Indexoperators zu beachten:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; muss ein [[C-Tutorial#Felder | Feld]] oder [[C-Tutorial#Zeiger | Zeiger]] sein&lt;br /&gt;
# &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; muss ein Integer sein oder ein Datentyp, der sich in einen int umwandeln läßt (z.B. char)&lt;br /&gt;
# Es wird nicht geprüft, ob der Index &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; im Feld &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gültig ist!&lt;br /&gt;
# Der erste Index eines Feldes ist immer 0. Daher ''(b+1)stes Element'' in der Beschreibung&lt;br /&gt;
&lt;br /&gt;
==Komponenten-Auswahl bei Structs und Unions==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a.b&amp;lt;/tt&amp;gt; || Element b der [[C-Tutorial#Strukturen | Struktur]] oder des Unions a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adress-Operator und Dereferenzierung==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&amp;amp;amp;a&amp;lt;/tt&amp;gt; || Speicheradresse der Variablen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;*a&amp;lt;/tt&amp;gt; || Wert, der an der Adresse &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a-&amp;amp;gt;b&amp;lt;/tt&amp;gt; || Wert des Elements &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; der Struktur, deren Adresse in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Adressoperator &amp;amp; kann auf Variablen angewendet werden und&lt;br /&gt;
gibt die Startadresse der Variablen im Speicher zurück.&lt;br /&gt;
&lt;br /&gt;
Handelt es sich bei einer Variable um einen [[C-Tutorial#Zeiger | Zeiger]], so enthält&lt;br /&gt;
sie eine Speicheradresse. Um an den '''Wert''' zu gelangen, der&lt;br /&gt;
an dieser Adresse steht, wird der Operator * vorangestellt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
&lt;br /&gt;
 {{comment|x ist eine Integervariable und hat den Wert 5}}&lt;br /&gt;
 int x = 5;&lt;br /&gt;
     &lt;br /&gt;
 {{comment|z ist ein Zeiger auf eine Integer-Variable und enthaelt somit}}&lt;br /&gt;
 {{comment|die Speicheradresse einer Integer-Variablen}}&lt;br /&gt;
 int *z;       &lt;br /&gt;
  &lt;br /&gt;
 {{comment|Verwendung des Adress-Operators: weist an z die Adresse von x zu}}&lt;br /&gt;
 z = &amp;amp;x;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Verwendung der Dereferenzierung}}&lt;br /&gt;
 {{comment|erhoehe den Wert, der bei Adresse z steht, um eins}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|da z auf x zeigt, hat x jetzt den Wert 6}}&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff auf Struktir- und Union-Elemente eine abkürzende Schreibweise möglich:&lt;br /&gt;
&lt;br /&gt;
Statt &lt;br /&gt;
  (*strukturZeiger).element&lt;br /&gt;
kann geschrieben werden&lt;br /&gt;
  strukturZeiger-&amp;gt;element&lt;br /&gt;
Beide Schreibweisen sind absolut gleichbedeutend, die Klammern bei der ersteren sind notwendig.&lt;br /&gt;
&lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
:Bei der Dereferenzierung durch &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; findet keine Prüfung statt, ob der Zeiger auch auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu einer Änderung '''irgendeiner''' Speicherstelle!&lt;br /&gt;
&lt;br /&gt;
 int *z; {{comment|z ist ein Zeiger auf einen int}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.}}&lt;br /&gt;
 {{comment|z enthaelt irgendeine ungueltige Adresse!!}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|&amp;quot;Erhoehe einen Integer _irgendwo_ im Speicher um 1&amp;quot; -&amp;gt; CRASH !!!}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
&lt;br /&gt;
==Cast-Operator==&lt;br /&gt;
&lt;br /&gt;
Der Cast Operator dient dazu, den Datentyp eines Wertes zu ändern. Dafür wird einfach der neue Datentyp in Klammern vor den Wert geschrieben.&lt;br /&gt;
&lt;br /&gt;
Um zum Beispiel aus einem Float ein Integer zu machen:&lt;br /&gt;
 var  = (int) 5.60;&lt;br /&gt;
Dabei wird der Wert aber auch gerundet, und es findet somit ein Informationsverlust statt.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Umwandeln einer ganzen Zahl in eine Adresse:&lt;br /&gt;
 int * addr;&lt;br /&gt;
 addr = (int*) 0x1234;&lt;br /&gt;
Damit ist &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; an Adresse 0x1234.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
Der Cast-Operator selbst führt ''keine Konvertierung'' von Darstellungen durch, etwa die Umwandlung der ganzen Zahl 123 ein den String &amp;lt;tt&amp;gt;&amp;quot;123&amp;quot;&amp;lt;/tt&amp;gt;, der diese Zahl darstellt! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
  int main(int argc, char ** argv)&lt;br /&gt;
  {&lt;br /&gt;
        char text[] = &amp;quot;5.6&amp;quot;;&lt;br /&gt;
        int zahl = (int) text;&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, zahl);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Anfangsadresse des Strings &amp;lt;tt&amp;gt;&amp;quot;5.6&amp;quot;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Komma-Operator==&lt;br /&gt;
Mit einem &amp;lt;tt&amp;gt;,&amp;lt;/tt&amp;gt; können mehrere Ausdrücke nacheinander ausgewertet werden.&lt;br /&gt;
Die Auswertung erfolgt von links nach rechts.&lt;br /&gt;
&lt;br /&gt;
Solche Konstrukte sieht man manchmal in Abfragen wie&lt;br /&gt;
 FILE  *file;&lt;br /&gt;
 if (file = fopen (&amp;quot;foo.exe&amp;quot;, &amp;quot;r&amp;quot;), file != NULL)&lt;br /&gt;
was erst an &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; einen Wert zuweist und den &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Block nur betritt,&lt;br /&gt;
wenn &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; nicht der Nullpointer ist.&lt;br /&gt;
&lt;br /&gt;
Bequem kann das auch in einer [[#for-Schleife|for-Schleife]] sein, wenn man zwei (oder mehr) Laufvariablen hat oder so:&lt;br /&gt;
 for (i=0, j=0; i &amp;lt; 10; i++, j += 2)&lt;br /&gt;
    &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Zuweisung===&lt;br /&gt;
=== ++ und -- ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; stellen einfachere Schreibweisen dar zum Addieren bzw. Subtrahieren von&amp;amp;nbsp;1.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; (Inkrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo++; &lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo + 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; 3}}&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; (Dekrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo--;&lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo - 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; -1}}&lt;br /&gt;
&lt;br /&gt;
Die beiden Operatoren können sowohl in der Präfix-Schreibweise (vor der Variablen) als auch als Postfix-Schreibweise (hinter der Variablen) notiert werden. &lt;br /&gt;
Der Unterschied liegt darin, dass beim Präfix der Wert zuerst neu berechnet wird und die Variable dann verwendet wird. Beim Postfix wird die Variable zuerst verwendet und erst nach Auswertung des Ausdrucks, in dem sie enthalten ist, neu berechnet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 int ausgabe1, ausgabe2, var1 = 10, var2 = 10;&lt;br /&gt;
 ausgabe1 = 3 * ++var1; {{comment|ausgabe1 &amp;amp;#61; 33; var1 &amp;amp;#61; 11;}}&lt;br /&gt;
 ausgabe2 = 3 * var2++; {{comment|ausgabe2 &amp;amp;#61; 30; var2 &amp;amp;#61; 11;}}&lt;br /&gt;
&lt;br /&gt;
Für Zeiger arbeiten diese Operatoren etwas anders, siehe dazu [[#Zeiger-Arithmetik|Zeiger-Arithmetik]].&lt;br /&gt;
&lt;br /&gt;
===Bedingter Ausdruck===&lt;br /&gt;
 ({{Bedingung}}) ? {{Ausdruck|1}} : {{Ausdruck|2}}&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; erfüllt ist, dann wertet dieser Ausdruck aus zu &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt;. Ist er nicht erfüllt, dann wertet er aus zu &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 x = (x &amp;gt;= 3) ? 0 : x+1;&lt;br /&gt;
Startet man &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; mit dem Wert 0, dann nimmt es bei mehrfacher Anwendung dieser Zeile (z.B. in einer Schleife) nacheinander die folgende Werte an:&lt;br /&gt;
:&amp;lt;tt&amp;gt;1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, ...&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
Eine Kontrollanweisung ist eine Anweisung, die Einfluss auf den Programmfluss hat. Normalerweise werden Anweisungen so ausgeführt, wie sie in der Quelldatei stehen: Von links nach rechts (falls mehrere Anweisungen in einer Zeile stehen sollten, wovon i.A. abzuraten ist) und von oben nach unten. Mit einer Kontrollanweisung kann dieser lineare Programmfluss durchbrochen werden: Die Codeausführung kann kann abhängig von einer Bedingung gemacht werden (&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;), kann wiederholt werden (Schleife) oder an einer anderen Stelle der Funktion fortgesetzt werden (&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==if-Anweisung==&lt;br /&gt;
Mit Hilfe des if-Befehls kann man Codeteile abhängig davon einer Bedingung ausführen lassen:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
oder mit else-Teil&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 if (x &amp;gt; 100)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;gt; 100 ist: Fehlerausgabe}}&lt;br /&gt;
    printf (&amp;quot;x = %d ist zu gross fuer die Berechnung!\n&amp;quot;, x);&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;lt;&amp;amp;#61; 100 ist: Berechne Summe der Zahlen 1...x}}&lt;br /&gt;
    {{comment|Die lokale Variable x2 lebt nur innerhalb dieses alse-Blocks}}&lt;br /&gt;
    int x2 = x;&lt;br /&gt;
 &lt;br /&gt;
    for (x = 0; x2 &amp;gt; 0; x2--)&lt;br /&gt;
       x += x2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Wenn die Bedingung wahr ist (&amp;lt;tt&amp;gt;x &amp;gt; 100&amp;lt;/tt&amp;gt;), dann wird eine Meldung ausgegeben; danach ist die if-Anweisung beendet. Der else-Block wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung nicht erfüllt (&amp;lt;tt&amp;gt;x &amp;amp;le; 100&amp;lt;/tt&amp;gt;), dann wird gleich zum else-Teil gesprungen, und nach dessen Ausführung der if-Befehl beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Ein häufiger Fehler ist es, statt &amp;lt;tt&amp;gt;if (a &amp;amp;#61;&amp;amp;#61; 23)&amp;lt;/tt&amp;gt; etwas wie &amp;lt;tt&amp;gt;if (a &amp;amp;#61; 23)&amp;lt;/tt&amp;gt; zu schreiben. &lt;br /&gt;
Dann wird allerdings nicht geprüft, ob die Variable&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gleich 23 ist, sondern der Variablen&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wird der Wert 23 zugewiesen. Der Ausdruck &amp;lt;tt&amp;gt;a &amp;amp;#61; 23&amp;lt;/tt&amp;gt; hat den Wert&amp;amp;nbsp;23 und ist damit immer &amp;quot;wahr&amp;quot;! Daher ist diese if-Bedingung immer erfüllt!&lt;br /&gt;
&lt;br /&gt;
Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken sondern bestenfalls eine Warnung. Damit ist dieser Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise &amp;lt;tt&amp;gt;if (23 &amp;amp;#61;&amp;amp;#61; a)&amp;lt;/tt&amp;gt;. Wenn man dort anstatt des Vergleichsoperators '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;amp;#61;&amp;lt;/tt&amp;gt;' den Zuweisungsoperator '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;lt;/tt&amp;gt;' verwendet, spuckt der Compiler sehr wohl einen Fehler aus! Ist die Zuweisung jedoch erwünscht und eine Compiler-Warnung lästig, dann wählt man eine Schreibweise wie &amp;lt;tt&amp;gt;if ((a &amp;amp;#61; b))&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;if (a &amp;amp;#61; b, a)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist zu schreiben &amp;lt;tt&amp;gt;if (Bedingung);&amp;lt;/tt&amp;gt; Richtig muss es heissen &amp;quot;&amp;lt;tt&amp;gt;if(Bedingung)&amp;lt;/tt&amp;gt;&amp;quot; Das Semikolon im ersten Fall ist eine leere Anweisung, die im if-Falle ausgeführt wird &amp;amp;ndash; sie bleibt also ohne Resultet. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt; ein auf das Semikolon folgende Anweisung die eigentlich zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören soll wird immer ausgeführt, die sie nicht mehr zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; dazu gehört.&lt;br /&gt;
}}&lt;br /&gt;
Bei verschachtelten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Konstrukten gehört ein &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zu letzten &amp;quot;freien&amp;quot; &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;. Soll in einer &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Folge das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zum ersten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören, dann ist das so zu hinzuschreiben:&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Ohne die geschweiften Klammern um das zweite &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehörte das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; dort hinzu.&lt;br /&gt;
&lt;br /&gt;
==switch-Anweisung==&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
&lt;br /&gt;
 switch ({{Ausdruck|}}) &lt;br /&gt;
 {&lt;br /&gt;
     case konstante1:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
    &lt;br /&gt;
     case konstante2:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 &lt;br /&gt;
     {{comment|weitere case-Marken}}&lt;br /&gt;
 &lt;br /&gt;
     default:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 } {{comment|Ende von switch}} &lt;br /&gt;
&lt;br /&gt;
Der Ausdruck muss ein skalarer Typ sein, er wird in die nächste ganze Zahl gewandelt und mit den Werten hinter den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Marken verglichen. Bei einer Übereinstimmung werden alle Befehle ab dem zutreffenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; ausgeführt. Stimmt der Ausdruck mit keinem der Werte überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt falls vorhanden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der nachfolgenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;- und des &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitts werden ausgeführt, wenn die Anweisungen des &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitts nicht mit dem Befehl &amp;lt;tt&amp;gt;break;&amp;lt;/tt&amp;gt; beendet werden!&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es dürfen beliebig viele &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitte angegeben werden, pro Vergleichswert jedoch nur einer.&lt;br /&gt;
Der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ist optional. Die Reihenfolge, in der &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt; angegeben werden, ist unerheblich.&lt;br /&gt;
&lt;br /&gt;
==Schleifen==&lt;br /&gt;
Um Anweisungen mehrmals hintereinander auszuführen, benötigt man Schleifen. Diese führen Anweisungen aus, bis oder solange Bedingungen erfüllt sind.&amp;lt;br&amp;gt; &lt;br /&gt;
Wichtig ist also, ob die Bedingung '''vor''' oder '''nach''' den Schleifen-Anweisungen geprüft wird. &lt;br /&gt;
&lt;br /&gt;
===while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 while ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Die while-Schleife wird solange durchlaufen, wie die Bedingung erfüllt ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Die Anweisung kann natürlich auch ein Block sein, der aus mehreren Deklarationen und Anweisungen besteht. &lt;br /&gt;
&lt;br /&gt;
 int zahl1 = 0;&lt;br /&gt;
 int zahl2 = 1;&lt;br /&gt;
 &lt;br /&gt;
 while (zahl1 &amp;lt; 3)&lt;br /&gt;
 {&lt;br /&gt;
    zahl1 = zahl1 + 1;&lt;br /&gt;
    zahl2 = zahl2 * 2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife drei mal durchlaufen. Zu Beginn des vierten Durchlaufs ist die Bedingung nicht mehr erfüllt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
&lt;br /&gt;
===do-while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
Die do-while-Schleife wird auf jeden Fall einmal durchlaufen und dann solange wiederholt, wie die Bedingung erfüllt ist.&lt;br /&gt;
 int i = 2;&lt;br /&gt;
 &lt;br /&gt;
 do &lt;br /&gt;
 {&lt;br /&gt;
     i = i*i;   {{comment|i quadrieren}}&lt;br /&gt;
     printf (&amp;quot;i = %d\n&amp;quot;, i);&lt;br /&gt;
 }&lt;br /&gt;
 while (i &amp;lt; 20);&lt;br /&gt;
&lt;br /&gt;
Die Schleife wird durchlaufen und wiederholt, solange &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; kleiner als 20 ist. Es werden also nacheinander die Werte 2, 4 und 16 ausgegeben. Nach der Schleife hat&amp;amp;nbsp;&amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; den Wert 256.&lt;br /&gt;
&lt;br /&gt;
===for-Schleife===&lt;br /&gt;
'''Syntax:''' &lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Bei den Ausdrücken wird es sich um einen Ausdrücke mit Nebeneffekt handeln wie etwa &amp;lt;tt&amp;gt;i=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;i=i+2&amp;lt;/tt&amp;gt;. Es werden folgende Aktionen ausgeführt:&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# falls die Bedingung wahr ist, dann führe &amp;lt;tt&amp;gt;Anweisung&amp;lt;/tt&amp;gt; aus.&lt;br /&gt;
# falls die Bedingung unwahr ist, dann sprinte zu 7 (Ende).&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# gehe zu 2&lt;br /&gt;
# nächste Anweisung nach der for-Schleife&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int lauf, summe;&lt;br /&gt;
 &lt;br /&gt;
 for (lauf=1, summe=0; lauf &amp;lt;= 10; lauf += 2) &lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel ist &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; ein [[#Komma-Operator|Komma-Ausdruck]], der zwei Anweisungen kombiniert und daher sogar zwei Nebeneffente hat: er setzt &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;1 und &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;0.&lt;br /&gt;
&lt;br /&gt;
Das Äquivalent als while-Schleife:&lt;br /&gt;
&lt;br /&gt;
 int lauf  = 1;                 {{comment|Anfangswerte}}&lt;br /&gt;
 int summe = 0;&lt;br /&gt;
 &lt;br /&gt;
 while (lauf &amp;lt;= 10)             {{comment|Bedingung}}&lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
    lauf  += 2;                 {{comment|Inkrement}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; in jedem Schleifendurchlauf um die Laufvariable &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; erhöht. Da &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nacheinander die ungeraden Werte von&amp;amp;nbsp;1 bis&amp;amp;nbsp;10 annimmt, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von&amp;amp;nbsp;1 bis kleinergleich 10 gespeichert, also der Wert&amp;amp;nbsp;25. &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; hat nach der Schleife den Wert&amp;amp;nbsp;11.&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf = 1&amp;lt;/tt&amp;gt; bedeutet, dass der Variablen &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; vor dem ersten Schleifendurchlauf der Wert&amp;amp;nbsp;1 zugewiesen wird. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf &amp;lt;= 10&amp;lt;/tt&amp;gt; ist die Schleifenbedingung; ist sie nicht erfüllt, wird die Schleife beendet. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf += 2&amp;lt;/tt&amp;gt; bedeutet, dass &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nach jedem Durchlauf um&amp;amp;nbsp;2 erhöht wird.&lt;br /&gt;
&lt;br /&gt;
===continue-Anweisung===&lt;br /&gt;
Innerhalb einer Schleife darf die &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die nachfolgenden Anweisungen übersprungen werden und mit dem nächsten Schleifendurchlauf fortgesetzt wird &amp;amp;ndash; vorausgesetzt die Schleifenbedingung ist noch erfüllt. Ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; etc. stehen, wenn dieses innerhalb einer Schleife steht.&lt;br /&gt;
&lt;br /&gt;
==break-Anweisung==&lt;br /&gt;
Innerhalb einer Schleife oder eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; darf die &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die Schleifen-/Switch-Anweisung sofort verlassen wird und das Programm dahinter weiter macht. Bei mehrfach geschachtelten Schleifen wird nur die innere verlassen. Ein &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; stehen, wenn dieses innerhalb einer Schleife/Switch-Anweisung steht.&lt;br /&gt;
&lt;br /&gt;
==goto-Anweisung==&lt;br /&gt;
&lt;br /&gt;
Innerhalb ein und derselben Funktion kann mit &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; an eine andere Stelle gesprungen werden. Dazu gibt man hinter dem &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einen Bezeichner an, der dadurch als Label fungiert:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 goto {{Bezeichner}};&lt;br /&gt;
Die Bezeichner selbst steht irgendwo in der Funktion und wird dadurch zur Sprungmarke (Label), daß er von einem Doppelpunkt (und mindestens einer C-Anweisung, die auch leer sein darf) gefolgt wird.&lt;br /&gt;
&lt;br /&gt;
Das Beispiel durchsucht das 2-dimensionale &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array &amp;lt;tt&amp;gt;feld&amp;lt;/tt&amp;gt; mit den &amp;lt;tt&amp;gt;SIZE_X &amp;amp;times; SIZE_Y&amp;lt;/tt&amp;gt; Werten nach dem Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;. Wird er gefunden, dann wird die 2-fach geschachtelte Suchschleife verlassen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int x, y;&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y; y++)&lt;br /&gt;
       if (feld[x][y] == 0)&lt;br /&gt;
          goto done;&lt;br /&gt;
 {{Label|done:}};&lt;br /&gt;
&lt;br /&gt;
Der folgende Code hat die gleiche Funktion, arbeitet jedoch ohne &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int x, y;&lt;br /&gt;
 int found = 0; {{comment|FALSE}}&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X &amp;amp;&amp;amp; !found; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y &amp;amp;&amp;amp; !found; y++)&lt;br /&gt;
       found = (0 == feld[x][y]);&lt;br /&gt;
Der Nachteil der &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-losen Variante ist, daß man eine Variable, die merkt, ob das Suchziel gefunden wurde, mitschleppen und in ''jedem'' Schleifendurchlauf abtesten muss. Dies bedeutet einen höheren Programmier- und Laufzeitaufwand und ist nicht so klar formuliert wie das &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-Beispiel.&lt;br /&gt;
&lt;br /&gt;
Gleichwohl sei angemerkt, daß die Verwendung von &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einem gewissen Dogmatismus unterliegt, der sich wie folgt subsummieren liesse:&lt;br /&gt;
:''goto ist böse und sollte keinesfalls verwendet werden! Wer es dennoch tut, offenbart dadurch seinen schlechten Geschmach sowie mangelhafte C-Kenntnis.'' &amp;lt;div align=&amp;quot;right&amp;quot;&amp;gt;http://www.roboternetz.de/phpBB2/images/smiles/icon_wink.gif&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Funktionen=&lt;br /&gt;
Stellen Dir vor, Du hast eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben &amp;amp;ndash; was Dich Zeit beim Erstellen des Programms und Speicherplatz im ausführbaren Programm kostet &amp;amp;ndash; kannst Du den Code-Abschnitt in eine Funktion schreiben und diese von jeder Stelle des Programms aus verwenden. Die Hauptgründe, um Funktionen zu verwenden, sind:&lt;br /&gt;
;Wiederverwendung von Code: Mehrfach verwendete Codestücke müssen nicht mehrfach implementiert werden. Oft unterscheiden sich die Codesequenzen nur in Kleinigkeiten, die man der Funktion über Parameter mitteilen kann.&lt;br /&gt;
;Übersichtlichkeit: Ein gut gegliedertes C-Programm implementiert klar umrissene Aufgaben in einer Funktion, auch wenn diese Funktion nur einmal im Code aufgerufen wird! Dadurch bleibt der Code um die Aufrufstelle besser verständlich, und man kann auf verschiedenen &amp;quot;Ebenen&amp;quot; denken. Eine Funktion wie &amp;quot;Datei öffnen&amp;quot; kann recht komplex sein. Auf höherer Ebene interessieren die Innereien nicht mehr, man möchte sich um andere Dinge kümmern und will den Code an der Stelle garnicht sehen...&lt;br /&gt;
;Rekursive Funktionen: Eine Funktion kann sich auch selbst aufrufen. In dem Falle nennt man die Funktion ''rekursiv''. Zwar lässt sich das, was eine rekursive Funktion tut, auch mit anderen Mitteln formulieren, die keine rekursiven Funktionen brauchen, aber oft ist der rekursive Weg knackiger und klarer formulierbar als eine nicht-rekursiven Ansatz, auch wenn es etwas mehr Resourcen verbraucht.&lt;br /&gt;
;Modulare Programmierung: Funktionen können anhand ihres Aufgabenbereichs auf verschiedene C-Quellen &amp;amp;ndash; sogenannte ''Module'' &amp;amp;ndash; verteilt werden. Funktionen, die etwas mit dem USB-Bus anstellen, werden in einem anderen Modul sein als mathematische Funktionen. Dies erhöht die Übersichtlichkeit und vereinfacht die Entwicklung im Team.&lt;br /&gt;
;Bibliotheken: Standard-Funktionen wie das hier oft auftauchende &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; sind in Bibliotheken gespeichert. Wenn das eigene Programm übersetzt wird, dann müssen nicht mehr alle Standard-Funktionen übersetzt werden, sondern werden nur noch aus der Bibliothek gelesen und ihr Code zum Programm dazugelinkt. Die Bibliotheks-Funktionen wurden schon zu einem früheren Zeitpunkt compiliert und liegen in dieser compilerten Form in der Bibliothek. Das spart mächtig Entwicklungszeit. Man kann auch selbst solche Bibliotheken erstellen und in diversen Projekten wiederverwenden.&lt;br /&gt;
;Generische Programmierung: In C ist es möglich, einer Funktion eine andere Funktion zu übergeben. (Damit ist nicht gemeint, ihr deren ''Rückgabewert'' zu übergeben (was auch ginge), sondern ''die Funktion selbst'' wird als Parameter übergeben und kann aufgerufen werden.) Ein typisches Beispiel dafür sind Sortieralgorithmen. Einem Sortieralgorithmus kann es egal sein, ''was'' er sortiert. Er muss lediglich wissen, ''wie'' er das Zeug zu sortieren hat: aufsteigend, absteigend, als Zahl, in lexikographischer Ordnung, nach der Quersumme, Körper nach Oberfläche, Durchmesser, Gewicht oder Volumen... Diese Vergleichsfunktion, die für zwei Objekte entscheidet, welches davon &amp;quot;kleiner&amp;quot; ist, kann man dem Sortierer übergeben. Will er zwei Werte vergleichen, dann muss er nur die Vergleichsfunktion aufrufen, ohne zu wissen, was diese tut. Damit kann der Sortieralgorithmus unanhängig von den Objekten gehalten werden, mit denen er hantieren soll.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Definition==&lt;br /&gt;
&lt;br /&gt;
In der ''Definition'' der Funktion wird gesagt, welche Werte sie liefern kann, wie sie heisst (Bezeichner) und wieviele und welche Parameter sie hat. Danach folgt ihre Implementierung:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}} ({{Parameterliste}})&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 &lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
Für Funktionen, die keinen Wert zurückliefern, gibt es den speziellen Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der besagt, daß die Funktion nichts zurückgibt. Die einfachste denkbare Funktion ist eine solch void-Funktion. Sie bekommt keine Parameter, gibt nicht zurück und ihr Body ist leer:&lt;br /&gt;
 void dummy()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==return-Anweisung==&lt;br /&gt;
An jeder Stelle des Programmflusses einer Funktion kann diese mit &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; beendet werden.&lt;br /&gt;
&lt;br /&gt;
'''bei void-Funktionen:'''&lt;br /&gt;
 return;&lt;br /&gt;
'''Funktionen mit Rückgabe-Wert:'''&lt;br /&gt;
 return {{Ausdruck|}};&lt;br /&gt;
Die zweite Variante gibt an, welcher Wert zurückgegeben wird.&lt;br /&gt;
 int main (int argc, char * argv[])&lt;br /&gt;
 {&lt;br /&gt;
    if (argc &amp;lt; 2)&lt;br /&gt;
       return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
Falls die letzte Anweisung einer void-Funktion ein &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; ist, kann es auch weggelassen werden wie oben bei der Funktion &amp;lt;tt&amp;gt;dummy&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Aufruf==&lt;br /&gt;
Um die Funktion aufzurufen gibt man ihren Namen an, gefolgt von den durch Komma getrennten Argumenten in runden Klammern wie im Beispiel unten das&lt;br /&gt;
 quadrat (5) &lt;br /&gt;
Da &amp;lt;tt&amp;gt;quadrat&amp;lt;/tt&amp;gt; einen Wert liefert, kann man damit weiter rechnen wie mit einem normalen Ausdruck:&lt;br /&gt;
 if (quadrat (a) + quadrat (b) == quadrat (c))&lt;br /&gt;
    c = quadrat (quadrat (a)); {{comment|c &amp;amp;#61; a hoch 4}}&lt;br /&gt;
&lt;br /&gt;
==Rekursive Funktionen==&lt;br /&gt;
Eine Funktion die sich selbst &amp;amp;ndash; möglicheweise auch über andere Zwischenfunktionen &amp;amp;ndash; wieder selbst aufruft, wird als ''rekursive Funktion'' bezeichnet. In der Definition ist nichts besonderes zu beachten. Ist die Verschachtelungstiefe im laufenden Programm zu tief, dann gibt das natürlich Probleme, aber das gilt bei tief verschachtelten 'normalen' Funktionen abenso...&lt;br /&gt;
&lt;br /&gt;
Das Beispiel berechnet den Größten Gemeinsamen Teiler zweier Zahlen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int ggT (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
     if (0 == a)&lt;br /&gt;
        return b;&lt;br /&gt;
 &lt;br /&gt;
    return ggT (b % a, a);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Ein komplettes kleines Programm:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int quadrat (int param1)&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  zahl = param1 * param1;&lt;br /&gt;
  return zahl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl, ergebnis;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Bitte Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = quadrat (zahl);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, zahl, ergebnis);&lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, 5, quadrat (5));&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur ausserhalb von Blöcken. Geschachtelte Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen beim Aufruf die Klammern angeben werden:&lt;br /&gt;
 dummy();&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Prototypen==&lt;br /&gt;
Wie oben erwähnt, kann ein Unterprogramm an jeder beliebigen Stelle im Programm stehen. Damit ist jedoch eine Bedingung verknüpft: Das Unterprogramm muß in der Datei oberhalb des ersten Aufrufes definiert worden sein. Wenn Sie ein Unterprogramm in Zeile 10 zum ersten mal aufrufen, müssen Sie die Deklaration davor erledigt haben. Verstanden?&lt;br /&gt;
Um dies zu erreichen, gibt es zwei Möglichkeiten: &lt;br /&gt;
&lt;br /&gt;
Entweder Sie schreiben alle Unterprogramme vor &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; in die Datei. Dies muß jedoch wiederum so geschehen, dass Funktionen zum Zeitpunkt ihres Aufrufes bereits bekannt sind! &lt;br /&gt;
Wo dies nicht möglich ist (z.B. sich gegenseitig aufrufende Unterprogramme), oder wenn Sie das stört, müssen Sie Prototypen verwenden. &lt;br /&gt;
Wie definiert man nun Prototypen? Sie kopieren einfach die erste Zeile des Unterprogrammes (z.B. &amp;quot;&amp;lt;tt&amp;gt;void ausgeben (int zahl)&amp;lt;/tt&amp;gt;&amp;quot;), fügen einen Strichpunkt&amp;amp;nbsp;&amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;an und fügen es an einer geeigneten Stelle ein (so, dass alle Aufrufe später in der Datei kommen). &lt;br /&gt;
Solche Definitionen stehen gewöhnlich am Anfang der Quelldatei oder in einer Header-Datei, die eingebunden wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl);  /* Der Prototyp */&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
   ausgeben (12);&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl)   /* Die eigentliche Prozedur */&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Ausgabe: %d\n&amp;quot;, zahl);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Parameterübergabe==&lt;br /&gt;
&lt;br /&gt;
Alle Werte, die an Prozeduren und Funktionen übergeben werden, werden grundsätzlich '''kopiert'''.&lt;br /&gt;
Das hat folgende Auswirkungen:&lt;br /&gt;
&lt;br /&gt;
# Änderungen an einem Parameter in einer Funktion erscheinen ''nicht'' beim Aufrufer!&lt;br /&gt;
# Möchte man, dass eine Funktion einen Wert trotzdem dauerhaft ändern soll, so muss die Adresse des Wertes via [[#Zeiger|Zeiger]] übergeben werden.&lt;br /&gt;
# Werden [[#Strukturen|Strukturen]] übergeben, so wird von ihnen eine Kopie erstellt, was bei großen Strukturen viel Zeit und Arbeitsspeicher kostet. Deshalb wird häufig nur die Adresse von Strukturen übergeben, da die Adresse viel schneller und platzsparender als die Struktur selbst kopiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele:'''&lt;br /&gt;
 void erhoehe (int x)&lt;br /&gt;
 {&lt;br /&gt;
    x = x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe(a);&lt;br /&gt;
    {{comment|a ist immer noch 0}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Beim Aufruf von &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; wird eine Kopie des Wertes von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; (im Beispiel also 0) erstellt und der Prozedur als Parameter &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; übergeben. Weil dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat dies keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|erhoehe den Wert an der Adresse x um eins}}&lt;br /&gt;
    *x = *x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe (&amp;amp;a);&lt;br /&gt;
    {{comment|a ist jetzt 1}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Jetzt wird im Hauptprogramm mittels [[#Adress-Operator und Dereferenzierung|Adress-Operator]] &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; die Speicheradresse von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; bestimmt. Dann wird eine ''Kopie der Adresse'' an das Unterprogramm &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; übergeben. Jetzt kennt das Unterprogramm die&lt;br /&gt;
Adresse des Originals &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und kann direkt mit dem Inhalts-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&lt;br /&gt;
'''Besonderheit bei Feldern'''&lt;br /&gt;
&lt;br /&gt;
Bei der Übergabe von [[#Felder|Feldern]] gibt es eine Besonderheit. Schreibt man nämlich den Namen eines Feldes, so ist das nichts anderes als die '''Speicheradresse des ersten Elements'''.&lt;br /&gt;
Bei der Übergabe eines Feldes wird also eine Kopie der Startadresse übergeben. Somit kann das Unterprogramm auf den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 void erhoehe (int x[])&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
   int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
   erhoehe (a);&lt;br /&gt;
   {{comment|a hat jetzt folgenden Inhalte: 11, 23, 35}}&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Dass die Übergabe einer Adresse erfolgt, sieht man an folgendem Beispiel, das von der Funktionsweise '''absolut identisch''' mit dem vorhergehenden ist:&lt;br /&gt;
&lt;br /&gt;
 {{comment|Bei Parametern gibt es keinen Unterschied zwischen Zeiger und Feld}}&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
    int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
    erhoehe (a);&lt;br /&gt;
 &lt;br /&gt;
    {{comment|a hat jetzt folgenden Inhalt: 11, 23, 35}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
Die Länge des Feldes wird nicht automatisch übergeben. Dafür ist ggf. ein zusätzlicher Parameter notwendig.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Variable Argumentanzahl==&lt;br /&gt;
== Funktionen indirekt aufrufen ==&lt;br /&gt;
Siehe [[#Zeiger auf Funktionen|Zeiger auf Funktionen]]&lt;br /&gt;
&lt;br /&gt;
=Zeiger II=&lt;br /&gt;
&lt;br /&gt;
Zeiger haben wir bereits weiter oben kennen gelernt. Zeiger sind ein zentrales Konzept in C und sollen hier etwas eingehender behandelt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger-Arithmetik==&lt;br /&gt;
In C kann man den Wert eines Zeigers verändern. Betrachten wir dazu die Funktion &amp;lt;tt&amp;gt;suche_0&amp;lt;/tt&amp;gt;, die einen Zeiger auf einen &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; erhält. Die Funktion soll ab der gegebenen Adresse nach dem ersten long-Wert suchen, der 0 ist, und dessen Adresse zurückgeben:&lt;br /&gt;
 long * suche_0 (long * addr)&lt;br /&gt;
 {&lt;br /&gt;
    while (*addr != 0)&lt;br /&gt;
       addr = addr + 1;&lt;br /&gt;
 &lt;br /&gt;
    return addr;&lt;br /&gt;
 }&lt;br /&gt;
In der Bedingung der while-Schleife wird der Inhalt an der Speicherstelle &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf 0 getestet. Ist der Wert 0, dann wird die Schleife beendet und die Adresse zurückgeliefert. Ist der Wert ungleich 0, dann wird &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf den nächste long gesetzt, &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; also um 4 Bytes weitergezählt. &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ist ja ein Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, und ein &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; ist 4 Bytes lang.&lt;br /&gt;
&lt;br /&gt;
Die Bedeutung von&lt;br /&gt;
 address + n&lt;br /&gt;
ist also, die Adresse um das &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;-fache der Größe des Typs, auf den &amp;lt;tt&amp;gt;address&amp;lt;/tt&amp;gt; zeigt, zu erhöhen. Dabei ist &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; eine ganze Zahl und darf auch negativ sein.&lt;br /&gt;
&lt;br /&gt;
Hier noch ein Beispiel einer Funktion, die nach einer Person mit einer bestimmten ID sucht (für die Definition von &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; siehe [[#Strukturen|Strukturen]]). Der Parameter &amp;lt;tt&amp;gt;person&amp;lt;/tt&amp;gt; ist dabei ein Array von Strukturen. Eine Person mit der gesuchten ID muss existieren, ansonsten hat die Suchfunktion kein definiertes Verhalten.&lt;br /&gt;
 {{comment|Sucht nach einer Person mit der ID person_id}}&lt;br /&gt;
 struct Person * &lt;br /&gt;
 suche_person_id (struct Person * person, int person_id)&lt;br /&gt;
 {&lt;br /&gt;
    while (person-&amp;gt;id != person_id)&lt;br /&gt;
       person++;&lt;br /&gt;
 &lt;br /&gt;
    return person;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:1em; padding:1em; border:solid 2px #FF0040;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- Vorlage:FarbigerRahmen funzt hier net --&amp;gt;&lt;br /&gt;
Beachte, daß es nicht sinnvoll ist, zwei Zeiger zu addieren oder zu multiplizieren. Ausserdem ist das &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt; der Zeiger-Arithmetik nicht kommutativ. Eine Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, der an Adresse 1 im Speicher zeigt, wird man schreiben als&lt;br /&gt;
 (long *) 1&lt;br /&gt;
Addiert man darauf eine ganze Zahl, dann haben die entstehenden Ausdrücke unterschiedliche Werte:&lt;br /&gt;
 (long *) 1 + 2    {{comment|zeigt zu Adresse 9}}&lt;br /&gt;
 (long *) 2 + 1    {{comment|zeigt zu Adresse 6}}&lt;br /&gt;
 (long *) (1 + 2)  {{comment|zeigt zu Adresse 3}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==void-Pointer==&lt;br /&gt;
Eine besondere Art von Zeiger ist der void-Pointer&lt;br /&gt;
 void * addr;&lt;br /&gt;
Ein void-Pointer ist ein &amp;quot;Zeiger auf irgendwas&amp;quot;, dementsprechend kann er nicht dereferenziert werden, Anwenden von &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf einen solchen Zeiger gibt also einen Fehler. Ausserdem ist es nicht möglich, mit einem void-Pointer Zeigerarithmetik zu machen, weil er nicht auf eine definierte Art von Objekt zeigt. Der Vorteil eines void-Pointers ist, daß er jede Art von Zeiger aufnehmen kann.&lt;br /&gt;
&lt;br /&gt;
Dazu betrachten wir die Funktion &amp;lt;tt&amp;gt;send_buf&amp;lt;/tt&amp;gt;, die eine Adresse erhält und ab dieser Adresse &amp;lt;tt&amp;gt;num&amp;lt;/tt&amp;gt; Bytes versenden soll. Wir könnten die Funktion so schreiben:&lt;br /&gt;
 void send_buf (unsigned char * buf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   ...&lt;br /&gt;
Das ist jedoch hässlich, wenn wir damit etwas anderes verschicken wollen als &amp;lt;tt&amp;gt; unsigned char&amp;lt;/tt&amp;gt;, etwa eine Struktur wie &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; (vom Typ &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;):&lt;br /&gt;
 send_buf ((unsigned char*) &amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
Ohne den Cast der Adresse von &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; zu einem Zeiger auf &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt; bekommt man eine Warnung oder gar einen Compilerfehler.&lt;br /&gt;
Dieses Zeiger gecaste ist mühsam und hässlich, es muss bei jedem Aufruf der Funktion explizit hingeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Besser ist es, den ersten Parameter der Funktion als void-Pointer zu definieren und den Cast in der Funktion zu machen:&lt;br /&gt;
 void send_buf (void * vbuf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   unsigned char *buf = (unsigned char*) vbuf;&lt;br /&gt;
   ...&lt;br /&gt;
Durch den Cast in der Funktion kann auf den Inhalt des Zeigers zugegriffen werden. Man muss nur festlegen, ''wie'' man zugreifen will, nämlich als &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Der Aufruf kann jetzt ohne Pointer-Cast erfolgen: &lt;br /&gt;
 send_buf (&amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
&lt;br /&gt;
==Null-Pointer==&lt;br /&gt;
==Zeiger als Parameter==&lt;br /&gt;
Wenn Sie ein Unterprogramm aufrufen, können Sie diesem Parameter übergeben, aber keine Werte zurückgekommen (außer den Funktionswert bei Funktionen). Dies hat einen guten Grund: beim Aufruf werden nicht die aufgerufenen Parameter benutzt, sondern es werden deren Werte in neue Variablen kopiert. Diese Variablen werden am Ende des Unterprogrammes &amp;quot;zerstört&amp;quot;, ohne ihre Werte an die aufrufenden Parameter zu übergeben. Jede Veränderung eines Parameters hat daher keine Auswirkung auf den Parameter.&lt;br /&gt;
&lt;br /&gt;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der C-Compiler legt dann immer noch Kopien an. In dieser Kopie steht aber kein Wert, sondern die Adresse einer Varaiblen. Und auf diese können Sie dann zugreifen. Denken Sie nur an &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; &amp;amp;ndash; da übergeben Sie ja auch die Adresse einer Variablen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void erhoehe (int *zeiger)&lt;br /&gt;
{&lt;br /&gt;
  *zeiger = 1 + *zeiger;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  erhoehe (&amp;amp;zahl);&lt;br /&gt;
  printf (&amp;quot;\nDie erhoehte Zahl lautet: %d\n&amp;quot;, zahl);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Zeiger auf Funktionen==&lt;br /&gt;
&lt;br /&gt;
Stell dir vor, du willst einen Sortieralgorithmus wie Bubble-Sort oder Quick-Sort oder wie sie alle heissen implementieren. Für den Sortieralgorithmus ist eigentlich egal, ''was'' er zu sortieren hat. Ihm ist es egal, ob er Zahlen aufwärts sortieren soll oder Strings in lexikographischer Reihenfolge, ob Objekte nach Größe oder Gewicht, Personen nach Alter oder Adressen nach Postleitzahl. Das einzige, was der Algorithmus wissen muss, ist ''wie'' er zwei Objekte zu vergleichen hat und wann eines davon &amp;quot;kleiner&amp;quot; (im Sinne der Ordnung, nach der sortiert werden soll) ist. &lt;br /&gt;
&lt;br /&gt;
Eine einfache Sortierfunktion, die nur zwei Zahlen sortiert, könnte man also so schreiben: &lt;br /&gt;
 {{comment|Sortiert ein Array von 2 int-Zeigern nach den Inhalten &lt;br /&gt;
  * an den Zeiger-Adressen}}&lt;br /&gt;
 void sort2_a (int * p[])&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Inhalte vergleichen...}}&lt;br /&gt;
    if (*p[0] &amp;gt; *p[1])&lt;br /&gt;
    {&lt;br /&gt;
       {{comment|... und ggf. Dreieckstausch der 2 Zeiger}}&lt;br /&gt;
       int * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Die Funktion bekommt ein Array der Länge&amp;amp;nbsp;2. In diesem Array stehen Zeiger auf die zu sortierenden Zahlen. Ein Array mit Zeigern zu verwenden und nicht ein Array von &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; scheint recht umständlich, und das ist es hier auch. Aber stell dir vor, du willst Strukturen wie &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; sortieren. Das Tauschen zweier Strukturen würde bedeuten, ihre kompletten Inhalte umzukopieren! Das wäre sehr aufwändig. Viel einfacher ist das Kopieren, wenn nur die Adressen zu kopieren sind.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; könnte dann so aussehen:&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void sortiere (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|p[] enthält 2 int-Zeiger: die Adressen von a und b}}&lt;br /&gt;
    int * p[2];&lt;br /&gt;
    p[0] = &amp;amp;a; &lt;br /&gt;
    p[1] = &amp;amp;b; &lt;br /&gt;
 &lt;br /&gt;
    {{comment|Sortiere die Zeiger}} &lt;br /&gt;
    sort2_a (p);&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Sortiert: %d, %d\n&amp;quot;, *p[0], *p[1]);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Für den nächsten Schritt überlegen wir uns, daß das Array in &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; ebensogut void-Pointer enthalten kann. Die einzige Stelle, an der wir auf die endgültigen int-Objekte zugreifen, ist der Vergleich. Diesen Vergleich lagern wir in die Funktion &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; aus:&lt;br /&gt;
 {{comment|Bekommt zwei void-Pointer und vergleicht die Inhalte.&lt;br /&gt;
  * Liefert 0 bei Gleichheit,&lt;br /&gt;
  * -1 wenn der erste Wert kleiner ist als der zweite und&lt;br /&gt;
  * 1  wenn der erste Wert größer ist als der zweite}}&lt;br /&gt;
 int compare_int (void * p0, void * p1)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Um über die Zeiger zugreifen zu können müssen wir diese&lt;br /&gt;
     * erst zu int-Zeigern casten}}&lt;br /&gt;
    int a0 = * (int*) p0;&lt;br /&gt;
    int a1 = * (int*) p1;&lt;br /&gt;
 &lt;br /&gt;
    if (a0 &amp;gt; a1)  return  1;&lt;br /&gt;
    if (a0 &amp;lt; a1)  return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void sort2_b (void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare_int (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Ein Aufruf von &amp;lt;tt&amp;gt;sort2_b&amp;lt;/tt&amp;gt; sieht dann genauso aus wie ein Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt definieren wir uns den neuen Datentyp &amp;lt;tt&amp;gt;comparator_t&amp;lt;/tt&amp;gt;. Dieser ist ein Zeiger auf eine Funktion, die zwei void-Pointer erhält und einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; zurückliefert, also analog arbeitet zu &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; von oben. &lt;br /&gt;
&lt;br /&gt;
Unsere Sortierfunktion bekommt nun neben dem zu sortierenden Zeiger-Array auch eine Vergleichsfunktion &amp;lt;tt&amp;gt;compare&amp;lt;/tt&amp;gt; mitgeliefert, die sie aufruft, wenn sie zwei Objekte vergleichen will&lt;br /&gt;
 {{comment|comparator_t sind Zeiger auf Funktionen, die 2 void-Pointer&lt;br /&gt;
  * erhalten und einen int zurückliefern}}&lt;br /&gt;
 typedef int (*comparator_t) (void*, void*);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Der Sortierer bekommt einen Funktionszeiger auf den Vergleicher.&lt;br /&gt;
  * Der Aufruf vom compare geht so als wäre es eine &amp;quot;normale&amp;quot; Funktion&lt;br /&gt;
  * (ist es im Endeffekt ja auch)}}&lt;br /&gt;
 void sort2_c (comparator_t compare, void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Bei einem Aufruf von &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; muss man dann einen Komparator mit angeben. In einem Beispiel analog zu &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; von oben ist das:&lt;br /&gt;
 sort2_c (compare_int, p);&lt;br /&gt;
Um zwei Strings lexikographisch zu sortieren nehmen wie die Standard-Funktion &amp;lt;tt&amp;gt;strcmp&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void foo()&lt;br /&gt;
 {&lt;br /&gt;
    char * worte[] = { &amp;quot;Wort1&amp;quot;, &amp;quot;Wort2&amp;quot; };&lt;br /&gt;
 &lt;br /&gt;
    sort2_c ((comparator_t) strcmp, (void**) worte);&lt;br /&gt;
 }&lt;br /&gt;
Die Casts sind hier erforderlich. Alternativ könnte man &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; mit reinen void-Pointern versorgen und diese dann dort umcasten.&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
&lt;br /&gt;
Die Syntax zur Definition/Deklaration von Funktionszeigern ist etwas verzwackt. Zur Verdeutlichung ein paar Beispiele. Dabei legt das linke &amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt; jeweils den Return-Typ fest.&lt;br /&gt;
 {{comment|definiert einen neuen Funktionszeiger-Typ}}&lt;br /&gt;
 typedef {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert einen Funktionszeiger}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert ein Array von Funktionszeigern (mit Initializer)}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}[]) ({{type}}, {{type}}, ...) = { wert1, wert2, ... };&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer}}&lt;br /&gt;
 ({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer und ruft die Funktion auf}}&lt;br /&gt;
 (({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}) (arg1, arg2, ...);&lt;br /&gt;
&lt;br /&gt;
=Standard-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==String-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===strcpy===&lt;br /&gt;
Bei vielen Compilern können sie einem String nicht direkt einen Wert (Text) zuweisen. Dazu müssen Sie dann die Prozedur strcpy() benutzen. Diese erwartet als ersten Parameter den Namen einer String-Variablen (ohne eckige Klammern) und als zweiten Parameter den eines (anderen) Strings. Letzterer kann auch ein in doppelten Hochkommas (&amp;quot;) eingeschlossener Text sein. Die Funktion fügt am Ende automatisch ein 0-Zeichen ein. Um diese Funktion nutzen zu können, müssen Sie die Datei string.h includieren! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri1[21], eingabe[21];&lt;br /&gt;
&lt;br /&gt;
  strcpy (stri1, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Der 1. String: %s\n&amp;quot;, stri1);&lt;br /&gt;
  printf (&amp;quot;Bitte geben Sie maximal 20 Zeichen ein: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%s&amp;quot;, eingabe);&lt;br /&gt;
  strcpy (stri1, eingabe);&lt;br /&gt;
  printf (&amp;quot;\n%s = %s&amp;quot;, stri1, eingabe);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis:''' &lt;br /&gt;
Da ein String, wie jedes Feld, eigentlich ein Zeiger ist, dürfen Sie kein &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; bei &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; angeben!&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
Es werden zwei gleich große Strings definiert: &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;eingabe&amp;lt;/tt&amp;gt;, mit je 20 &amp;quot;nutzbaren&amp;quot; Zeichen. &lt;br /&gt;
In &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; wird die Zeichenkette &amp;lt;tt&amp;gt;&amp;quot;hallo&amp;quot;&amp;lt;/tt&amp;gt; hineinkopiert. Das 0-Zeichen am Ende wird automatisch angefügt. &lt;br /&gt;
Der String wird ausgegeben. Als neues &amp;quot;Sonderzeichen&amp;quot; kommt &amp;lt;tt&amp;gt;%s&amp;lt;/tt&amp;gt; ins Spiel. Es hat die gleiche Aufgabe wie &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt;, nur für Strings. &lt;br /&gt;
Sie werden gebeten, eine String einzugeben. &lt;br /&gt;
Dieser String wird danach in die Variable &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; kopiert. &lt;br /&gt;
Beide Strings, die ja nun die gleiche Zeichenkette enthalten, werden ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===strlen===&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;strlen&amp;lt;/tt&amp;gt;, die als Parameter eine String-Variable erwartet, liefert die Länge diese Strings zurück. Sie werden jetzt vermutlich sagen: &amp;quot;Das ist doch klar, wie lang der String ist. Ich habe es ja bei der Deklaratin angegeben&amp;quot;. Das stimmt schon, aber denken Sie noch einmal an die null-terminierten Strings. Das 0-Zeichen steht am Ende des Strings (am Ende der gültigen Zeichenfolge), aber nicht unbedingt am Ende des reservierten Speicherplatzes. Haben Sie eine Variable &amp;quot;char Variable[21];&amp;quot;, und ihr den Wert &amp;quot;hallo&amp;quot; zugewiesen, dann steht das null-Zeichen in Variable[5]. Der &amp;quot;gültige&amp;quot; String ist also 5 Zeichen (0-4) lang. Und genau das (5) würde strlen zurück liefern. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri[21];&lt;br /&gt;
  &lt;br /&gt;
  strcpy (stri, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
  printf (&amp;quot;Der String ist %d Zeichen lang&amp;quot;, strlen (stri));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird vor allem gebraucht, wenn Sie direkt auf den String zugreifen, mittels &amp;lt;tt&amp;gt;stri[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;stri[1]&amp;lt;/tt&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
==Ein- und Ausgabe-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===Bildschirm-Ausgabe===&lt;br /&gt;
Bisher war das Tutorial trotz aller Beispiele reine Theorie. Sie konnten zwar Programme schreiben, aber die Funktion nicht testen. Hier lernen Sie nun, wie Sie etwas am Bildschirm ausgeben.&lt;br /&gt;
&lt;br /&gt;
Die dazu notwendige Funktione heisst &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (das '&amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt;' ist kein Fehler!). Diese Anweisung gibt die ihr übergebenen Parameter auf das Standard-Ausgabegerät aus, in der Regel also auf den Bildschirm. Sie kann beliebig viele Parameter übernehmen. Es müssen jedoch Standard-Datentypen (z.B. &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;...) sein! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
    int zahl1 = 12;&lt;br /&gt;
    char zeichen1 = 'A';&lt;br /&gt;
    &lt;br /&gt;
    printf (&amp;quot;Das ist Text, und er wird als solcher ausgegeben. \n&amp;quot;);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zahl1' ist: %d \n&amp;quot;, zahl1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %c \n&amp;quot;, zeichen1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %d \n&amp;quot;, zeichen1);&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt Text aus. Das Zeichen am Ende (&amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;) bedeutet &amp;quot;New Line&amp;quot;, es bewegt den Cursor an den Anfang der nächsten Zeile. &lt;br /&gt;
&lt;br /&gt;
Der zweite &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt auch Text aus, am Ende befindet sich wieder das &amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;, um einen Zeilenvorschub zu erreichen. Das &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; wird vom Compiler durch den ersten Parameter ersetzt, der nach dem Text angegeben wird. In diesem Fall wird &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; also durch den Wert der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ersetzt. Das &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; im &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; bedeutet &amp;quot;Dezimalzahl&amp;quot;, der Computer gibt also eine ganze Zahl aus. &lt;br /&gt;
&lt;br /&gt;
In der dritten Ausgabe wird ein Zeichen ausgegeben. Diesmal bedeutet &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; &amp;quot;char&amp;quot; (Zeichen). Es wird also &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; durch ein &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt; ersetzt, denn die Variable &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; wird als Character interpretiert. &lt;br /&gt;
&lt;br /&gt;
Die letzte Ausgabe interpretiert den Inhalt von &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; als Zahl, und gibt dager den ASCII-Wert von &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, also 65 aus. Das ist ein typisches Beispiel für das mögliche unterschiedliche Interpretieren einer  Variablen!&lt;br /&gt;
&lt;br /&gt;
===Tastatur-Eingabe===&lt;br /&gt;
&lt;br /&gt;
Um ein &amp;quot;gscheites&amp;quot; Programm schreiben zu können, muß man wissen, wie der Benutzer über die Tastatur Befehle eingeben kann. Die dafür notwendigen Funktionen stelle ich in diesem Kapitel vor.&lt;br /&gt;
Die wichtigste Funktion ist &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt;. Er liest Daten von der Tastatur. Die Syntax entspricht derer von &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int  zahl1;&lt;br /&gt;
char zeichen1;&lt;br /&gt;
&lt;br /&gt;
printf (&amp;quot;Bitte geben Sie eine Zahl ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl1);&lt;br /&gt;
printf (&amp;quot;Geben Sie einen Zeichen ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%c&amp;quot;, &amp;amp;zeichen1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Programm gibt eine Eingabeaufforderung aus. Dann erwartet es vom Benutzer, daß er eine Zahl eingibt, die mit [ENTER] bestätigt wird. Dieser Wert wird in &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; abgespeichert. Danach erfolgt wiederum eine Aufforderung zur Eingabe, diesmal eines einzelnen Zeichens. Dieses kann man nun eingeben und ebenfalls mit [ENTER] bestätigen.&lt;br /&gt;
&lt;br /&gt;
Macht man keine dem Datentyp der erwarteten Variable entsprechende Eingabe, dann bricht das Programm mit einer Fehlermeldung ab (wenn man z.B. &amp;quot;1_T2&amp;quot; eingibt, wenn eine Zahl erwartet wird)!&lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; vor den Parametern ist notwendig. Warum, das erfahren Sie im Kapitel &amp;quot;Unterprogramme&amp;quot;. Für die Profis eine Kurz-Erklärung: Das Unterprogramm &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; bekommt zwar einen Wert übergeben, kann aber keinen zurückliefern (&amp;quot;call by value&amp;quot;). Daher wird kein Wert, sondern ein Zeiger auf eine Variable übergeben. Mit dem &amp;amp; Zeichen bekommen Sie die Adresse einer Variablen (&amp;quot;call by reference&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=Parameter von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;=&lt;br /&gt;
Das Unterprogramm &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; kann, wie jede andere Funktion, Parameter besitzen. Doch keine selbst gewählten, sondern nur bestimmte. Doch warum braucht main Parameter? Denken Sie einmal an alle Betriebssystembefehle:&lt;br /&gt;
&amp;lt;tt&amp;gt;dir *.exe &amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;copy *.* a:&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;ls -la &amp;lt;/tt&amp;gt;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;&amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen!&lt;br /&gt;
&lt;br /&gt;
=Kurzreferenz=&lt;br /&gt;
==Syntax-Bausteine==&lt;br /&gt;
&lt;br /&gt;
Die Erklärung des Aufbaus von C-Befehlen erfolgt neben einfachen Beispielen auch durch ihren prinzipellen Aufbau. In diesen Syntax-Beschreibungen finden sich immer wieder die gleichen Bausteine, die hier näher erklärt werden sollen. Falls die solch ein Syntax-Baustein begegnet, kannst Du ihn anclicken und kommst dann zu seiner Erläuterung. &lt;br /&gt;
&lt;br /&gt;
In den Beispielen selbst gehören auch die spitzen Klammern zu dem Baustein (was daran zu erkennen ist, daß auch die Klammern eingefärbt sind). Die Klammern dürfen in einem konkreten C-Programm daher nicht eingetippt werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bezeichner&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Bezeichner in C dienen dazu, Variablen zu identifizieren und ihnen sprechende Namen zu geben, um die Quelle lesbarer zu machen. Man braucht Bezeichner auch, um selbstdefinierte Datentypen zu benennen und zum Benennen von Struct- und Union-Komponenten sowie als Namen für Funktionen und Sprungmarken (Labels).&lt;br /&gt;
&lt;br /&gt;
Bezeichner dürfen aus den Kleinbuchstaben &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;z&amp;lt;/tt&amp;gt;, den Großbuchstaben &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;Z&amp;lt;/tt&amp;gt;, dem Unterstrich&amp;amp;nbsp;&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt; und den Ziffern &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;9&amp;lt;/tt&amp;gt; aufgebaut werden, wobei an erster Stelle jedoch keine Ziffer stehen darf.&lt;br /&gt;
&lt;br /&gt;
Es wird zwischen Groß- und Kleinschreibung unterschieden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Ausdruck in C ist ein Konstrukt, das einen Wert hat. Ob dieser Wert eine ganze Zahl ist, eine Kommazahl oder ein Zeiger, etc. ist dabei egal. Die einfachsten Ausdrücke sind Konstanten wie&lt;br /&gt;
 2&lt;br /&gt;
oder Variablen wie&lt;br /&gt;
 ein_zahl&lt;br /&gt;
Mehrere Ausdrücke können durch [[#Liste der Operatoren|Operatoren]] zu komplexeren Ausdrücken kombiniert werden, etwa&lt;br /&gt;
 eine_zahl + andere_zahl == 2&lt;br /&gt;
oder &lt;br /&gt;
 eine_zahl = 2&lt;br /&gt;
Letzterer hat den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; und den Nebeneffekt, daß er diesen Wert an &amp;lt;tt&amp;gt;eine_zahl&amp;lt;/tt&amp;gt; zuweist.&lt;br /&gt;
&lt;br /&gt;
Auch der Aufruf einer Funktion, die einen Rückgabewert liefert, ist ein Ausdruck:&lt;br /&gt;
 sin (1.2)&lt;br /&gt;
und kann zum Aufbau komplexerer Ausdrüche verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bedingung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Bedingung ist ein Ausdruck, bei der nur interessiert, ob dieser zu&amp;amp;nbsp;0 (unwahr) auswertet oder zu ungleich&amp;amp;nbsp;0 (wahr). Solche Ausdrücke findet man in if-Anweisungen, in Schleifenbedingungen und bedingten Zuweisungen&lt;br /&gt;
 (ein_wert &amp;lt; 2) || (ein_wert &amp;gt; 40)&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Lvalue ist ein Ausdruck, dem etwas zugewiesen werden kann. Der Name ''Lvalue'' kommt aus dem Englischen. Das ''L'' steht abkürzend für left. Ein Lvalue ist damit ein Ausdruck, der auf der linken Seite eine Zuweisung in C stehen darf. Das &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; in den folgenden Beispiel-Ausdrücken muss ein Lvalue sein:&lt;br /&gt;
 x = y-1&lt;br /&gt;
&lt;br /&gt;
 x++&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Konstante&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Konstante ist ein Ausdruck, dessen Wert dem Compiler bekannt ist. Beispiele für Konstanten sind etwa&lt;br /&gt;
 7&lt;br /&gt;
 'B'&lt;br /&gt;
 -13.98e12&lt;br /&gt;
 1+(2*3)&lt;br /&gt;
und die Werte von [[#Enum|Enum]]s. &lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; aus dem folgenden Codestück definiert jedoch keine Konstante in diesem Sinne&lt;br /&gt;
 const double Pi = 3.14159256;&lt;br /&gt;
denn in einem anderen Quellmodul könnte durch die Deklaration&lt;br /&gt;
 extern const double Pi;&lt;br /&gt;
das Symbol &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; bekannt sein, ohne daß sein Wert bekannt ist!&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Adresse&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Adresse ist ein Ausdruck, der einen Speicherort (physikalisch oder virtuell) halten kann. Adressen erhält man dadurch, daß man einem Bezeichner den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt;voranstellt, Adressen durch Arithmetik berechnet oder Zahlen zu Adressen castet. Folgende Ausdrücke sind Adressen (eine sinnvolle Deklaration der auftretenden Variablen vorausgesetzt)&lt;br /&gt;
 &amp;amp; eine_zahl&lt;br /&gt;
 &amp;amp; ein_array[10]&lt;br /&gt;
 &amp;amp; ein_struct&lt;br /&gt;
 &amp;amp; ein_struct.komponente&lt;br /&gt;
 (int *) 0x1234&lt;br /&gt;
 (int *) eine_zahl&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Deklaration&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Anweisungen sind gewissermassen die Atome (oder Moleküle?), aus denen ein C-Programm besteht. Jedes C-Programm ist eine Abfolge von Deklarationen und Anweisungen. Einfache Anweisungen erhält man, in dem man einen Ausdruck nimmt und einen Strichpunkt dahinter schreibt:&lt;br /&gt;
 {{Ausdruck|}};&lt;br /&gt;
wie in&lt;br /&gt;
 x = x+1;&lt;br /&gt;
&lt;br /&gt;
Andere Anweisungen sind die unten aufgeführten Schleifen und die if- sowie die switch-Anweisung.&lt;br /&gt;
&lt;br /&gt;
Mehrere Deklarationen und Anweisungen können zu einem Block zusammengefasst werden. Dieser Block stellt dann wieder eine einzelne Anweisung dar und kann genau so gehandhabt werden!&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
In diesem Sinne ist auch z.B. die Syntax der if-Anweisung zu verstehen&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
besagt, daß der abhängig ausgeführte Code eine einzelne Anweisung sein darf oder eben ein kompletter Block oder die Verschachtelung mehrerer Blöcke etc.&lt;br /&gt;
&lt;br /&gt;
Eine Anweisung kann auch &amp;quot;leer&amp;quot; sein, also nichts tun. Diese Anweisungen sind der leere Block&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
und der Strichpunkt&lt;br /&gt;
 ;&lt;br /&gt;
die man gelegentlich in Schleifen findet:&lt;br /&gt;
 while (!timeout())&lt;br /&gt;
    {}&lt;br /&gt;
oder hinter Sprungmarken, die sonst direkt vor einer schliessenden Blockklammer stünden:&lt;br /&gt;
 {&lt;br /&gt;
    ...&lt;br /&gt;
    goto ein_label;&lt;br /&gt;
    ...&lt;br /&gt;
    {{Label|ein_label}}:;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Nicht jede Anweisung ist an jeder Stelle eines C-Programms erlaubt, so darf ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; nut innerhalb einer Schleife stehen. Gleiches gilt für &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;, das aber auch innerhalb eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; vorkommen darf.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Dies steht für einen Datentyp. Es kann ein elementarer Typ sein wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;, ein Zeiger darauf wie &amp;lt;tt&amp;gt;char*&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;void*&amp;lt;/tt&amp;gt;, und auch Qualifier enthalten wie das &amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt; im Typ &amp;lt;tt&amp;gt;unsigned long long&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Zu den Typen gehören auch zusammengesetzte Datentypen wie Strukturen und Unions, mit &amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt; selbst definierte Typen und natürlich Zeiger darauf, wie aus dem Abschnitt [[#Datentypen|Datentypen]]:&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person *&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;data32_t&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;&lt;br /&gt;
und Zeiger auf Funktionen.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Parameterliste&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
Die Parameterliste bei einer Funktionsdefinition gibt an, wieviel Übergabeparameter sie bekommt, wie diese heissen und welchen Typs diese sind. Der prinzipielle Aufbau ist&lt;br /&gt;
 {{Type}} {{Bezeichner}}, {{Type}} {{Bezeichner}}, ...&lt;br /&gt;
Falls die Funktion keine Parameter hat, dann ist die Parameterliste leer.&lt;br /&gt;
&lt;br /&gt;
Hier als Beispiel die zweiparametrige Funktion &amp;lt;tt&amp;gt;produkt&amp;lt;/tt&amp;gt;. Der erste Parameter heisst&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und ist ein &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;. Der zweite namens&amp;amp;nbsp;&amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; ist vom Typ &amp;quot;Zeiger auf double&amp;quot;, der Inhalt &amp;lt;tt&amp;gt;*b&amp;lt;/tt&amp;gt; ist also auch ein double.&lt;br /&gt;
&lt;br /&gt;
'''Definition der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b)&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
In älteren C-Quellen findet man noch eine andere Syntax für die Deklaration der Parameter, die aber heute praktisch nicht mehr verwendet wird:&lt;br /&gt;
'''alte Definition der Funktion:'''&lt;br /&gt;
 double produkt (a, b)&lt;br /&gt;
 double a, *b;&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Um die Funktion bekannt zu machen, werdendet man eine Deklaration bzw. den Prototypen, der dem Compiler nur mitteilt, welche Parameter die Funktion bekommt und was sie zurückliefert. Für den Aufruf der Funktion muss der Compiler nur diesen Prototyp kennen, ''was'' die Funktion im Endeffekt macht und wie sie implementiert wurde ist egal, sie wird als BlackBox angesehen.&lt;br /&gt;
&lt;br /&gt;
'''Prototyp der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b);&lt;br /&gt;
Hier dürfen die Bezeichner auch fehlen:&lt;br /&gt;
 double produkt (double, double*);&lt;br /&gt;
&lt;br /&gt;
==if==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==if-else==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==for==&lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Eine for-Schleife entspricht folgendem Konstrukt. Dabei sind die drei Ausdrücke optional. Fehlt die Bedingung, dann wird diese als &amp;quot;wahr&amp;quot; angenommen. Die beiden anderen Ausdrücke wird man als Ausdrücke mit Nebeneffekt wählen wie z.B. &amp;lt;tt&amp;gt;x=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;x=x-2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
 {&lt;br /&gt;
    {{Ausdruck|1}};&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_loop}}:&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
    else&lt;br /&gt;
       goto _break;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_continue}}:&lt;br /&gt;
    {{Ausdruck|2}};&lt;br /&gt;
    goto _loop;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_break}}:;&lt;br /&gt;
 }&lt;br /&gt;
Die Labels &amp;lt;tt&amp;gt;_break&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_continue&amp;lt;/tt&amp;gt; entsprechen den Sprungzielen einer &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Anweisung innerhalb von &amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==do-while==&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while  ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
==while==&lt;br /&gt;
 while  ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==switch==&lt;br /&gt;
 switch  ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    ...&lt;br /&gt;
  &lt;br /&gt;
    default:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#break-Anweisung|&amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Konstanten|&amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#continue-Anweisung|&amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#do-while-Schleife|&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Enum|&amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#for-Schleife|&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#goto-Anweisung|&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#return-Anweisung|&amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Liste der Operatoren|sizeof]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Strukturen|&amp;lt;tt&amp;gt;struct&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Eigene Datentypen|&amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Unions|&amp;lt;tt&amp;gt;union&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#while-Schleife|&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund2}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Arithmetische Operatoren&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Dies sind die &amp;quot;normalen&amp;quot; arithmetischen Operationen, wie man sie aus der Schule kennt. Man kann damit und allen anderen Operatoren auch komplexere Ausdrücke aufbauen. Die Prioritäten sind so, wie man sie kennt, also &amp;quot;Punktrechnung vor Strichrechnung&amp;quot;. Will man dies ändern, dann mit den runden Klammern:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;1+2*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 7&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(1+2)*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 9&amp;lt;br/&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}}&amp;amp;nbsp;+&amp;amp;nbsp;{{Ausdruck|}}&amp;lt;/tt&amp;gt; || Addition&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} - {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Subtraktion&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} * {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Multiplikation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} / {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Division&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} % {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Rest der Division (modulo)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;- {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Vorzeichenumkehr, Zweier-Komplement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Logische Operatoren und Vergleiche&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die logischen und die vergleichenden Operatoren liefern als Ergebnis den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (wahr) oder einen Wert ungleich&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (falsch, um genau zu sein den Wert &amp;lt;tt&amp;gt;!0&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Man kann das Ergebnis zwar einer Variablen zuweisen, in aller Regel wird man solche Ausdrücke jedoch in Bedingungen zu &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder in Abbruch-Bedingungen von Schleifen finden.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;&amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches AND: beides wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124;&amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches OR: mind. eines ist wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;! {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches NOT (0 &amp;amp;harr; ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} == {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} != {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist nicht gleich&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bitweise Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~ {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise NOT (Einser-Komplement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise AND&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise ODER&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} ^ {{Ausdruck|}}&amp;lt;/tt&amp;gt; ||bitweise XOR&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Shift-Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;lt;&amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Bits nach links schieben&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;gt;&amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Schieben nach rechts schieben&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Typen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Ein Cast in C kann dazu verwendet werden, den Typ eines Ausdruckes zu ändern oder den Ausdruck mit einer bestimmten Genauigkeit zu berechnen. Wird z.B. eine Berechnung standardmässig in 16 Bit ausgeführt, dann kann man mit einem Cast &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(long) &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
ausdrücken, daß die Berechnung in 32 Bit erfolgen soll. Des weiteren kann man Zeiger und ganze Zahlen und Gleitkommazahlen ineinander umwandeln.&lt;br /&gt;
&lt;br /&gt;
Casts können ''nicht'' dazu verwendet werden, um z.B. eine Zahl in einen String zu konvertieren, der diese Zahl darstellt! Dafür gibt es spezielle Funktionen wie &amp;lt;tt&amp;gt;itoa&amp;lt;/tt&amp;gt;!&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Type}}) {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Cast, Typwandlung&lt;br /&gt;
|-&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;| &amp;lt;tt&amp;gt;sizeof ({{Type}})&amp;lt;/tt&amp;gt; || Eine Konstante, deren Wert die Größe (in Bytes) des Typs ist. &amp;lt;tt&amp;gt;sizeof&amp;lt;/tt&amp;gt; ist auch auf Objekte anwendbar wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, Arrays bekannter Größe, Strukturen und Unions,  Array-, Struktur- und Union-Komponenten, Pointer, etc. Beispiel:&amp;lt;br/&amp;gt;&lt;br /&gt;
 int i, sum=0, array[] = { 1, -13, 4, 0, sizeof (int*) };&lt;br /&gt;
 &lt;br /&gt;
 for (i=0; i&amp;lt; sizeof (array) / sizeof (array[0]); i++)&lt;br /&gt;
    sum += array[i];&lt;br /&gt;
Alle Elemente des Arrays werden aufaddiert, ohne daß deren Anzahl explizit in der Schleife genannt ist.&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zeiger und Adressen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;* {{Adresse}}&amp;lt;/tt&amp;gt; || der Inhalt an Adresse&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp; {{Lvalue}}&amp;lt;/tt&amp;gt; || Adresse von&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Strukturen, Unions, Arrays&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Struct&amp;gt;}}.{{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Zeiger-auf-Struct&amp;gt;}} -&amp;gt; {{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union, deren Adresse man hat&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Adresse}}&amp;amp;#91;{{Ausdruck|}}&amp;amp;#93;&amp;lt;/tt&amp;gt; || Array-Element&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bedingte Auswertung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Bedingung}}) ? {{Ausdruck|}} : {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Auswahl des Wertes abhängig von der Bedingung&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zuweisung und Operatoren mit Nebeneffekt&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die Unterschiede der post- und pre-Varianten der Increment/Decrement kommen in Konstrukten wie &amp;lt;tt&amp;gt;x = *p++&amp;lt;/tt&amp;gt; zum tragen:&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *p++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; p = p+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *++p;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; p = p+1; x = *p;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = (*p)++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; *p = (*p)+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = ++(*p);&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; *p = (*p)+1; x = *p;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} = {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Zuweisung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++ {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-- {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Decrement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ++&amp;lt;/tt&amp;gt; || Post-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} --&amp;lt;/tt&amp;gt; || Post-Decrement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Kurzschreibweisen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Für ganz Faule gibt es anstatt&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a = a @ b&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
für viele Operatoren (hier dargestellt durch ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;@&amp;lt;/tt&amp;gt;) die abkürzende Schreibweise&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a @= b&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} += {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} -= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} *= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} /= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} %= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ^= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;lt;&amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;gt;&amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Autoren'''&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
* Kernighan und Ritchie - Buch&lt;br /&gt;
* Christian Wirth , C Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://wwwuser.gwdg.de/~kboehm/ebook/inhalt.html C-Programmieren unter Linux]&lt;br /&gt;
* [http://www.gdv.uni-hannover.de/documentation.php Skripte zum Selbststudium: C, C++, Java, etc]&lt;br /&gt;
* [http://info.baeumle.com/ansic.html Einführung in ANSI-C]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Quellcode C|!]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Inrfb2</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10388</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10388"/>
				<updated>2007-03-13T10:42:59Z</updated>
		
		<summary type="html">&lt;p&gt;Inrfb2: /* Zeiger */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Programmiersprache C wurde 1971 als Gundlage für das Betriebssystem UNIX in den USA entwickelt (UNIX ist zu über 90% in C geschrieben). 1978 wurde von Brian Kernighan und Dennis Ritchie eine eindeutige Sprachdefinition entwickelt. Mittlerweile ist C von ANSI und ISO standardisiert.&lt;br /&gt;
&lt;br /&gt;
Heute sind C und ihr Nachfolger C++ die dominierenden Programmiersprachen. Sehr viele Anwendungen sind in C geschrieben, was inzwischen auch auf eingebettete Systeme zutrifft, die lange in Assembler programmiert werden mussten, da keine ausreichend leistungsfähigen Compiler zur Verfügung standen. &lt;br /&gt;
&lt;br /&gt;
Leider ist C nicht einfach zu lernen &amp;amp;ndash; es wurde weder von noch für Hobby-Programmierer entwickelt &amp;amp;ndash; und eignet sich daher nur bedingt für den Einsteiger. Mit etwas Übung und einem optimierenden Compiler kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
Vom Design her ist C eine Hardware-unabhängig Sprache. Das bedeutet, daß C-Programme mit vertretbarem Aufwand auf ein anderes System portiert werden können. Dazu benötigt man lediglich einen anderen Compiler, und Inline-Assembler-Anweisungen (Assembleranweisungen innerhalb eines C-Programmes) müssen der neuen Hardware (Prozessor) angepasst werden. &lt;br /&gt;
&lt;br /&gt;
==Geschichte==&lt;br /&gt;
;1971: C wird entwickelt&lt;br /&gt;
;1978: Kernighan und Ritchie definieren die Sprache.&lt;br /&gt;
;1983: ANSI und ISO standardisieren C.&lt;br /&gt;
;1992: Bjarne Stroustrup enwickelt die Nachfolgesprache C++.&lt;br /&gt;
&lt;br /&gt;
=Aufbau eines C-Programmes=&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
   C-Programme haben keinen fixen Aufbau wie z.B. Pascal. Es gibt zwar gewisse Regeln, aber sonst sind dem Programmierer alle Freiheiten überlassen. Der folgende &amp;quot;Beispiel-Aufbau&amp;quot; ist daher nicht zwingend und kann durchaus verändert werden.&lt;br /&gt;
&lt;br /&gt;
   Natürlich haben C-Programme einen fixen Aufbau! Ebenso wie Pascal-Programme auch unterliegen sie einer strikten Grammatik! &lt;br /&gt;
Auskommentiert --[[Benutzer:SprinterSB|SprinterSB]] 10:23, 17. Feb 2006 (CET)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Ein einfaches C-Programm könnte folgendermassen aussehen. Das Programm tut eigentlich nichts, aber das Beispiel zeigt den prinzipiellen Aufbau. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 int Zahl1;&lt;br /&gt;
 char Zeichen1;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int zahl2;&lt;br /&gt;
 &lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Beschreibung:'''&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndash; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
 {{comment|void-Definition von main ist nur beim Controller ueblich}}&lt;br /&gt;
 {{comment|spezielle Compilereinstellungen sind noetig, damit bei dieser Definition von main}}&lt;br /&gt;
 {{comment|kein Fehler/Warnung erzeugt wird.}}&lt;br /&gt;
 void main ()&lt;br /&gt;
 {&lt;br /&gt;
     ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
 int main (void)&lt;br /&gt;
 {  {{comment|der Block &amp;quot;main&amp;quot; beginnt}}&lt;br /&gt;
    int zahl;&lt;br /&gt;
    &lt;br /&gt;
    {   {{comment|ein Block beginnt}}&lt;br /&gt;
        {{comment|hier koennen Deklarationen und Anweisungen stehen}}&lt;br /&gt;
    }   {{comment|der Block endet}}&lt;br /&gt;
   &lt;br /&gt;
    return 0;&lt;br /&gt;
 }  {{comment|&amp;quot;main&amp;quot; endet}}&lt;br /&gt;
&lt;br /&gt;
=Datentypen=&lt;br /&gt;
==Elementare Datentypen==&lt;br /&gt;
Der Datentyp einer Variable gibt an, welche Werte eine Variable enthalten kann, welcher Art diese Daten sind und wie sie verarbeitet werden, etwa in arithmetischen Operationen wie einer Addition. So ist es zum Beispiel möglich, in eine Variable vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ganze Zahlen zwischen ca. -32000 und +32000 einzutragen. In einer char-Variable können ASCII-Zeichen gespeichert werden (alles, was Sie mit der Tastatur erzeugen können) oder ganze Zahlen von -128 bis 127.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da C plattformabhängig ist, hängt die Größe eines Datentypes zum Teil von der genutzten Hardware (z.B. 8, 16 oder 32 Bit-Controller) und dem Compiler und dessen Einstellungen ab!&lt;br /&gt;
&lt;br /&gt;
===int, char, short, long (ganze Zahlen)===&lt;br /&gt;
In Variable dieser Typen können Sie ganze Zahlen abspeichern, also z.B. 1, &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;2, 100, 12345. Jeden dieser Typen gibt es in zwei Ausprägungen: als &amp;quot;&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;quot;, also als vorzeichenbehafteten Typ, und als &amp;quot;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&amp;quot;, also ohne Vorzeichen, d.h. das Vorzeichen wird als 0 oder +1 genommen. &lt;br /&gt;
&lt;br /&gt;
Vorzeichenbehaftete Ganzzahl-Typen werden intern im &amp;lt;tt&amp;gt;n-1&amp;lt;/tt&amp;gt;-Komplement dargestellt, das Vorzeichen selbst findet sich also im höchstwertigen Bit. Werden zur Speicherung ''b'' Bits verwendet, dann reicht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;z.B. *zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==Enum==&lt;br /&gt;
&lt;br /&gt;
Über &amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt; können Aufzählungen definiert werden. Die Werte sind &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Werte und beginnen mit&amp;amp;nbsp;0. Der folgende enum hat einen um&amp;amp;nbsp;1 grösseren Wert. Mit einer Zuweisung können auch andere Werte zugeordnet werden. Klarer wird's im Beispiel:&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 enum Farben&lt;br /&gt;
 {&lt;br /&gt;
    ROT,&lt;br /&gt;
    GRUEN,&lt;br /&gt;
    BLAU,&lt;br /&gt;
    BRAUN = 5,&lt;br /&gt;
    SCHWARZ&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
Dies definiert die Konstanten &amp;lt;tt&amp;gt;ROT=0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;GRUEN=1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BLAU=2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BRAUN=5&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;SCHWARZ=6&amp;lt;/tt&amp;gt; und den Typ &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void foo (enum Farben farbe)&lt;br /&gt;
{&lt;br /&gt;
   switch (farbe)&lt;br /&gt;
   {&lt;br /&gt;
      case ROT:&lt;br /&gt;
         ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit kann man anstatt &amp;quot;magischer&amp;quot; Zahlen sprechende Namen im Code verwenden, etwa in Berechnungen und Zuweisungen, Vergleichen oder als Konstante hinter einem &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zusammengesetzte Datentypen==&lt;br /&gt;
===Arrays===&lt;br /&gt;
Oft muß man sehr viele Werte gleichzeitig abspeichern und betrachten, die alle der selben Aufgabe dienen. Man schreibt z.B. ein Programm, das 10 Zahlen einlesen und anschließend wieder ausgeben soll. Man könnte das natürlich mit 10 einzelnen Variablen bewerkstelligen, aber es ist sinnvoller, dabei Arrays &amp;amp;ndash; teilweise auch als ''Felder'' bezeichnet &amp;amp;ndash; zu verwenden.&lt;br /&gt;
&lt;br /&gt;
In einem Array werden mehrere Variablen gleichen Typs zusammengefasst und hintereinander im Speicher abgelegt. So kann man viele tausend Variablen anlegen mit nur einer Zeile Code. Doch es gibt noch größere Vorteile: Sie können das Array mit einer Schleife ganz einfach nach Werten durchsuchen. Stellen Sie sich vor, Sie müssten mit 100 verschiedenen Variablen &amp;lt;tt&amp;gt;Zahl_00&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;Zahl_99&amp;lt;/tt&amp;gt; arbeiten!&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}}&amp;amp;#91;{{Konstante}}&amp;amp;#93;;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 unsigned int werte[100];&lt;br /&gt;
&lt;br /&gt;
Der Name muß natürlich ein gültiger Bezeichner sein, als Datentyp kann jeder Typ genommen werden &amp;amp;ndash sowohl elementare Datentypen als auch Zeiger, Strukturen, Unions oder selbst definierte Datentypen. In der eckigen Klammer wird die Anzahl der Elemente bekanntgegeben. Ein mit [3] definiertes Array hat Platz für drei Variablen. Da der Index immer bei 0 beginnt, greift man also mit &amp;lt;tt&amp;gt;[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;[1]&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;[2]&amp;lt;/tt&amp;gt; auf den jeweilige Inhalt zu. Um auf eine der im Array enthaltenen Variablen zugreifen zu können, müssen Sie den Variablennamen und in eckigen Klammern den Index (die &amp;quot;Nummer&amp;quot;) der Variablen angeben. Diese Variable verhält sich dann wie eine ganz normale Variable des jeweiligen Datentypes. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #define NZAHLEN 10&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int i;&lt;br /&gt;
    int zahlen[NZAHLEN];  {{comment|zahlen[0] ... zahlen[9]}}&lt;br /&gt;
  &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++)&lt;br /&gt;
    {&lt;br /&gt;
       printf (&amp;quot;Bitte Zahl %d eingeben: &amp;quot;, i);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; zahlen[i]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++) &lt;br /&gt;
       printf (&amp;quot;Zahl %d ist: %d\n&amp;quot;, i, zahlen[i]);&lt;br /&gt;
      &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 10 int-Variablen großes Array angelegt. &lt;br /&gt;
In dieses wird nun der Reihe nach 10 Zahlen eingelesen. &lt;br /&gt;
Anschließend werden alle 10 Zahlen ausgegeben. &lt;br /&gt;
&lt;br /&gt;
Dabei wird die Größe der Arrays und das Schleifenende über das Define &amp;quot;&amp;lt;tt&amp;gt;NZAHLEN&amp;lt;/tt&amp;gt;&amp;quot; angegeben. Dadurch muss nur ''eine Stelle'' im Code geändert werden, wenn die Größe des Arrays einmal einen anderer Wert als 10 haben soll &amp;amp;ndash; dies vermeidet Fehler die dadurch entstehen, wenn man beim Anpassen der Array-Größe eine Codestelle vergisst, zudem wird der Code lesbarer als wenn irgendwo die Zahl &amp;quot;10&amp;quot; auftaucht.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
:Wird ein ungültiger Index angeben (einer, der in der Deklaration nicht enthalten ist) können  undefinierte Dinge passieren, wenn dadurch andere Variableninhalte oder Programmcode überschrieben wird, der hinter oder vor dem Array im Speicher liegt. Schlimmstenfalls kann sogar der Computer/Controller abstürzen. Also darauf achten, daß keine ungültigen Werte als Index auftreten!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Strings (Zeichenketten)===&lt;br /&gt;
Ein String ist nichts anderes als ein Array, das aus einzelnen Zeichen (&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;) gebildet wird. Die Ausgabe auf dem Bildschirm funktioniert am einfachsten mittels Strings.&lt;br /&gt;
&lt;br /&gt;
Die Definition eines Strings erfolgt also genauso wie bei Arrays:&lt;br /&gt;
 char string[21];&lt;br /&gt;
&lt;br /&gt;
Nun haben Sie eine String, in dem Sie 21 Zeichen speichern können. Ganz richtig ist das jedoch nicht. C arbeitet mit &amp;quot;null-terminierten Strings&amp;quot;. Das beudeutet, dass die Länge des Strings nicht abgespeichert wird, sondern das Zeichen mit dem ASCII-Wert 0 das Stringende kennzeichnet. Daher auch die Bezeichnung  &amp;quot;null terminiert&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Das letzte Zeichen eines Strings muß daher immer das ASCII-Zeichen Nr. 0 sein. Ist es das nicht, hat der String kein definiertes Ende, und wenn Sie versuchen, ihn durch eine Standard-Funktion auszugeben zu lassen, könnte es eine Weile dauern, bis sich im Speicher zufällig irgendwo eine 0 befindet. Es stehen ihnen daher bei dem Beispiel nur 20 Zeichen zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
===Mehrdimensionale Arrays===&lt;br /&gt;
Manchmal benötigt man mehr als nur ein eindimensionales Array, wie Sie es bisher kennengelernt haben. Auch dies ist kein Problem. In der Deklaration geben Sie einfach mehrere eckige Klammern hintereinander an. Aber Vorsicht: der Speicherplatz ist begrenzt, ein &amp;quot;&amp;lt;tt&amp;gt;char feld[1024][1024]&amp;lt;/tt&amp;gt;&amp;quot; hat die Speicherplatzgrenzen vermutlich bereits weit überschritten, und der Compiler wird einen (bei gewissen Einstellung auch keinen) Fehler liefern.&lt;br /&gt;
Beim Zugriff auf mehrdimensionale Felder müssen auch mehrere Indizes angeben werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  int x,y;&lt;br /&gt;
  int feld[3][5];&lt;br /&gt;
 &lt;br /&gt;
  for (x=0; x&amp;lt;3; x++) &lt;br /&gt;
  {&lt;br /&gt;
     for (y=0; y&amp;lt;5; y++)&lt;br /&gt;
     {&lt;br /&gt;
       printf (&amp;quot;Feldwert x: %d,  y: %d &amp;quot;, x, y);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; feld[x][y]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  for(x=0; x&amp;lt;3; x++) &lt;br /&gt;
     for (y=0; y&amp;lt;5; y++) &lt;br /&gt;
        printf (&amp;quot;Wert: feld[%d][%d] = %d\n&amp;quot;, x, y, feld[x][y]);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 3 mal 5 &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array angelegt. &lt;br /&gt;
Dann werden die Werte eingegeben: zuerst &amp;lt;tt&amp;gt;feld[0][0]&amp;lt;/tt&amp;gt;, dann &amp;lt;tt&amp;gt;feld[0][1]&amp;lt;/tt&amp;gt;, usw. bis &amp;lt;tt&amp;gt;feld[2][4]&amp;lt;/tt&amp;gt;. &lt;br /&gt;
Zum Schluß werden alle Werte noch einmal ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===Strukturen===&lt;br /&gt;
In C können Sie sogenannte &amp;quot;Strukturen&amp;quot; definieren. Dabei handelt es sich um eine Zusammenfassung mehrerer Datentypen zu einem größeren. Im Unterschied zu Feldern können in Strukturen unterschiedliche Datentypen zusammengestellt und gespeichert werden: &lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 struct {{Bezeichner}}&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur 'Person'}}&lt;br /&gt;
 struct Person &lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;lt;tt&amp;gt;struct Person {&amp;lt;/tt&amp;gt;&amp;quot; leitet die Definition der Struktur mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;Person&amp;lt;/tt&amp;gt;&amp;quot; ein. &lt;br /&gt;
Dann werden in dieser Struktur fünf Komponenten definiert: drei Strings und zwei &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. &lt;br /&gt;
mit &amp;lt;tt&amp;gt;}&amp;lt;/tt&amp;gt; wird die Definition abgeschlossen. Sie haben damit einen Datentyp erstellt. Um eine Variable des Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach an&lt;br /&gt;
 struct Person {{Bezeichner}};&lt;br /&gt;
&lt;br /&gt;
Zum Zugriff auf eine Komponente der Struktur gibt man den Namen der Struktur-Variablen an (im folgenden Beispiel also &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;klaus&amp;lt;/tt&amp;gt;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
 {{comment|Definition zweier Struktur-Variablen}}&lt;br /&gt;
 struct Person hubert, klaus;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Zugriff auf Struktur-Komponenten}}&lt;br /&gt;
 hubert.alter = 32;&lt;br /&gt;
 klaus.alter = hubert.alter + 1;&lt;br /&gt;
&lt;br /&gt;
===Unions===&lt;br /&gt;
Eine Union wird ganz analog zu einer Struktur deklariert und verwendet. Sie unterscheidet sich von einer Struktur jedoch dadurch, daß ihre Elemente nicht nacheinander im Speicher abgelegt werden, sondern sich überlagern. Auf die in einer Union enthaltenen Daten gibt es also verschiedene Sichten: je nachdem, welche Sicht bzw. Interpretation der Daten man gerne hätte, wählt man den gewünschten Zugriff.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
union Daten &lt;br /&gt;
{&lt;br /&gt;
   int id;&lt;br /&gt;
&lt;br /&gt;
   struct Person u_person;&lt;br /&gt;
&lt;br /&gt;
   struct u_double&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      double wert;&lt;br /&gt;
   };&lt;br /&gt;
&lt;br /&gt;
   struct u_pointer&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      union Daten * p1;&lt;br /&gt;
      union Daten * p2;&lt;br /&gt;
   };&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
union Daten data;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies definiert eine Union mit den vier Zugriffsmöglichkeiten &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_double&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Größe der Union richtet sich dabei nach der grössten Komponente. In diesem Beispiel sind alle Komponenten so angelegt worden, daß sie an erster Stelle ein &amp;lt;tt&amp;gt;int id&amp;lt;/tt&amp;gt; enthalten. In &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; könnte man sich also merken, wie die Daten in der Union zu interpretieren sind. Würde &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; nicht dieses &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; enthalten, so würde sich &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; mit &amp;lt;tt&amp;gt;data.u_person.vname&amp;lt;/tt&amp;gt; überlagern. Ein Ändern der ersten Buchstaben von &amp;lt;tt&amp;gt;vname&amp;lt;/tt&amp;gt; hätte also ein Ändern von &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; zur Folge, und man könnte es nicht mehr als Merker verwenden. Mit diesem Feld überlagert das &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; die &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;-Felder der anderen Sichten, z.B. ist &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; der selbe Zugriff wie auf &amp;lt;tt&amp;gt;data.u_person.id&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein anderes Beispiel ist eine Union, die es ermöglicht, auf die einzelnen Bytes eines &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; zuzugreifen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef union&lt;br /&gt;
{&lt;br /&gt;
   unsigned long  as_long;&lt;br /&gt;
   unsignen short as_short[2];&lt;br /&gt;
   unsignen char  as_byte[4];&lt;br /&gt;
} data32_t;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies überlagert einen &amp;lt;tt&amp;gt;unsigned long&amp;lt;/tt&amp;gt; &amp;amp;ndash; also eine 32-Bit-Zahl &amp;amp;ndash; mit vier Bytes bzw. zwei Shorts.&lt;br /&gt;
 data32_t wert;&lt;br /&gt;
 &lt;br /&gt;
 wert.as_long = 0x12345678;&lt;br /&gt;
 wert.as_byte[0] = 0xab;&lt;br /&gt;
 {{comment|nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform)}}&lt;br /&gt;
&lt;br /&gt;
==Eigene Datentypen==&lt;br /&gt;
&lt;br /&gt;
=Variablen=&lt;br /&gt;
Eine Variable ist ein Synonym (=anderer Name) für eine Speicherstelle in einem Computer. Einfacher gesagt, eine Variable bietet Raum, um Daten wie Zahlen oder Zeichen zu speichern und wieder zu lesen.&lt;br /&gt;
&lt;br /&gt;
==Variablennamen==&lt;br /&gt;
Ein Variablenname kann zusammengesetzt werden aus den Buchstaben &amp;lt;tt&amp;gt;'''A'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''Z'''&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;'''a'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''z'''&amp;lt;/tt&amp;gt;, den Ziffern &amp;lt;tt&amp;gt;'''0'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''9'''&amp;lt;/tt&amp;gt;, sowie dem Sonderzeichen &amp;quot;Unterstrich&amp;quot; (underscore) &amp;lt;tt&amp;gt;'''_'''&amp;lt;/tt&amp;gt;. Dabei darf an erster Stelle keine Ziffer stehen. Die Bezeichner &amp;lt;tt&amp;gt;hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALLO&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALL0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;_123&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_HALLO&amp;lt;/tt&amp;gt; sind also alle gültige und unterschiedliche Variablennamen.&lt;br /&gt;
&lt;br /&gt;
==Anlegen von Variablen==&lt;br /&gt;
Um eine Variable verwenden zu können, muss sie zuerst vereinbart (&amp;quot;erzeugt&amp;quot;) werden. Dies wird auch als &amp;quot;''Definition der Variablen''&amp;quot; bezeichnet und geht so: Schreiben Sie zuerst den Datentyp, dann den Namen der Variablen. Zum Schluß kommt noch der Strichpunkt, wie nach jeder C-Anweisung oder Deklaration. Und nicht vergessen: C unterscheidet zwischen  Groß- und Kleinschreibung! &lt;br /&gt;
 int Zahl1, Zahl2;&lt;br /&gt;
 char Zeichen;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    float gleitZahl;&lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:'''&lt;br /&gt;
In einer Zeile können auch mehrere Variablen gleichen Types vereinbart werden, wenn man ein Komma dazwischen setzt. Variablen können in jedem Block vereinbart werden. Siehe [[#Gültigkeitsbereich|Gültigkeitsbereich]].&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen==&lt;br /&gt;
Man kann einer vereinbarten Variable Werte [[#Zuweisungen|zuweisen]]. Dazu schreibt man zuerst den Variablennamen, ein Gleichheitszeichen &amp;quot;&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;&amp;quot; und anschliessend den zuzuweisenden [[#Ausdrücke|Ausdruck]]. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, zahl2 = 12;&lt;br /&gt;
  char zeichen1 = 'A';&lt;br /&gt;
&lt;br /&gt;
  zahl1 = 52;&lt;br /&gt;
  zeichen1 = zeichen1 + 1; &lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Zuerst werden drei Variablen angelegt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;: wird gleich bei der Vereinbarung der Wert 12 zugewiesen. &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl1 = 52&amp;lt;/tt&amp;gt;: Hier wird der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; der Wert 52 zugewiesen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;: wird um 1 erhöht. Da in der Variablen &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; gespeichert ist, gibt sich ihr neuer Wert aus &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt;. Weil &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; dem Wert 65 entspricht, ist &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt; gleich 66, was dem Wert für &amp;lt;tt&amp;gt;'B'&amp;lt;/tt&amp;gt; entspricht.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei float==&lt;br /&gt;
Das funktioniert genau wie bei normale Zuweisungen. Nachkommastellen werden durch einen Punkt abgegrenzt: &lt;br /&gt;
 floatVariable = 3.14;&lt;br /&gt;
Zusätzlich kann eine Zehnerpotenz angegeben werden:&lt;br /&gt;
 floatVariable2 = -1.234E-6;&lt;br /&gt;
Dadurch wird der erst Wert mit 10&amp;lt;sup&amp;gt;&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;6&amp;lt;/sup&amp;gt; multipliziert, der Wert der Variablen ist also &lt;br /&gt;
:&amp;lt;math&amp;gt;-1{,}234\cdot10^{-6} = -0.000001234&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei logischen Variablen==&lt;br /&gt;
Wie bereits erwähnt, besitzt C keinen logischen Datentyp. Es müssen also &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; dafür genutzt werden. Die Zuweisung entpricht der Standard-Zuweisung. Wird der Wert 0 zugewiesen, dann ist die Variable &amp;quot;unwahr&amp;quot;, ansonsten ist sie &amp;quot;wahr&amp;quot;. &lt;br /&gt;
 intVariable = !0;   /* entspricht &amp;quot;wahr&amp;quot;   */&lt;br /&gt;
 intVariable = 0;    /* entspricht &amp;quot;unwahr&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
==Konstanten==&lt;br /&gt;
Konstanten können als Variable angesehen werden, die nicht beschrieben, sondern nur gelesen werden können. Ein typisches Beispiel dafür ist die Zahl &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; (rund 3,141592654). Niemand würde in der realen Welt versuchen, ihr einen anderen Wert zuzuweisen. Würde man &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; jedoch wie eine normale Variable anlegen, wäre dies ohne weiteres möglich. Um dies zu verhindern, gibt es das Schlüsselwort &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in C:&lt;br /&gt;
 const {{Type}} {{Bezeichner}} = {{Konstante}};  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Wichtig dabei ist, dass man Konstanten nur bei der Vereinbarung einen Wert zuweisen kann. &lt;br /&gt;
Da Konstanten gewöhnlich im gesamten Programm, zumindest einer Quelldatei genutzt werden, definiert man diese allerdings gewöhnlich außerhalb des main-Blockes entweder am Anfang eines Programmes, oder in einer sogenannten Header-Datei, die per &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; eingebunden wird.&lt;br /&gt;
 const float PI = 3.141592;  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Es sei jedoch erwähnt, daß auch einer Konstanten nachträglich ein anderer Wert zugewieden werden kann. Im obigen Beispiel könnte mit&lt;br /&gt;
 * ((float*) &amp;amp;PI) = 2;&lt;br /&gt;
der Wert von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; im Nachhinein verändert werden. Es wird die Adresse von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; genommen und diese Adresse durch den Cast in eine ganz normale &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;-Adresse umgewandelt, über welche der Wert geändert wird. Die sei der Vollständigkeit halber erwähnt.&lt;br /&gt;
&lt;br /&gt;
Je nachdem, an welcher Stelle sich das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; bei einer Pointer-Deklaration befindet, markiert es den Pointer als konstant oder das Objekt, auf das dieser Pointer zeigt. Eine häufige Parameterdeklaration in Ausgabe-Funktionen, die einen String erhalten, ist&lt;br /&gt;
 void foo (const char * str, ...);&lt;br /&gt;
Dadurch ist &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; der Zeiger auf eine Zeichenkette, die innerhalt der Funktion nicht verändert wird bzw. verändert werden darf. Eine Zuweisung wie &amp;lt;tt&amp;gt;*str = 'a'&amp;lt;/tt&amp;gt; ergibt also einen Fehler. &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; selbst kann aber sehr wohl verändert werden, etwa mit &amp;lt;tt&amp;gt;str++&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Soll ausgedrückt werden, daß &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; unveränderlich ist, dann so:&lt;br /&gt;
 void foo (char * const str, ...);&lt;br /&gt;
Jetzt wäre eine Änderung des Strings in Ordnung, etwa durch &amp;lt;tt&amp;gt;str[10] = 'a'&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Um sich zu merken, worauf das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; wirkt, trennt man die Deklaration in Gedanken beim&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf: Steht das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; links vom&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, dann gehört es zum &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, steht es rechts davon, dann gehört es zum Pointer. Natürlich ist es auch denkbar, beides &amp;amp;ndash; also den Zeiger und sein Ziel &amp;amp;ndash; als konstant zu markieren.&lt;br /&gt;
&lt;br /&gt;
==Gültigkeitsbereich==&lt;br /&gt;
In C können mehrere Variablen den gleichen Namen haben, solange eindeutig ist, welche in welchen Block gültig ist. Dabei gelten folgende Regeln: &lt;br /&gt;
&lt;br /&gt;
;Lokale Variablen: sind Variablen, die innerhalb eines Blockes definiert werden. Jede Variable ist nur in dem Block gültig, in dem sie vereinbart wurde, sowie in allen darin enthaltenen Blöcken; es sei denn, in einem Unter-Block wird eine Variable gleichen Namens definiert. Dann bezieht sich in diesem Unter-Block der Bezeichner auf die im Unter-Block angelegte Variable.&lt;br /&gt;
;Globale Variablen: werden ausserhalb jedes Blockes definiert und gelten ab der Stelle, an der sie deklariert werden, siehe auch [[#Deklaration und Definition|Deklaration und Definition]]. Wird jedoch in einem Block eine Variable gleichen Namens angelegt, gilt ab hier bis zum Ende des Blocks nicht mehr die globale Variable, sondern die im Block deklarierte. Das Spiel kann man weiterspielen: wird in einem Unter-Block wieder eine namensgleiche Variable angelegt, gilt diese in dem Unterblock.&lt;br /&gt;
&lt;br /&gt;
==Speicherklassen==&lt;br /&gt;
Jede Variable in C gehört zu einer bestimmten Speicherklasse&lt;br /&gt;
;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;: Lokale Variablen sind in aller Regal sogenannte ''automatische Variablen''. Das bedeutet, sie werden automatisch angelegt, wenn ein Block bzw. eine Funktion betreten wird und danach wieder entfernt. Das Schlüsselwort &amp;quot;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;&amp;quot; wird praktisch nie hingeschrieben, denn lokale Variablen ohne die ausdrückliche Angabe einer Speicherklasse, sind automatisch automatische Variablen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;: Eine externes Symbol ist im ganzen Programm bekannt bzw. in dem Block, in der die Deklaration steht. In unterschiedlichen Blöcken stehende Deklarationen beziehen sich auf das gleiche Symbol! Obgleich das Datum global zugreifbar ist, ist der Gültigkeitsbereich auf den deklarierenden Block begrenzt bzw. auf das deklarierende Quell-Modul, sofern das Symbol ausserhalb jedes Blocks des Moduls deklariert wird. Siehe auch [[#Deklaration und Definition|Deklaration und Definition]].&lt;br /&gt;
;&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;: Die Variable ist im Block gültig bzw. im Quell-Modul (also in der C-Datei, in der die angelegt wurde), wenn sie nicht innerhalb eines Blockes angelegt wurde. Statische Variablen werden nicht in Registern oder im Frame der Funktion angelegt, sondern im selben Speicherbereich, in dem auch die globalen Variablen liegen; Konstanten evtl. auch im Flash. Eine lokale Variable, die als &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; angelegt wird, &amp;quot;überlebt&amp;quot; also das Verlassen des Blocks und hat beim neuerlichen Betreten des Blockes ihren bisherigen Wert. In unterschiedlichen Blöcken angelegte lokale statische Variablen beziehen sich auf unterschiedliche Speicherstellen, genau wie bei lokalen Variablen auch.&lt;br /&gt;
;&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;: Durch diese Speicherklasse wird eine Variable &amp;amp;ndash; falls möglich &amp;amp;ndash; als Registervariable angelegt, also in einem Maschinenregister des Computer/Controllers gehalten. Dadurch kann auf solche Variablen besonders schnell zugegriffen werden. Dieses Schlüsselwort ist bei modernen Compilern weitgehend überflüssig, da die entsprechenden Optimierungen selbständig vorgenommen werden, wenn ausreichend Register vorhanden sind. Auch globale Variablen können als Register angelegt werden, davon ist dem Anfänger aber dringend abzuraten, weil leicht schwerauffindbare Fehler und Abstürze auftreten, wenn man nicht genau weiss, welche Implikationen in einer solchen Definition stecken!&lt;br /&gt;
;&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;: (FIXME: volatile ist ein Qualifier und keine Speicherklasse) Dies ist das genaue Gegenteil von &amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt; und bewirkt, dass die Variable auf keinen Fall in einem Register zwischengespeichert werden darf, sondern immer aus dem RAM gelesen und ins RAM geschrieben werden soll. &amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt; müssen alle ''globalen'' Variablen markiert werden, die in [[ISR | Interrupt-Handlern]] verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Ausdrücke=&lt;br /&gt;
Eine Variable oder eine Konstante in C stellen einfache Ausdrücke dar.&lt;br /&gt;
Diese elementaren Ausdrücke können durch Operatoren miteinander verknüpft werden und so zu neuen, komplexeren Ausdrücken zusammen gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Einfache Beispiele für Ausdrücke sind also z.B.:&lt;br /&gt;
 1&lt;br /&gt;
 a&lt;br /&gt;
 'a'&lt;br /&gt;
 1 + a&lt;br /&gt;
 a == 1&lt;br /&gt;
&lt;br /&gt;
Auch Funktionen können einen Wert zurückliefern und in Ausdrücken weiter benutzt werden.&lt;br /&gt;
In den folgenden Abschnitten wird gezeigt, welche Operatoren in C vorhanden sind,&lt;br /&gt;
und wei man damit neue Ausdrücke aufbauen kann.&lt;br /&gt;
&lt;br /&gt;
==Lvalues==&lt;br /&gt;
&lt;br /&gt;
Ein Lvalue in C ist ein Ausdruck, dem ein anderer Ausdruck zugewiesen werden kann, dessen Wert also durch eine Zuweisung verändert werden kann.&lt;br /&gt;
das 'L' leitet sich ab von 'left' bwz. 'links' und das 'value' bedeutet Wert: Ein Lvalue ist ein Ausdruck, der auf der linken Seite einer Zuweisung stehen darf. Ein Lvalue ist also immer auch ein gültiger Ausdruck, aber die Umkehrung gilt in alles Regel nicht.&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für einen Lvalue ist eine &amp;quot;normale&amp;quot; Variable, die nicht mit &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; als Konstante markiert ist:&lt;br /&gt;
 a = 1;&lt;br /&gt;
Hingegen ist der Ausdruck &amp;lt;tt&amp;gt;a+1&amp;lt;/tt&amp;gt; kein Lvalue, denn eine Zuweisung wie&lt;br /&gt;
 a+1 = 2;&lt;br /&gt;
die mathematisch durchaus sinnvoll ist, erzeugt einen Compilerfehler, der etwa lauten könnte &amp;quot;illegal lvalue in assignment&amp;quot;:&lt;br /&gt;
&amp;quot;ungültiger Wert in Zuweisung&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Andere Beipiele für Lvalues sind die Komponenten von (nicht-konstanten) [[#Strukturen|Strukturen]] und [[#Unions|Unions]], [[#Arrays|Array]]-Elemente und die Dereferenzierungen von Pointern: Die Konstante&amp;amp;nbsp;4 wird durch den Cast in eine Adresse umgewandelt. Über die Dereferenzierung&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; wird an die Adresse&amp;amp;nbsp;4 im Speicher eine&amp;amp;nbsp;3 geschrieben. Ob das erlaubt bzw. sinnvoll ist, ist abhängig von der jeweiligen Architektur.&lt;br /&gt;
 * ((unsigned int *) 4) = 3;&lt;br /&gt;
Hier ist der gesamte &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;-Ausdruck ein Lvalue&lt;br /&gt;
&lt;br /&gt;
==Logische (boolsche) Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp;amp;&amp;amp;amp; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr oder &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; || gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; || ungleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;= b&amp;lt;/tt&amp;gt; || kleiner oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt; b&amp;lt;/tt&amp;gt; || kleiner als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt;= b&amp;lt;/tt&amp;gt; || glösser oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt; b&amp;lt;/tt&amp;gt; || grösser als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; nicht wahr und vice versa&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine interessante Eigenschaft der Operatoren &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;amp;amp;&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; ist, dass&lt;br /&gt;
sie die Auswertung abbrechen, sobald das Ergebnis feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet. Ein oft anzutreffendes Codestück sieht so aus, dabei sei &amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
  if (p &amp;amp;&amp;amp; *p == 5)&lt;br /&gt;
  {&lt;br /&gt;
     {{comment|mach was}}&lt;br /&gt;
  }&lt;br /&gt;
Zuerst wird in der Bedinung geprüft, ob Zeiger&amp;amp;nbsp;&amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; einen Wert ungleich Null hat, also ob er überhaupt einen gültigen Wert enthält. Es ist weit verbreitete Konvention in C, daß Zeiger, die keinen gültigen Wert haben, die Adresse&amp;amp;nbsp;0 enthalten. '''Nur dann, wenn ein Zeiger nicht ein Null-Pointer ist, darf überhaupt ein Zugriff über ihn erfolgen!'''&lt;br /&gt;
&lt;br /&gt;
==Vergleich von Variablen==&lt;br /&gt;
Skalare Variablen (also ganze Zahlen, Gleitkommazahlen, Zeiger) können miteinander verglichen werden. Dazu gibt es die folgenden Operatoren in C: &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; || ist nicht gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;=&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;=&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das Ergebnis der Auswertung ist eine ganze Zahl. Ist die Bedingung erfüllt, dann ist der Wert ungleich&amp;amp;nbsp;0. Ist die Bedingung nicht erfüllt, dann ist ihr Wert gleich&amp;amp;nbsp;0.&lt;br /&gt;
Meistens wird man diese Operatoren in &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Konstrukten finden wie zum Beispiel&lt;br /&gt;
 if (x &amp;gt;= 10)&lt;br /&gt;
    x = 10;&lt;br /&gt;
oder in Abbruchbedingungen von Schleifen, wie sie weiter unten erklärt werden.&lt;br /&gt;
&lt;br /&gt;
Es ist auch möglich, das Ergebnis der Auswertung in einer &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Variablen zu speichern:&lt;br /&gt;
 int i;&lt;br /&gt;
 int z1, z2;&lt;br /&gt;
 &lt;br /&gt;
 z1 = 5;&lt;br /&gt;
 z2 = 100;&lt;br /&gt;
 i = z1 &amp;lt;= z2;  {{comment|Ein Vergleich. i wird &amp;quot;wahr&amp;quot;, da z1 kleinergleich z2 ist}}&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich&amp;amp;nbsp;0 (&amp;quot;wahr&amp;quot;), wenn &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; kleiner oder gleich &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt; ist. Ist &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; jedoch größer als &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt;, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich&amp;amp;nbsp;0 (&amp;quot;unwahr&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
==Arithmetische Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a + b&amp;lt;/tt&amp;gt; || Summe (Addition)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a - b&amp;lt;/tt&amp;gt; || Differenz (Subtraktion)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a * b&amp;lt;/tt&amp;gt; || Produkt (Multiplikation)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a / b&amp;lt;/tt&amp;gt; || Quotient (Division, evtl. mit Rest)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a % b&amp;lt;/tt&amp;gt; || Rest bei Division (Modulo)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;-a&amp;lt;/tt&amp;gt; || Vorzeichenumkehr (Zweierkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Bit-Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp; b&amp;lt;/tt&amp;gt; || bitweise und (and)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || bitweise oder (or)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a ^ b&amp;lt;/tt&amp;gt; || bitweise exclusiv-oder (xor, exor)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;~a&amp;lt;/tt&amp;gt; || jedes Bit in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; invertieren (not, Einerkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Index-Operator bei Arrays==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a[b]&amp;lt;/tt&amp;gt; || das (b+1)ste Element des Feldes a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Folgendes gilt es bei der Verwendung des Indexoperators zu beachten:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; muss ein [[C-Tutorial#Felder | Feld]] oder [[C-Tutorial#Zeiger | Zeiger]] sein&lt;br /&gt;
# &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; muss ein Integer sein oder ein Datentyp, der sich in einen int umwandeln läßt (z.B. char)&lt;br /&gt;
# Es wird nicht geprüft, ob der Index &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; im Feld &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gültig ist!&lt;br /&gt;
# Der erste Index eines Feldes ist immer 0. Daher ''(b+1)stes Element'' in der Beschreibung&lt;br /&gt;
&lt;br /&gt;
==Komponenten-Auswahl bei Structs und Unions==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a.b&amp;lt;/tt&amp;gt; || Element b der [[C-Tutorial#Strukturen | Struktur]] oder des Unions a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adress-Operator und Dereferenzierung==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&amp;amp;amp;a&amp;lt;/tt&amp;gt; || Speicheradresse der Variablen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;*a&amp;lt;/tt&amp;gt; || Wert, der an der Adresse &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a-&amp;amp;gt;b&amp;lt;/tt&amp;gt; || Wert des Elements &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; der Struktur, deren Adresse in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Adressoperator &amp;amp; kann auf Variablen angewendet werden und&lt;br /&gt;
gibt die Startadresse der Variablen im Speicher zurück.&lt;br /&gt;
&lt;br /&gt;
Handelt es sich bei einer Variable um einen [[C-Tutorial#Zeiger | Zeiger]], so enthält&lt;br /&gt;
sie eine Speicheradresse. Um an den '''Wert''' zu gelangen, der&lt;br /&gt;
an dieser Adresse steht, wird der Operator * vorangestellt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
&lt;br /&gt;
 {{comment|x ist eine Integervariable und hat den Wert 5}}&lt;br /&gt;
 int x = 5;&lt;br /&gt;
     &lt;br /&gt;
 {{comment|z ist ein Zeiger auf eine Integer-Variable und enthaelt somit}}&lt;br /&gt;
 {{comment|die Speicheradresse einer Integer-Variablen}}&lt;br /&gt;
 int *z;       &lt;br /&gt;
  &lt;br /&gt;
 {{comment|Verwendung des Adress-Operators: weist an z die Adresse von x zu}}&lt;br /&gt;
 z = &amp;amp;x;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Verwendung der Dereferenzierung}}&lt;br /&gt;
 {{comment|erhoehe den Wert, der bei Adresse z steht, um eins}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|da z auf x zeigt, hat x jetzt den Wert 6}}&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff auf Struktir- und Union-Elemente eine abkürzende Schreibweise möglich:&lt;br /&gt;
&lt;br /&gt;
Statt &lt;br /&gt;
  (*strukturZeiger).element&lt;br /&gt;
kann geschrieben werden&lt;br /&gt;
  strukturZeiger-&amp;gt;element&lt;br /&gt;
Beide Schreibweisen sind absolut gleichbedeutend, die Klammern bei der ersteren sind notwendig.&lt;br /&gt;
&lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
:Bei der Dereferenzierung durch &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; findet keine Prüfung statt, ob der Zeiger auch auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu einer Änderung '''irgendeiner''' Speicherstelle!&lt;br /&gt;
&lt;br /&gt;
 int *z; {{comment|z ist ein Zeiger auf einen int}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.}}&lt;br /&gt;
 {{comment|z enthaelt irgendeine ungueltige Adresse!!}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|&amp;quot;Erhoehe einen Integer _irgendwo_ im Speicher um 1&amp;quot; -&amp;gt; CRASH !!!}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
&lt;br /&gt;
==Cast-Operator==&lt;br /&gt;
&lt;br /&gt;
Der Cast Operator dient dazu, den Datentyp eines Wertes zu ändern. Dafür wird einfach der neue Datentyp in Klammern vor den Wert geschrieben.&lt;br /&gt;
&lt;br /&gt;
Um zum Beispiel aus einem Float ein Integer zu machen:&lt;br /&gt;
 var  = (int) 5.60;&lt;br /&gt;
Dabei wird der Wert aber auch gerundet, und es findet somit ein Informationsverlust statt.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Umwandeln einer ganzen Zahl in eine Adresse:&lt;br /&gt;
 int * addr;&lt;br /&gt;
 addr = (int*) 0x1234;&lt;br /&gt;
Damit ist &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; an Adresse 0x1234.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
Der Cast-Operator selbst führt ''keine Konvertierung'' von Darstellungen durch, etwa die Umwandlung der ganzen Zahl 123 ein den String &amp;lt;tt&amp;gt;&amp;quot;123&amp;quot;&amp;lt;/tt&amp;gt;, der diese Zahl darstellt! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
  int main(int argc, char ** argv)&lt;br /&gt;
  {&lt;br /&gt;
        char text[] = &amp;quot;5.6&amp;quot;;&lt;br /&gt;
        int zahl = (int) text;&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, zahl);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Anfangsadresse des Strings &amp;lt;tt&amp;gt;&amp;quot;5.6&amp;quot;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Komma-Operator==&lt;br /&gt;
Mit einem &amp;lt;tt&amp;gt;,&amp;lt;/tt&amp;gt; können mehrere Ausdrücke nacheinander ausgewertet werden.&lt;br /&gt;
Die Auswertung erfolgt von links nach rechts.&lt;br /&gt;
&lt;br /&gt;
Solche Konstrukte sieht man manchmal in Abfragen wie&lt;br /&gt;
 FILE  *file;&lt;br /&gt;
 if (file = fopen (&amp;quot;foo.exe&amp;quot;, &amp;quot;r&amp;quot;), file != NULL)&lt;br /&gt;
was erst an &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; einen Wert zuweist und den &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Block nur betritt,&lt;br /&gt;
wenn &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; nicht der Nullpointer ist.&lt;br /&gt;
&lt;br /&gt;
Bequem kann das auch in einer [[#for-Schleife|for-Schleife]] sein, wenn man zwei (oder mehr) Laufvariablen hat oder so:&lt;br /&gt;
 for (i=0, j=0; i &amp;lt; 10; i++, j += 2)&lt;br /&gt;
    &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Zuweisung===&lt;br /&gt;
=== ++ und -- ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; stellen einfachere Schreibweisen dar zum Addieren bzw. Subtrahieren von&amp;amp;nbsp;1.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; (Inkrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo++; &lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo + 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; 3}}&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; (Dekrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo--;&lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo - 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; -1}}&lt;br /&gt;
&lt;br /&gt;
Die beiden Operatoren können sowohl in der Präfix-Schreibweise (vor der Variablen) als auch als Postfix-Schreibweise (hinter der Variablen) notiert werden. &lt;br /&gt;
Der Unterschied liegt darin, dass beim Präfix der Wert zuerst neu berechnet wird und die Variable dann verwendet wird. Beim Postfix wird die Variable zuerst verwendet und erst nach Auswertung des Ausdrucks, in dem sie enthalten ist, neu berechnet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 int ausgabe1, ausgabe2, var1 = 10, var2 = 10;&lt;br /&gt;
 ausgabe1 = 3 * ++var1; {{comment|ausgabe1 &amp;amp;#61; 33; var1 &amp;amp;#61; 11;}}&lt;br /&gt;
 ausgabe2 = 3 * var2++; {{comment|ausgabe2 &amp;amp;#61; 30; var2 &amp;amp;#61; 11;}}&lt;br /&gt;
&lt;br /&gt;
Für Zeiger arbeiten diese Operatoren etwas anders, siehe dazu [[#Zeiger-Arithmetik|Zeiger-Arithmetik]].&lt;br /&gt;
&lt;br /&gt;
===Bedingter Ausdruck===&lt;br /&gt;
 ({{Bedingung}}) ? {{Ausdruck|1}} : {{Ausdruck|2}}&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; erfüllt ist, dann wertet dieser Ausdruck aus zu &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt;. Ist er nicht erfüllt, dann wertet er aus zu &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 x = (x &amp;gt;= 3) ? 0 : x+1;&lt;br /&gt;
Startet man &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; mit dem Wert 0, dann nimmt es bei mehrfacher Anwendung dieser Zeile (z.B. in einer Schleife) nacheinander die folgende Werte an:&lt;br /&gt;
:&amp;lt;tt&amp;gt;1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, ...&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
Eine Kontrollanweisung ist eine Anweisung, die Einfluss auf den Programmfluss hat. Normalerweise werden Anweisungen so ausgeführt, wie sie in der Quelldatei stehen: Von links nach rechts (falls mehrere Anweisungen in einer Zeile stehen sollten, wovon i.A. abzuraten ist) und von oben nach unten. Mit einer Kontrollanweisung kann dieser lineare Programmfluss durchbrochen werden: Die Codeausführung kann kann abhängig von einer Bedingung gemacht werden (&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;), kann wiederholt werden (Schleife) oder an einer anderen Stelle der Funktion fortgesetzt werden (&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==if-Anweisung==&lt;br /&gt;
Mit Hilfe des if-Befehls kann man Codeteile abhängig davon einer Bedingung ausführen lassen:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
oder mit else-Teil&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 if (x &amp;gt; 100)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;gt; 100 ist: Fehlerausgabe}}&lt;br /&gt;
    printf (&amp;quot;x = %d ist zu gross fuer die Berechnung!\n&amp;quot;, x);&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;lt;&amp;amp;#61; 100 ist: Berechne Summe der Zahlen 1...x}}&lt;br /&gt;
    {{comment|Die lokale Variable x2 lebt nur innerhalb dieses alse-Blocks}}&lt;br /&gt;
    int x2 = x;&lt;br /&gt;
 &lt;br /&gt;
    for (x = 0; x2 &amp;gt; 0; x2--)&lt;br /&gt;
       x += x2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Wenn die Bedingung wahr ist (&amp;lt;tt&amp;gt;x &amp;gt; 100&amp;lt;/tt&amp;gt;), dann wird eine Meldung ausgegeben; danach ist die if-Anweisung beendet. Der else-Block wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung nicht erfüllt (&amp;lt;tt&amp;gt;x &amp;amp;le; 100&amp;lt;/tt&amp;gt;), dann wird gleich zum else-Teil gesprungen, und nach dessen Ausführung der if-Befehl beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Ein häufiger Fehler ist es, statt &amp;lt;tt&amp;gt;if (a &amp;amp;#61;&amp;amp;#61; 23)&amp;lt;/tt&amp;gt; etwas wie &amp;lt;tt&amp;gt;if (a &amp;amp;#61; 23)&amp;lt;/tt&amp;gt; zu schreiben. &lt;br /&gt;
Dann wird allerdings nicht geprüft, ob die Variable&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gleich 23 ist, sondern der Variablen&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wird der Wert 23 zugewiesen. Der Ausdruck &amp;lt;tt&amp;gt;a &amp;amp;#61; 23&amp;lt;/tt&amp;gt; hat den Wert&amp;amp;nbsp;23 und ist damit immer &amp;quot;wahr&amp;quot;! Daher ist diese if-Bedingung immer erfüllt!&lt;br /&gt;
&lt;br /&gt;
Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken sondern bestenfalls eine Warnung. Damit ist dieser Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise &amp;lt;tt&amp;gt;if (23 &amp;amp;#61;&amp;amp;#61; a)&amp;lt;/tt&amp;gt;. Wenn man dort anstatt des Vergleichsoperators '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;amp;#61;&amp;lt;/tt&amp;gt;' den Zuweisungsoperator '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;lt;/tt&amp;gt;' verwendet, spuckt der Compiler sehr wohl einen Fehler aus! Ist die Zuweisung jedoch erwünscht und eine Compiler-Warnung lästig, dann wählt man eine Schreibweise wie &amp;lt;tt&amp;gt;if ((a &amp;amp;#61; b))&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;if (a &amp;amp;#61; b, a)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist zu schreiben &amp;lt;tt&amp;gt;if (Bedingung);&amp;lt;/tt&amp;gt; Richtig muss es heissen &amp;quot;&amp;lt;tt&amp;gt;if(Bedingung)&amp;lt;/tt&amp;gt;&amp;quot; Das Semikolon im ersten Fall ist eine leere Anweisung, die im if-Falle ausgeführt wird &amp;amp;ndash; sie bleibt also ohne Resultet. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt; ein auf das Semikolon folgende Anweisung die eigentlich zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören soll wird immer ausgeführt, die sie nicht mehr zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; dazu gehört.&lt;br /&gt;
}}&lt;br /&gt;
Bei verschachtelten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Konstrukten gehört ein &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zu letzten &amp;quot;freien&amp;quot; &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;. Soll in einer &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Folge das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zum ersten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören, dann ist das so zu hinzuschreiben:&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Ohne die geschweiften Klammern um das zweite &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehörte das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; dort hinzu.&lt;br /&gt;
&lt;br /&gt;
==switch-Anweisung==&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
&lt;br /&gt;
 switch ({{Ausdruck|}}) &lt;br /&gt;
 {&lt;br /&gt;
     case konstante1:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
    &lt;br /&gt;
     case konstante2:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 &lt;br /&gt;
     {{comment|weitere case-Marken}}&lt;br /&gt;
 &lt;br /&gt;
     default:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 } {{comment|Ende von switch}} &lt;br /&gt;
&lt;br /&gt;
Der Ausdruck muss ein skalarer Typ sein, er wird in die nächste ganze Zahl gewandelt und mit den Werten hinter den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Marken verglichen. Bei einer Übereinstimmung werden alle Befehle ab dem zutreffenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; ausgeführt. Stimmt der Ausdruck mit keinem der Werte überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt falls vorhanden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der nachfolgenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;- und des &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitts werden ausgeführt, wenn die Anweisungen des &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitts nicht mit dem Befehl &amp;lt;tt&amp;gt;break;&amp;lt;/tt&amp;gt; beendet werden!&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es dürfen beliebig viele &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitte angegeben werden, pro Vergleichswert jedoch nur einer.&lt;br /&gt;
Der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ist optional. Die Reihenfolge, in der &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt; angegeben werden, ist unerheblich.&lt;br /&gt;
&lt;br /&gt;
==Schleifen==&lt;br /&gt;
Um Anweisungen mehrmals hintereinander auszuführen, benötigt man Schleifen. Diese führen Anweisungen aus, bis oder solange Bedingungen erfüllt sind.&amp;lt;br&amp;gt; &lt;br /&gt;
Wichtig ist also, ob die Bedingung '''vor''' oder '''nach''' den Schleifen-Anweisungen geprüft wird. &lt;br /&gt;
&lt;br /&gt;
===while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 while ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Die while-Schleife wird solange durchlaufen, wie die Bedingung erfüllt ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Die Anweisung kann natürlich auch ein Block sein, der aus mehreren Deklarationen und Anweisungen besteht. &lt;br /&gt;
&lt;br /&gt;
 int zahl1 = 0;&lt;br /&gt;
 int zahl2 = 1;&lt;br /&gt;
 &lt;br /&gt;
 while (zahl1 &amp;lt; 3)&lt;br /&gt;
 {&lt;br /&gt;
    zahl1 = zahl1 + 1;&lt;br /&gt;
    zahl2 = zahl2 * 2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife drei mal durchlaufen. Zu Beginn des vierten Durchlaufs ist die Bedingung nicht mehr erfüllt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
&lt;br /&gt;
===do-while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
Die do-while-Schleife wird auf jeden Fall einmal durchlaufen und dann solange wiederholt, wie die Bedingung erfüllt ist.&lt;br /&gt;
 int i = 2;&lt;br /&gt;
 &lt;br /&gt;
 do &lt;br /&gt;
 {&lt;br /&gt;
     i = i*i;   {{comment|i quadrieren}}&lt;br /&gt;
     printf (&amp;quot;i = %d\n&amp;quot;, i);&lt;br /&gt;
 }&lt;br /&gt;
 while (i &amp;lt; 20);&lt;br /&gt;
&lt;br /&gt;
Die Schleife wird durchlaufen und wiederholt, solange &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; kleiner als 20 ist. Es werden also nacheinander die Werte 2, 4 und 16 ausgegeben. Nach der Schleife hat&amp;amp;nbsp;&amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; den Wert 256.&lt;br /&gt;
&lt;br /&gt;
===for-Schleife===&lt;br /&gt;
'''Syntax:''' &lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Bei den Ausdrücken wird es sich um einen Ausdrücke mit Nebeneffekt handeln wie etwa &amp;lt;tt&amp;gt;i=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;i=i+2&amp;lt;/tt&amp;gt;. Es werden folgende Aktionen ausgeführt:&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# falls die Bedingung wahr ist, dann führe &amp;lt;tt&amp;gt;Anweisung&amp;lt;/tt&amp;gt; aus.&lt;br /&gt;
# falls die Bedingung unwahr ist, dann sprinte zu 7 (Ende).&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# gehe zu 2&lt;br /&gt;
# nächste Anweisung nach der for-Schleife&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int lauf, summe;&lt;br /&gt;
 &lt;br /&gt;
 for (lauf=1, summe=0; lauf &amp;lt;= 10; lauf += 2) &lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel ist &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; ein [[#Komma-Operator|Komma-Ausdruck]], der zwei Anweisungen kombiniert und daher sogar zwei Nebeneffente hat: er setzt &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;1 und &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;0.&lt;br /&gt;
&lt;br /&gt;
Das Äquivalent als while-Schleife:&lt;br /&gt;
&lt;br /&gt;
 int lauf  = 1;                 {{comment|Anfangswerte}}&lt;br /&gt;
 int summe = 0;&lt;br /&gt;
 &lt;br /&gt;
 while (lauf &amp;lt;= 10)             {{comment|Bedingung}}&lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
    lauf  += 2;                 {{comment|Inkrement}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; in jedem Schleifendurchlauf um die Laufvariable &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; erhöht. Da &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nacheinander die ungeraden Werte von&amp;amp;nbsp;1 bis&amp;amp;nbsp;10 annimmt, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von&amp;amp;nbsp;1 bis kleinergleich 10 gespeichert, also der Wert&amp;amp;nbsp;25. &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; hat nach der Schleife den Wert&amp;amp;nbsp;11.&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf = 1&amp;lt;/tt&amp;gt; bedeutet, dass der Variablen &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; vor dem ersten Schleifendurchlauf der Wert&amp;amp;nbsp;1 zugewiesen wird. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf &amp;lt;= 10&amp;lt;/tt&amp;gt; ist die Schleifenbedingung; ist sie nicht erfüllt, wird die Schleife beendet. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf += 2&amp;lt;/tt&amp;gt; bedeutet, dass &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nach jedem Durchlauf um&amp;amp;nbsp;2 erhöht wird.&lt;br /&gt;
&lt;br /&gt;
===continue-Anweisung===&lt;br /&gt;
Innerhalb einer Schleife darf die &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die nachfolgenden Anweisungen übersprungen werden und mit dem nächsten Schleifendurchlauf fortgesetzt wird &amp;amp;ndash; vorausgesetzt die Schleifenbedingung ist noch erfüllt. Ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; etc. stehen, wenn dieses innerhalb einer Schleife steht.&lt;br /&gt;
&lt;br /&gt;
==break-Anweisung==&lt;br /&gt;
Innerhalb einer Schleife oder eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; darf die &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die Schleifen-/Switch-Anweisung sofort verlassen wird und das Programm dahinter weiter macht. Bei mehrfach geschachtelten Schleifen wird nur die innere verlassen. Ein &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; stehen, wenn dieses innerhalb einer Schleife/Switch-Anweisung steht.&lt;br /&gt;
&lt;br /&gt;
==goto-Anweisung==&lt;br /&gt;
&lt;br /&gt;
Innerhalb ein und derselben Funktion kann mit &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; an eine andere Stelle gesprungen werden. Dazu gibt man hinter dem &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einen Bezeichner an, der dadurch als Label fungiert:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 goto {{Bezeichner}};&lt;br /&gt;
Die Bezeichner selbst steht irgendwo in der Funktion und wird dadurch zur Sprungmarke (Label), daß er von einem Doppelpunkt (und mindestens einer C-Anweisung, die auch leer sein darf) gefolgt wird.&lt;br /&gt;
&lt;br /&gt;
Das Beispiel durchsucht das 2-dimensionale &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array &amp;lt;tt&amp;gt;feld&amp;lt;/tt&amp;gt; mit den &amp;lt;tt&amp;gt;SIZE_X &amp;amp;times; SIZE_Y&amp;lt;/tt&amp;gt; Werten nach dem Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;. Wird er gefunden, dann wird die 2-fach geschachtelte Suchschleife verlassen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int x, y;&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y; y++)&lt;br /&gt;
       if (feld[x][y] == 0)&lt;br /&gt;
          goto done;&lt;br /&gt;
 {{Label|done:}};&lt;br /&gt;
&lt;br /&gt;
Der folgende Code hat die gleiche Funktion, arbeitet jedoch ohne &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int x, y;&lt;br /&gt;
 int found = 0; {{comment|FALSE}}&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X &amp;amp;&amp;amp; !found; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y &amp;amp;&amp;amp; !found; y++)&lt;br /&gt;
       found = (0 == feld[x][y]);&lt;br /&gt;
Der Nachteil der &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-losen Variante ist, daß man eine Variable, die merkt, ob das Suchziel gefunden wurde, mitschleppen und in ''jedem'' Schleifendurchlauf abtesten muss. Dies bedeutet einen höheren Programmier- und Laufzeitaufwand und ist nicht so klar formuliert wie das &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-Beispiel.&lt;br /&gt;
&lt;br /&gt;
Gleichwohl sei angemerkt, daß die Verwendung von &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einem gewissen Dogmatismus unterliegt, der sich wie folgt subsummieren liesse:&lt;br /&gt;
:''goto ist böse und sollte keinesfalls verwendet werden! Wer es dennoch tut, offenbart dadurch seinen schlechten Geschmach sowie mangelhafte C-Kenntnis.'' &amp;lt;div align=&amp;quot;right&amp;quot;&amp;gt;http://www.roboternetz.de/phpBB2/images/smiles/icon_wink.gif&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Funktionen=&lt;br /&gt;
Stellen Dir vor, Du hast eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben &amp;amp;ndash; was Dich Zeit beim Erstellen des Programms und Speicherplatz im ausführbaren Programm kostet &amp;amp;ndash; kannst Du den Code-Abschnitt in eine Funktion schreiben und diese von jeder Stelle des Programms aus verwenden. Die Hauptgründe, um Funktionen zu verwenden, sind:&lt;br /&gt;
;Wiederverwendung von Code: Mehrfach verwendete Codestücke müssen nicht mehrfach implementiert werden. Oft unterscheiden sich die Codesequenzen nur in Kleinigkeiten, die man der Funktion über Parameter mitteilen kann.&lt;br /&gt;
;Übersichtlichkeit: Ein gut gegliedertes C-Programm implementiert klar umrissene Aufgaben in einer Funktion, auch wenn diese Funktion nur einmal im Code aufgerufen wird! Dadurch bleibt der Code um die Aufrufstelle besser verständlich, und man kann auf verschiedenen &amp;quot;Ebenen&amp;quot; denken. Eine Funktion wie &amp;quot;Datei öffnen&amp;quot; kann recht komplex sein. Auf höherer Ebene interessieren die Innereien nicht mehr, man möchte sich um andere Dinge kümmern und will den Code an der Stelle garnicht sehen...&lt;br /&gt;
;Rekursive Funktionen: Eine Funktion kann sich auch selbst aufrufen. In dem Falle nennt man die Funktion ''rekursiv''. Zwar lässt sich das, was eine rekursive Funktion tut, auch mit anderen Mitteln formulieren, die keine rekursiven Funktionen brauchen, aber oft ist der rekursive Weg knackiger und klarer formulierbar als eine nicht-rekursiven Ansatz, auch wenn es etwas mehr Resourcen verbraucht.&lt;br /&gt;
;Modulare Programmierung: Funktionen können anhand ihres Aufgabenbereichs auf verschiedene C-Quellen &amp;amp;ndash; sogenannte ''Module'' &amp;amp;ndash; verteilt werden. Funktionen, die etwas mit dem USB-Bus anstellen, werden in einem anderen Modul sein als mathematische Funktionen. Dies erhöht die Übersichtlichkeit und vereinfacht die Entwicklung im Team.&lt;br /&gt;
;Bibliotheken: Standard-Funktionen wie das hier oft auftauchende &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; sind in Bibliotheken gespeichert. Wenn das eigene Programm übersetzt wird, dann müssen nicht mehr alle Standard-Funktionen übersetzt werden, sondern werden nur noch aus der Bibliothek gelesen und ihr Code zum Programm dazugelinkt. Die Bibliotheks-Funktionen wurden schon zu einem früheren Zeitpunkt compiliert und liegen in dieser compilerten Form in der Bibliothek. Das spart mächtig Entwicklungszeit. Man kann auch selbst solche Bibliotheken erstellen und in diversen Projekten wiederverwenden.&lt;br /&gt;
;Generische Programmierung: In C ist es möglich, einer Funktion eine andere Funktion zu übergeben. (Damit ist nicht gemeint, ihr deren ''Rückgabewert'' zu übergeben (was auch ginge), sondern ''die Funktion selbst'' wird als Parameter übergeben und kann aufgerufen werden.) Ein typisches Beispiel dafür sind Sortieralgorithmen. Einem Sortieralgorithmus kann es egal sein, ''was'' er sortiert. Er muss lediglich wissen, ''wie'' er das Zeug zu sortieren hat: aufsteigend, absteigend, als Zahl, in lexikographischer Ordnung, nach der Quersumme, Körper nach Oberfläche, Durchmesser, Gewicht oder Volumen... Diese Vergleichsfunktion, die für zwei Objekte entscheidet, welches davon &amp;quot;kleiner&amp;quot; ist, kann man dem Sortierer übergeben. Will er zwei Werte vergleichen, dann muss er nur die Vergleichsfunktion aufrufen, ohne zu wissen, was diese tut. Damit kann der Sortieralgorithmus unanhängig von den Objekten gehalten werden, mit denen er hantieren soll.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Definition==&lt;br /&gt;
&lt;br /&gt;
In der ''Definition'' der Funktion wird gesagt, welche Werte sie liefern kann, wie sie heisst (Bezeichner) und wieviele und welche Parameter sie hat. Danach folgt ihre Implementierung:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}} ({{Parameterliste}})&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 &lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
Für Funktionen, die keinen Wert zurückliefern, gibt es den speziellen Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der besagt, daß die Funktion nichts zurückgibt. Die einfachste denkbare Funktion ist eine solch void-Funktion. Sie bekommt keine Parameter, gibt nicht zurück und ihr Body ist leer:&lt;br /&gt;
 void dummy()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==return-Anweisung==&lt;br /&gt;
An jeder Stelle des Programmflusses einer Funktion kann diese mit &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; beendet werden.&lt;br /&gt;
&lt;br /&gt;
'''bei void-Funktionen:'''&lt;br /&gt;
 return;&lt;br /&gt;
'''Funktionen mit Rückgabe-Wert:'''&lt;br /&gt;
 return {{Ausdruck|}};&lt;br /&gt;
Die zweite Variante gibt an, welcher Wert zurückgegeben wird.&lt;br /&gt;
 int main (int argc, char * argv[])&lt;br /&gt;
 {&lt;br /&gt;
    if (argc &amp;lt; 2)&lt;br /&gt;
       return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
Falls die letzte Anweisung einer void-Funktion ein &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; ist, kann es auch weggelassen werden wie oben bei der Funktion &amp;lt;tt&amp;gt;dummy&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Aufruf==&lt;br /&gt;
Um die Funktion aufzurufen gibt man ihren Namen an, gefolgt von den durch Komma getrennten Argumenten in runden Klammern wie im Beispiel unten das&lt;br /&gt;
 quadrat (5) &lt;br /&gt;
Da &amp;lt;tt&amp;gt;quadrat&amp;lt;/tt&amp;gt; einen Wert liefert, kann man damit weiter rechnen wie mit einem normalen Ausdruck:&lt;br /&gt;
 if (quadrat (a) + quadrat (b) == quadrat (c))&lt;br /&gt;
    c = quadrat (quadrat (a)); {{comment|c &amp;amp;#61; a hoch 4}}&lt;br /&gt;
&lt;br /&gt;
==Rekursive Funktionen==&lt;br /&gt;
Eine Funktion die sich selbst &amp;amp;ndash; möglicheweise auch über andere Zwischenfunktionen &amp;amp;ndash; wieder selbst aufruft, wird als ''rekursive Funktion'' bezeichnet. In der Definition ist nichts besonderes zu beachten. Ist die Verschachtelungstiefe im laufenden Programm zu tief, dann gibt das natürlich Probleme, aber das gilt bei tief verschachtelten 'normalen' Funktionen abenso...&lt;br /&gt;
&lt;br /&gt;
Das Beispiel berechnet den Größten Gemeinsamen Teiler zweier Zahlen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int ggT (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
     if (0 == a)&lt;br /&gt;
        return b;&lt;br /&gt;
 &lt;br /&gt;
    return ggT (b % a, a);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Ein komplettes kleines Programm:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int quadrat (int param1)&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  zahl = param1 * param1;&lt;br /&gt;
  return zahl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl, ergebnis;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Bitte Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = quadrat (zahl);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, zahl, ergebnis);&lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, 5, quadrat (5));&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur ausserhalb von Blöcken. Geschachtelte Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen beim Aufruf die Klammern angeben werden:&lt;br /&gt;
 dummy();&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Prototypen==&lt;br /&gt;
Wie oben erwähnt, kann ein Unterprogramm an jeder beliebigen Stelle im Programm stehen. Damit ist jedoch eine Bedingung verknüpft: Das Unterprogramm muß in der Datei oberhalb des ersten Aufrufes definiert worden sein. Wenn Sie ein Unterprogramm in Zeile 10 zum ersten mal aufrufen, müssen Sie die Deklaration davor erledigt haben. Verstanden?&lt;br /&gt;
Um dies zu erreichen, gibt es zwei Möglichkeiten: &lt;br /&gt;
&lt;br /&gt;
Entweder Sie schreiben alle Unterprogramme vor &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; in die Datei. Dies muß jedoch wiederum so geschehen, dass Funktionen zum Zeitpunkt ihres Aufrufes bereits bekannt sind! &lt;br /&gt;
Wo dies nicht möglich ist (z.B. sich gegenseitig aufrufende Unterprogramme), oder wenn Sie das stört, müssen Sie Prototypen verwenden. &lt;br /&gt;
Wie definiert man nun Prototypen? Sie kopieren einfach die erste Zeile des Unterprogrammes (z.B. &amp;quot;&amp;lt;tt&amp;gt;void ausgeben (int zahl)&amp;lt;/tt&amp;gt;&amp;quot;), fügen einen Strichpunkt&amp;amp;nbsp;&amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;an und fügen es an einer geeigneten Stelle ein (so, dass alle Aufrufe später in der Datei kommen). &lt;br /&gt;
Solche Definitionen stehen gewöhnlich am Anfang der Quelldatei oder in einer Header-Datei, die eingebunden wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl);  /* Der Prototyp */&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
   ausgeben (12);&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl)   /* Die eigentliche Prozedur */&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Ausgabe: %d\n&amp;quot;, zahl);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Parameterübergabe==&lt;br /&gt;
&lt;br /&gt;
Alle Werte, die an Prozeduren und Funktionen übergeben werden, werden grundsätzlich '''kopiert'''.&lt;br /&gt;
Das hat folgende Auswirkungen:&lt;br /&gt;
&lt;br /&gt;
# Änderungen an einem Parameter in einer Funktion erscheinen ''nicht'' beim Aufrufer!&lt;br /&gt;
# Möchte man, dass eine Funktion einen Wert trotzdem dauerhaft ändern soll, so muss die Adresse des Wertes via [[#Zeiger|Zeiger]] übergeben werden.&lt;br /&gt;
# Werden [[#Strukturen|Strukturen]] übergeben, so wird von ihnen eine Kopie erstellt, was bei großen Strukturen viel Zeit und Arbeitsspeicher kostet. Deshalb wird häufig nur die Adresse von Strukturen übergeben, da die Adresse viel schneller und platzsparender als die Struktur selbst kopiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele:'''&lt;br /&gt;
 void erhoehe (int x)&lt;br /&gt;
 {&lt;br /&gt;
    x = x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe(a);&lt;br /&gt;
    {{comment|a ist immer noch 0}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Beim Aufruf von &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; wird eine Kopie des Wertes von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; (im Beispiel also 0) erstellt und der Prozedur als Parameter &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; übergeben. Weil dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat dies keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|erhoehe den Wert an der Adresse x um eins}}&lt;br /&gt;
    *x = *x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe (&amp;amp;a);&lt;br /&gt;
    {{comment|a ist jetzt 1}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Jetzt wird im Hauptprogramm mittels [[#Adress-Operator und Dereferenzierung|Adress-Operator]] &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; die Speicheradresse von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; bestimmt. Dann wird eine ''Kopie der Adresse'' an das Unterprogramm &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; übergeben. Jetzt kennt das Unterprogramm die&lt;br /&gt;
Adresse des Originals &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und kann direkt mit dem Inhalts-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&lt;br /&gt;
'''Besonderheit bei Feldern'''&lt;br /&gt;
&lt;br /&gt;
Bei der Übergabe von [[#Felder|Feldern]] gibt es eine Besonderheit. Schreibt man nämlich den Namen eines Feldes, so ist das nichts anderes als die '''Speicheradresse des ersten Elements'''.&lt;br /&gt;
Bei der Übergabe eines Feldes wird also eine Kopie der Startadresse übergeben. Somit kann das Unterprogramm auf den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 void erhoehe (int x[])&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
   int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
   erhoehe (a);&lt;br /&gt;
   {{comment|a hat jetzt folgenden Inhalte: 11, 23, 35}}&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Dass die Übergabe einer Adresse erfolgt, sieht man an folgendem Beispiel, das von der Funktionsweise '''absolut identisch''' mit dem vorhergehenden ist:&lt;br /&gt;
&lt;br /&gt;
 {{comment|Bei Parametern gibt es keinen Unterschied zwischen Zeiger und Feld}}&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
    int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
    erhoehe (a);&lt;br /&gt;
 &lt;br /&gt;
    {{comment|a hat jetzt folgenden Inhalt: 11, 23, 35}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
Die Länge des Feldes wird nicht automatisch übergeben. Dafür ist ggf. ein zusätzlicher Parameter notwendig.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Variable Argumentanzahl==&lt;br /&gt;
== Funktionen indirekt aufrufen ==&lt;br /&gt;
Siehe [[#Zeiger auf Funktionen|Zeiger auf Funktionen]]&lt;br /&gt;
&lt;br /&gt;
=Zeiger II=&lt;br /&gt;
&lt;br /&gt;
Zeiger haben wir bereits weiter oben kennen gelernt. Zeiger sind ein zentrales Konzept in C und sollen hier etwas eingehender behandelt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger-Arithmetik==&lt;br /&gt;
In C kann man den Wert eines Zeigers verändern. Betrachten wir dazu die Funktion &amp;lt;tt&amp;gt;suche_0&amp;lt;/tt&amp;gt;, die einen Zeiger auf einen &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; erhält. Die Funktion soll ab der gegebenen Adresse nach dem ersten long-Wert suchen, der 0 ist, und dessen Adresse zurückgeben:&lt;br /&gt;
 long * suche_0 (long * addr)&lt;br /&gt;
 {&lt;br /&gt;
    while (*addr != 0)&lt;br /&gt;
       addr = addr + 1;&lt;br /&gt;
 &lt;br /&gt;
    return addr;&lt;br /&gt;
 }&lt;br /&gt;
In der Bedingung der while-Schleife wird der Inhalt an der Speicherstelle &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf 0 getestet. Ist der Wert 0, dann wird die Schleife beendet und die Adresse zurückgeliefert. Ist der Wert ungleich 0, dann wird &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf den nächste long gesetzt, &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; also um 4 Bytes weitergezählt. &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ist ja ein Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, und ein &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; ist 4 Bytes lang.&lt;br /&gt;
&lt;br /&gt;
Die Bedeutung von&lt;br /&gt;
 address + n&lt;br /&gt;
ist also, die Adresse um das &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;-fache der Größe des Typs, auf den &amp;lt;tt&amp;gt;address&amp;lt;/tt&amp;gt; zeigt, zu erhöhen. Dabei ist &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; eine ganze Zahl und darf auch negativ sein.&lt;br /&gt;
&lt;br /&gt;
Hier noch ein Beispiel einer Funktion, die nach einer Person mit einer bestimmten ID sucht (für die Definition von &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; siehe [[#Strukturen|Strukturen]]). Der Parameter &amp;lt;tt&amp;gt;person&amp;lt;/tt&amp;gt; ist dabei ein Array von Strukturen. Eine Person mit der gesuchten ID muss existieren, ansonsten hat die Suchfunktion kein definiertes Verhalten.&lt;br /&gt;
 {{comment|Sucht nach einer Person mit der ID person_id}}&lt;br /&gt;
 struct Person * &lt;br /&gt;
 suche_person_id (struct Person * person, int person_id)&lt;br /&gt;
 {&lt;br /&gt;
    while (person-&amp;gt;id != person_id)&lt;br /&gt;
       person++;&lt;br /&gt;
 &lt;br /&gt;
    return person;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:1em; padding:1em; border:solid 2px #FF0040;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- Vorlage:FarbigerRahmen funzt hier net --&amp;gt;&lt;br /&gt;
Beachte, daß es nicht sinnvoll ist, zwei Zeiger zu addieren oder zu multiplizieren. Ausserdem ist das &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt; der Zeiger-Arithmetik nicht kommutativ. Eine Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, der an Adresse 1 im Speicher zeigt, wird man schreiben als&lt;br /&gt;
 (long *) 1&lt;br /&gt;
Addiert man darauf eine ganze Zahl, dann haben die entstehenden Ausdrücke unterschiedliche Werte:&lt;br /&gt;
 (long *) 1 + 2    {{comment|zeigt zu Adresse 9}}&lt;br /&gt;
 (long *) 2 + 1    {{comment|zeigt zu Adresse 6}}&lt;br /&gt;
 (long *) (1 + 2)  {{comment|zeigt zu Adresse 3}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==void-Pointer==&lt;br /&gt;
Eine besondere Art von Zeiger ist der void-Pointer&lt;br /&gt;
 void * addr;&lt;br /&gt;
Ein void-Pointer ist ein &amp;quot;Zeiger auf irgendwas&amp;quot;, dementsprechend kann er nicht dereferenziert werden, Anwenden von &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf einen solchen Zeiger gibt also einen Fehler. Ausserdem ist es nicht möglich, mit einem void-Pointer Zeigerarithmetik zu machen, weil er nicht auf eine definierte Art von Objekt zeigt. Der Vorteil eines void-Pointers ist, daß er jede Art von Zeiger aufnehmen kann.&lt;br /&gt;
&lt;br /&gt;
Dazu betrachten wir die Funktion &amp;lt;tt&amp;gt;send_buf&amp;lt;/tt&amp;gt;, die eine Adresse erhält und ab dieser Adresse &amp;lt;tt&amp;gt;num&amp;lt;/tt&amp;gt; Bytes versenden soll. Wir könnten die Funktion so schreiben:&lt;br /&gt;
 void send_buf (unsigned char * buf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   ...&lt;br /&gt;
Das ist jedoch hässlich, wenn wir damit etwas anderes verschicken wollen als &amp;lt;tt&amp;gt; unsigned char&amp;lt;/tt&amp;gt;, etwa eine Struktur wie &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; (vom Typ &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;):&lt;br /&gt;
 send_buf ((unsigned char*) &amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
Ohne den Cast der Adresse von &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; zu einem Zeiger auf &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt; bekommt man eine Warnung oder gar einen Compilerfehler.&lt;br /&gt;
Dieses Zeiger gecaste ist mühsam und hässlich, es muss bei jedem Aufruf der Funktion explizit hingeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Besser ist es, den ersten Parameter der Funktion als void-Pointer zu definieren und den Cast in der Funktion zu machen:&lt;br /&gt;
 void send_buf (void * vbuf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   unsigned char *buf = (unsigned char*) vbuf;&lt;br /&gt;
   ...&lt;br /&gt;
Durch den Cast in der Funktion kann auf den Inhalt des Zeigers zugegriffen werden. Man muss nur festlegen, ''wie'' man zugreifen will, nämlich als &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Der Aufruf kann jetzt ohne Pointer-Cast erfolgen: &lt;br /&gt;
 send_buf (&amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
&lt;br /&gt;
==Null-Pointer==&lt;br /&gt;
==Zeiger als Parameter==&lt;br /&gt;
Wenn Sie ein Unterprogramm aufrufen, können Sie diesem Parameter übergeben, aber keine Werte zurückgekommen (außer den Funktionswert bei Funktionen). Dies hat einen guten Grund: beim Aufruf werden nicht die aufgerufenen Parameter benutzt, sondern es werden deren Werte in neue Variablen kopiert. Diese Variablen werden am Ende des Unterprogrammes &amp;quot;zerstört&amp;quot;, ohne ihre Werte an die aufrufenden Parameter zu übergeben. Jede Veränderung eines Parameters hat daher keine Auswirkung auf den Parameter.&lt;br /&gt;
&lt;br /&gt;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der C-Compiler legt dann immer noch Kopien an. In dieser Kopie steht aber kein Wert, sondern die Adresse einer Varaiblen. Und auf diese können Sie dann zugreifen. Denken Sie nur an &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; &amp;amp;ndash; da übergeben Sie ja auch die Adresse einer Variablen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void erhoehe (int *zeiger)&lt;br /&gt;
{&lt;br /&gt;
  *zeiger = 1 + *zeiger;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  erhoehe (&amp;amp;zahl);&lt;br /&gt;
  printf (&amp;quot;\nDie erhoehte Zahl lautet: %d\n&amp;quot;, zahl);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Zeiger auf Funktionen==&lt;br /&gt;
&lt;br /&gt;
Stell dir vor, du willst einen Sortieralgorithmus wie Bubble-Sort oder Quick-Sort oder wie sie alle heissen implementieren. Für den Sortieralgorithmus ist eigentlich egal, ''was'' er zu sortieren hat. Ihm ist es egal, ob er Zahlen aufwärts sortieren soll oder Strings in lexikographischer Reihenfolge, ob Objekte nach Größe oder Gewicht, Personen nach Alter oder Adressen nach Postleitzahl. Das einzige, was der Algorithmus wissen muss, ist ''wie'' er zwei Objekte zu vergleichen hat und wann eines davon &amp;quot;kleiner&amp;quot; (im Sinne der Ordnung, nach der sortiert werden soll) ist. &lt;br /&gt;
&lt;br /&gt;
Eine einfache Sortierfunktion, die nur zwei Zahlen sortiert, könnte man also so schreiben: &lt;br /&gt;
 {{comment|Sortiert ein Array von 2 int-Zeigern nach den Inhalten &lt;br /&gt;
  * an den Zeiger-Adressen}}&lt;br /&gt;
 void sort2_a (int * p[])&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Inhalte vergleichen...}}&lt;br /&gt;
    if (*p[0] &amp;gt; *p[1])&lt;br /&gt;
    {&lt;br /&gt;
       {{comment|... und ggf. Dreieckstausch der 2 Zeiger}}&lt;br /&gt;
       int * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Die Funktion bekommt ein Array der Länge&amp;amp;nbsp;2. In diesem Array stehen Zeiger auf die zu sortierenden Zahlen. Ein Array mit Zeigern zu verwenden und nicht ein Array von &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; scheint recht umständlich, und das ist es hier auch. Aber stell dir vor, du willst Strukturen wie &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; sortieren. Das Tauschen zweier Strukturen würde bedeuten, ihre kompletten Inhalte umzukopieren! Das wäre sehr aufwändig. Viel einfacher ist das Kopieren, wenn nur die Adressen zu kopieren sind.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; könnte dann so aussehen:&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void sortiere (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|p[] enthält 2 int-Zeiger: die Adressen von a und b}}&lt;br /&gt;
    int * p[2];&lt;br /&gt;
    p[0] = &amp;amp;a; &lt;br /&gt;
    p[1] = &amp;amp;b; &lt;br /&gt;
 &lt;br /&gt;
    {{comment|Sortiere die Zeiger}} &lt;br /&gt;
    sort2_a (p);&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Sortiert: %d, %d\n&amp;quot;, *p[0], *p[1]);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Für den nächsten Schritt überlegen wir uns, daß das Array in &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; ebensogut void-Pointer enthalten kann. Die einzige Stelle, an der wir auf die endgültigen int-Objekte zugreifen, ist der Vergleich. Diesen Vergleich lagern wir in die Funktion &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; aus:&lt;br /&gt;
 {{comment|Bekommt zwei void-Pointer und vergleicht die Inhalte.&lt;br /&gt;
  * Liefert 0 bei Gleichheit,&lt;br /&gt;
  * -1 wenn der erste Wert kleiner ist als der zweite und&lt;br /&gt;
  * 1  wenn der erste Wert größer ist als der zweite}}&lt;br /&gt;
 int compare_int (void * p0, void * p1)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Um über die Zeiger zugreifen zu können müssen wir diese&lt;br /&gt;
     * erst zu int-Zeigern casten}}&lt;br /&gt;
    int a0 = * (int*) p0;&lt;br /&gt;
    int a1 = * (int*) p1;&lt;br /&gt;
 &lt;br /&gt;
    if (a0 &amp;gt; a1)  return  1;&lt;br /&gt;
    if (a0 &amp;lt; a1)  return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void sort2_b (void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare_int (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Ein Aufruf von &amp;lt;tt&amp;gt;sort2_b&amp;lt;/tt&amp;gt; sieht dann genauso aus wie ein Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt definieren wir uns den neuen Datentyp &amp;lt;tt&amp;gt;comparator_t&amp;lt;/tt&amp;gt;. Dieser ist ein Zeiger auf eine Funktion, die zwei void-Pointer erhält und einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; zurückliefert, also analog arbeitet zu &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; von oben. &lt;br /&gt;
&lt;br /&gt;
Unsere Sortierfunktion bekommt nun neben dem zu sortierenden Zeiger-Array auch eine Vergleichsfunktion &amp;lt;tt&amp;gt;compare&amp;lt;/tt&amp;gt; mitgeliefert, die sie aufruft, wenn sie zwei Objekte vergleichen will&lt;br /&gt;
 {{comment|comparator_t sind Zeiger auf Funktionen, die 2 void-Pointer&lt;br /&gt;
  * erhalten und einen int zurückliefern}}&lt;br /&gt;
 typedef int (*comparator_t) (void*, void*);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Der Sortierer bekommt einen Funktionszeiger auf den Vergleicher.&lt;br /&gt;
  * Der Aufruf vom compare geht so als wäre es eine &amp;quot;normale&amp;quot; Funktion&lt;br /&gt;
  * (ist es im Endeffekt ja auch)}}&lt;br /&gt;
 void sort2_c (comparator_t compare, void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Bei einem Aufruf von &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; muss man dann einen Komparator mit angeben. In einem Beispiel analog zu &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; von oben ist das:&lt;br /&gt;
 sort2_c (compare_int, p);&lt;br /&gt;
Um zwei Strings lexikographisch zu sortieren nehmen wie die Standard-Funktion &amp;lt;tt&amp;gt;strcmp&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void foo()&lt;br /&gt;
 {&lt;br /&gt;
    char * worte[] = { &amp;quot;Wort1&amp;quot;, &amp;quot;Wort2&amp;quot; };&lt;br /&gt;
 &lt;br /&gt;
    sort2_c ((comparator_t) strcmp, (void**) worte);&lt;br /&gt;
 }&lt;br /&gt;
Die Casts sind hier erforderlich. Alternativ könnte man &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; mit reinen void-Pointern versorgen und diese dann dort umcasten.&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
&lt;br /&gt;
Die Syntax zur Definition/Deklaration von Funktionszeigern ist etwas verzwackt. Zur Verdeutlichung ein paar Beispiele. Dabei legt das linke &amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt; jeweils den Return-Typ fest.&lt;br /&gt;
 {{comment|definiert einen neuen Funktionszeiger-Typ}}&lt;br /&gt;
 typedef {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert einen Funktionszeiger}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert ein Array von Funktionszeigern (mit Initializer)}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}[]) ({{type}}, {{type}}, ...) = { wert1, wert2, ... };&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer}}&lt;br /&gt;
 ({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer und ruft die Funktion auf}}&lt;br /&gt;
 (({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}) (arg1, arg2, ...);&lt;br /&gt;
&lt;br /&gt;
=Standard-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==String-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===strcpy===&lt;br /&gt;
Bei vielen Compilern können sie einem String nicht direkt einen Wert (Text) zuweisen. Dazu müssen Sie dann die Prozedur strcpy() benutzen. Diese erwartet als ersten Parameter den Namen einer String-Variablen (ohne eckige Klammern) und als zweiten Parameter den eines (anderen) Strings. Letzterer kann auch ein in doppelten Hochkommas (&amp;quot;) eingeschlossener Text sein. Die Funktion fügt am Ende automatisch ein 0-Zeichen ein. Um diese Funktion nutzen zu können, müssen Sie die Datei string.h includieren! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri1[21], eingabe[21];&lt;br /&gt;
&lt;br /&gt;
  strcpy (stri1, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Der 1. String: %s\n&amp;quot;, stri1);&lt;br /&gt;
  printf (&amp;quot;Bitte geben Sie maximal 20 Zeichen ein: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%s&amp;quot;, eingabe);&lt;br /&gt;
  strcpy (stri1, eingabe);&lt;br /&gt;
  printf (&amp;quot;\n%s = %s&amp;quot;, stri1, eingabe);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis:''' &lt;br /&gt;
Da ein String, wie jedes Feld, eigentlich ein Zeiger ist, dürfen Sie kein &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; bei &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; angeben!&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
Es werden zwei gleich große Strings definiert: &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;eingabe&amp;lt;/tt&amp;gt;, mit je 20 &amp;quot;nutzbaren&amp;quot; Zeichen. &lt;br /&gt;
In &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; wird die Zeichenkette &amp;lt;tt&amp;gt;&amp;quot;hallo&amp;quot;&amp;lt;/tt&amp;gt; hineinkopiert. Das 0-Zeichen am Ende wird automatisch angefügt. &lt;br /&gt;
Der String wird ausgegeben. Als neues &amp;quot;Sonderzeichen&amp;quot; kommt &amp;lt;tt&amp;gt;%s&amp;lt;/tt&amp;gt; ins Spiel. Es hat die gleiche Aufgabe wie &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt;, nur für Strings. &lt;br /&gt;
Sie werden gebeten, eine String einzugeben. &lt;br /&gt;
Dieser String wird danach in die Variable &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; kopiert. &lt;br /&gt;
Beide Strings, die ja nun die gleiche Zeichenkette enthalten, werden ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===strlen===&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;strlen&amp;lt;/tt&amp;gt;, die als Parameter eine String-Variable erwartet, liefert die Länge diese Strings zurück. Sie werden jetzt vermutlich sagen: &amp;quot;Das ist doch klar, wie lang der String ist. Ich habe es ja bei der Deklaratin angegeben&amp;quot;. Das stimmt schon, aber denken Sie noch einmal an die null-terminierten Strings. Das 0-Zeichen steht am Ende des Strings (am Ende der gültigen Zeichenfolge), aber nicht unbedingt am Ende des reservierten Speicherplatzes. Haben Sie eine Variable &amp;quot;char Variable[21];&amp;quot;, und ihr den Wert &amp;quot;hallo&amp;quot; zugewiesen, dann steht das null-Zeichen in Variable[5]. Der &amp;quot;gültige&amp;quot; String ist also 5 Zeichen (0-4) lang. Und genau das (5) würde strlen zurück liefern. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri[21];&lt;br /&gt;
  &lt;br /&gt;
  strcpy (stri, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
  printf (&amp;quot;Der String ist %d Zeichen lang&amp;quot;, strlen (stri));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird vor allem gebraucht, wenn Sie direkt auf den String zugreifen, mittels &amp;lt;tt&amp;gt;stri[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;stri[1]&amp;lt;/tt&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
==Ein- und Ausgabe-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===Bildschirm-Ausgabe===&lt;br /&gt;
Bisher war das Tutorial trotz aller Beispiele reine Theorie. Sie konnten zwar Programme schreiben, aber die Funktion nicht testen. Hier lernen Sie nun, wie Sie etwas am Bildschirm ausgeben.&lt;br /&gt;
&lt;br /&gt;
Die dazu notwendige Funktione heisst &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (das '&amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt;' ist kein Fehler!). Diese Anweisung gibt die ihr übergebenen Parameter auf das Standard-Ausgabegerät aus, in der Regel also auf den Bildschirm. Sie kann beliebig viele Parameter übernehmen. Es müssen jedoch Standard-Datentypen (z.B. &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;...) sein! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
    int zahl1 = 12;&lt;br /&gt;
    char zeichen1 = 'A';&lt;br /&gt;
    &lt;br /&gt;
    printf (&amp;quot;Das ist Text, und er wird als solcher ausgegeben. \n&amp;quot;);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zahl1' ist: %d \n&amp;quot;, zahl1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %c \n&amp;quot;, zeichen1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %d \n&amp;quot;, zeichen1);&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt Text aus. Das Zeichen am Ende (&amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;) bedeutet &amp;quot;New Line&amp;quot;, es bewegt den Cursor an den Anfang der nächsten Zeile. &lt;br /&gt;
&lt;br /&gt;
Der zweite &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt auch Text aus, am Ende befindet sich wieder das &amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;, um einen Zeilenvorschub zu erreichen. Das &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; wird vom Compiler durch den ersten Parameter ersetzt, der nach dem Text angegeben wird. In diesem Fall wird &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; also durch den Wert der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ersetzt. Das &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; im &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; bedeutet &amp;quot;Dezimalzahl&amp;quot;, der Computer gibt also eine ganze Zahl aus. &lt;br /&gt;
&lt;br /&gt;
In der dritten Ausgabe wird ein Zeichen ausgegeben. Diesmal bedeutet &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; &amp;quot;char&amp;quot; (Zeichen). Es wird also &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; durch ein &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt; ersetzt, denn die Variable &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; wird als Character interpretiert. &lt;br /&gt;
&lt;br /&gt;
Die letzte Ausgabe interpretiert den Inhalt von &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; als Zahl, und gibt dager den ASCII-Wert von &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, also 65 aus. Das ist ein typisches Beispiel für das mögliche unterschiedliche Interpretieren einer  Variablen!&lt;br /&gt;
&lt;br /&gt;
===Tastatur-Eingabe===&lt;br /&gt;
&lt;br /&gt;
Um ein &amp;quot;gscheites&amp;quot; Programm schreiben zu können, muß man wissen, wie der Benutzer über die Tastatur Befehle eingeben kann. Die dafür notwendigen Funktionen stelle ich in diesem Kapitel vor.&lt;br /&gt;
Die wichtigste Funktion ist &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt;. Er liest Daten von der Tastatur. Die Syntax entspricht derer von &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int  zahl1;&lt;br /&gt;
char zeichen1;&lt;br /&gt;
&lt;br /&gt;
printf (&amp;quot;Bitte geben Sie eine Zahl ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl1);&lt;br /&gt;
printf (&amp;quot;Geben Sie einen Zeichen ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%c&amp;quot;, &amp;amp;zeichen1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Programm gibt eine Eingabeaufforderung aus. Dann erwartet es vom Benutzer, daß er eine Zahl eingibt, die mit [ENTER] bestätigt wird. Dieser Wert wird in &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; abgespeichert. Danach erfolgt wiederum eine Aufforderung zur Eingabe, diesmal eines einzelnen Zeichens. Dieses kann man nun eingeben und ebenfalls mit [ENTER] bestätigen.&lt;br /&gt;
&lt;br /&gt;
Macht man keine dem Datentyp der erwarteten Variable entsprechende Eingabe, dann bricht das Programm mit einer Fehlermeldung ab (wenn man z.B. &amp;quot;1_T2&amp;quot; eingibt, wenn eine Zahl erwartet wird)!&lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; vor den Parametern ist notwendig. Warum, das erfahren Sie im Kapitel &amp;quot;Unterprogramme&amp;quot;. Für die Profis eine Kurz-Erklärung: Das Unterprogramm &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; bekommt zwar einen Wert übergeben, kann aber keinen zurückliefern (&amp;quot;call by value&amp;quot;). Daher wird kein Wert, sondern ein Zeiger auf eine Variable übergeben. Mit dem &amp;amp; Zeichen bekommen Sie die Adresse einer Variablen (&amp;quot;call by reference&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=Parameter von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;=&lt;br /&gt;
Das Unterprogramm &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; kann, wie jede andere Funktion, Parameter besitzen. Doch keine selbst gewählten, sondern nur bestimmte. Doch warum braucht main Parameter? Denken Sie einmal an alle Betriebssystembefehle:&lt;br /&gt;
&amp;lt;tt&amp;gt;dir *.exe &amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;copy *.* a:&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;ls -la &amp;lt;/tt&amp;gt;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;&amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen!&lt;br /&gt;
&lt;br /&gt;
=Kurzreferenz=&lt;br /&gt;
==Syntax-Bausteine==&lt;br /&gt;
&lt;br /&gt;
Die Erklärung des Aufbaus von C-Befehlen erfolgt neben einfachen Beispielen auch durch ihren prinzipellen Aufbau. In diesen Syntax-Beschreibungen finden sich immer wieder die gleichen Bausteine, die hier näher erklärt werden sollen. Falls die solch ein Syntax-Baustein begegnet, kannst Du ihn anclicken und kommst dann zu seiner Erläuterung. &lt;br /&gt;
&lt;br /&gt;
In den Beispielen selbst gehören auch die spitzen Klammern zu dem Baustein (was daran zu erkennen ist, daß auch die Klammern eingefärbt sind). Die Klammern dürfen in einem konkreten C-Programm daher nicht eingetippt werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bezeichner&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Bezeichner in C dienen dazu, Variablen zu identifizieren und ihnen sprechende Namen zu geben, um die Quelle lesbarer zu machen. Man braucht Bezeichner auch, um selbstdefinierte Datentypen zu benennen und zum Benennen von Struct- und Union-Komponenten sowie als Namen für Funktionen und Sprungmarken (Labels).&lt;br /&gt;
&lt;br /&gt;
Bezeichner dürfen aus den Kleinbuchstaben &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;z&amp;lt;/tt&amp;gt;, den Großbuchstaben &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;Z&amp;lt;/tt&amp;gt;, dem Unterstrich&amp;amp;nbsp;&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt; und den Ziffern &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;9&amp;lt;/tt&amp;gt; aufgebaut werden, wobei an erster Stelle jedoch keine Ziffer stehen darf.&lt;br /&gt;
&lt;br /&gt;
Es wird zwischen Groß- und Kleinschreibung unterschieden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Ausdruck in C ist ein Konstrukt, das einen Wert hat. Ob dieser Wert eine ganze Zahl ist, eine Kommazahl oder ein Zeiger, etc. ist dabei egal. Die einfachsten Ausdrücke sind Konstanten wie&lt;br /&gt;
 2&lt;br /&gt;
oder Variablen wie&lt;br /&gt;
 ein_zahl&lt;br /&gt;
Mehrere Ausdrücke können durch [[#Liste der Operatoren|Operatoren]] zu komplexeren Ausdrücken kombiniert werden, etwa&lt;br /&gt;
 eine_zahl + andere_zahl == 2&lt;br /&gt;
oder &lt;br /&gt;
 eine_zahl = 2&lt;br /&gt;
Letzterer hat den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; und den Nebeneffekt, daß er diesen Wert an &amp;lt;tt&amp;gt;eine_zahl&amp;lt;/tt&amp;gt; zuweist.&lt;br /&gt;
&lt;br /&gt;
Auch der Aufruf einer Funktion, die einen Rückgabewert liefert, ist ein Ausdruck:&lt;br /&gt;
 sin (1.2)&lt;br /&gt;
und kann zum Aufbau komplexerer Ausdrüche verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bedingung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Bedingung ist ein Ausdruck, bei der nur interessiert, ob dieser zu&amp;amp;nbsp;0 (unwahr) auswertet oder zu ungleich&amp;amp;nbsp;0 (wahr). Solche Ausdrücke findet man in if-Anweisungen, in Schleifenbedingungen und bedingten Zuweisungen&lt;br /&gt;
 (ein_wert &amp;lt; 2) || (ein_wert &amp;gt; 40)&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Lvalue ist ein Ausdruck, dem etwas zugewiesen werden kann. Der Name ''Lvalue'' kommt aus dem Englischen. Das ''L'' steht abkürzend für left. Ein Lvalue ist damit ein Ausdruck, der auf der linken Seite eine Zuweisung in C stehen darf. Das &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; in den folgenden Beispiel-Ausdrücken muss ein Lvalue sein:&lt;br /&gt;
 x = y-1&lt;br /&gt;
&lt;br /&gt;
 x++&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Konstante&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Konstante ist ein Ausdruck, dessen Wert dem Compiler bekannt ist. Beispiele für Konstanten sind etwa&lt;br /&gt;
 7&lt;br /&gt;
 'B'&lt;br /&gt;
 -13.98e12&lt;br /&gt;
 1+(2*3)&lt;br /&gt;
und die Werte von [[#Enum|Enum]]s. &lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; aus dem folgenden Codestück definiert jedoch keine Konstante in diesem Sinne&lt;br /&gt;
 const double Pi = 3.14159256;&lt;br /&gt;
denn in einem anderen Quellmodul könnte durch die Deklaration&lt;br /&gt;
 extern const double Pi;&lt;br /&gt;
das Symbol &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; bekannt sein, ohne daß sein Wert bekannt ist!&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Adresse&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Adresse ist ein Ausdruck, der einen Speicherort (physikalisch oder virtuell) halten kann. Adressen erhält man dadurch, daß man einem Bezeichner den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt;voranstellt, Adressen durch Arithmetik berechnet oder Zahlen zu Adressen castet. Folgende Ausdrücke sind Adressen (eine sinnvolle Deklaration der auftretenden Variablen vorausgesetzt)&lt;br /&gt;
 &amp;amp; eine_zahl&lt;br /&gt;
 &amp;amp; ein_array[10]&lt;br /&gt;
 &amp;amp; ein_struct&lt;br /&gt;
 &amp;amp; ein_struct.komponente&lt;br /&gt;
 (int *) 0x1234&lt;br /&gt;
 (int *) eine_zahl&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Deklaration&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Anweisungen sind gewissermassen die Atome (oder Moleküle?), aus denen ein C-Programm besteht. Jedes C-Programm ist eine Abfolge von Deklarationen und Anweisungen. Einfache Anweisungen erhält man, in dem man einen Ausdruck nimmt und einen Strichpunkt dahinter schreibt:&lt;br /&gt;
 {{Ausdruck|}};&lt;br /&gt;
wie in&lt;br /&gt;
 x = x+1;&lt;br /&gt;
&lt;br /&gt;
Andere Anweisungen sind die unten aufgeführten Schleifen und die if- sowie die switch-Anweisung.&lt;br /&gt;
&lt;br /&gt;
Mehrere Deklarationen und Anweisungen können zu einem Block zusammengefasst werden. Dieser Block stellt dann wieder eine einzelne Anweisung dar und kann genau so gehandhabt werden!&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
In diesem Sinne ist auch z.B. die Syntax der if-Anweisung zu verstehen&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
besagt, daß der abhängig ausgeführte Code eine einzelne Anweisung sein darf oder eben ein kompletter Block oder die Verschachtelung mehrerer Blöcke etc.&lt;br /&gt;
&lt;br /&gt;
Eine Anweisung kann auch &amp;quot;leer&amp;quot; sein, also nichts tun. Diese Anweisungen sind der leere Block&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
und der Strichpunkt&lt;br /&gt;
 ;&lt;br /&gt;
die man gelegentlich in Schleifen findet:&lt;br /&gt;
 while (!timeout())&lt;br /&gt;
    {}&lt;br /&gt;
oder hinter Sprungmarken, die sonst direkt vor einer schliessenden Blockklammer stünden:&lt;br /&gt;
 {&lt;br /&gt;
    ...&lt;br /&gt;
    goto ein_label;&lt;br /&gt;
    ...&lt;br /&gt;
    {{Label|ein_label}}:;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Nicht jede Anweisung ist an jeder Stelle eines C-Programms erlaubt, so darf ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; nut innerhalb einer Schleife stehen. Gleiches gilt für &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;, das aber auch innerhalb eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; vorkommen darf.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Dies steht für einen Datentyp. Es kann ein elementarer Typ sein wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;, ein Zeiger darauf wie &amp;lt;tt&amp;gt;char*&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;void*&amp;lt;/tt&amp;gt;, und auch Qualifier enthalten wie das &amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt; im Typ &amp;lt;tt&amp;gt;unsigned long long&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Zu den Typen gehören auch zusammengesetzte Datentypen wie Strukturen und Unions, mit &amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt; selbst definierte Typen und natürlich Zeiger darauf, wie aus dem Abschnitt [[#Datentypen|Datentypen]]:&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person *&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;data32_t&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;&lt;br /&gt;
und Zeiger auf Funktionen.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Parameterliste&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
Die Parameterliste bei einer Funktionsdefinition gibt an, wieviel Übergabeparameter sie bekommt, wie diese heissen und welchen Typs diese sind. Der prinzipielle Aufbau ist&lt;br /&gt;
 {{Type}} {{Bezeichner}}, {{Type}} {{Bezeichner}}, ...&lt;br /&gt;
Falls die Funktion keine Parameter hat, dann ist die Parameterliste leer.&lt;br /&gt;
&lt;br /&gt;
Hier als Beispiel die zweiparametrige Funktion &amp;lt;tt&amp;gt;produkt&amp;lt;/tt&amp;gt;. Der erste Parameter heisst&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und ist ein &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;. Der zweite namens&amp;amp;nbsp;&amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; ist vom Typ &amp;quot;Zeiger auf double&amp;quot;, der Inhalt &amp;lt;tt&amp;gt;*b&amp;lt;/tt&amp;gt; ist also auch ein double.&lt;br /&gt;
&lt;br /&gt;
'''Definition der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b)&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
In älteren C-Quellen findet man noch eine andere Syntax für die Deklaration der Parameter, die aber heute praktisch nicht mehr verwendet wird:&lt;br /&gt;
'''alte Definition der Funktion:'''&lt;br /&gt;
 double produkt (a, b)&lt;br /&gt;
 double a, *b;&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Um die Funktion bekannt zu machen, werdendet man eine Deklaration bzw. den Prototypen, der dem Compiler nur mitteilt, welche Parameter die Funktion bekommt und was sie zurückliefert. Für den Aufruf der Funktion muss der Compiler nur diesen Prototyp kennen, ''was'' die Funktion im Endeffekt macht und wie sie implementiert wurde ist egal, sie wird als BlackBox angesehen.&lt;br /&gt;
&lt;br /&gt;
'''Prototyp der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b);&lt;br /&gt;
Hier dürfen die Bezeichner auch fehlen:&lt;br /&gt;
 double produkt (double, double*);&lt;br /&gt;
&lt;br /&gt;
==if==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==if-else==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==for==&lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Eine for-Schleife entspricht folgendem Konstrukt. Dabei sind die drei Ausdrücke optional. Fehlt die Bedingung, dann wird diese als &amp;quot;wahr&amp;quot; angenommen. Die beiden anderen Ausdrücke wird man als Ausdrücke mit Nebeneffekt wählen wie z.B. &amp;lt;tt&amp;gt;x=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;x=x-2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
 {&lt;br /&gt;
    {{Ausdruck|1}};&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_loop}}:&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
    else&lt;br /&gt;
       goto _break;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_continue}}:&lt;br /&gt;
    {{Ausdruck|2}};&lt;br /&gt;
    goto _loop;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_break}}:;&lt;br /&gt;
 }&lt;br /&gt;
Die Labels &amp;lt;tt&amp;gt;_break&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_continue&amp;lt;/tt&amp;gt; entsprechen den Sprungzielen einer &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Anweisung innerhalb von &amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==do-while==&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while  ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
==while==&lt;br /&gt;
 while  ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==switch==&lt;br /&gt;
 switch  ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    ...&lt;br /&gt;
  &lt;br /&gt;
    default:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#break-Anweisung|&amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Konstanten|&amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#continue-Anweisung|&amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#do-while-Schleife|&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Enum|&amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#for-Schleife|&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#goto-Anweisung|&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#return-Anweisung|&amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Liste der Operatoren|sizeof]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Strukturen|&amp;lt;tt&amp;gt;struct&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Eigene Datentypen|&amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Unions|&amp;lt;tt&amp;gt;union&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#while-Schleife|&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund2}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Arithmetische Operatoren&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Dies sind die &amp;quot;normalen&amp;quot; arithmetischen Operationen, wie man sie aus der Schule kennt. Man kann damit und allen anderen Operatoren auch komplexere Ausdrücke aufbauen. Die Prioritäten sind so, wie man sie kennt, also &amp;quot;Punktrechnung vor Strichrechnung&amp;quot;. Will man dies ändern, dann mit den runden Klammern:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;1+2*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 7&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(1+2)*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 9&amp;lt;br/&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}}&amp;amp;nbsp;+&amp;amp;nbsp;{{Ausdruck|}}&amp;lt;/tt&amp;gt; || Addition&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} - {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Subtraktion&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} * {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Multiplikation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} / {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Division&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} % {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Rest der Division (modulo)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;- {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Vorzeichenumkehr, Zweier-Komplement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Logische Operatoren und Vergleiche&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die logischen und die vergleichenden Operatoren liefern als Ergebnis den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (wahr) oder einen Wert ungleich&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (falsch, um genau zu sein den Wert &amp;lt;tt&amp;gt;!0&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Man kann das Ergebnis zwar einer Variablen zuweisen, in aller Regel wird man solche Ausdrücke jedoch in Bedingungen zu &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder in Abbruch-Bedingungen von Schleifen finden.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;&amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches AND: beides wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124;&amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches OR: mind. eines ist wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;! {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches NOT (0 &amp;amp;harr; ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} == {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} != {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist nicht gleich&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bitweise Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~ {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise NOT (Einser-Komplement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise AND&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise ODER&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} ^ {{Ausdruck|}}&amp;lt;/tt&amp;gt; ||bitweise XOR&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Shift-Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;lt;&amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Bits nach links schieben&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;gt;&amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Schieben nach rechts schieben&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Typen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Ein Cast in C kann dazu verwendet werden, den Typ eines Ausdruckes zu ändern oder den Ausdruck mit einer bestimmten Genauigkeit zu berechnen. Wird z.B. eine Berechnung standardmässig in 16 Bit ausgeführt, dann kann man mit einem Cast &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(long) &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
ausdrücken, daß die Berechnung in 32 Bit erfolgen soll. Des weiteren kann man Zeiger und ganze Zahlen und Gleitkommazahlen ineinander umwandeln.&lt;br /&gt;
&lt;br /&gt;
Casts können ''nicht'' dazu verwendet werden, um z.B. eine Zahl in einen String zu konvertieren, der diese Zahl darstellt! Dafür gibt es spezielle Funktionen wie &amp;lt;tt&amp;gt;itoa&amp;lt;/tt&amp;gt;!&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Type}}) {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Cast, Typwandlung&lt;br /&gt;
|-&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;| &amp;lt;tt&amp;gt;sizeof ({{Type}})&amp;lt;/tt&amp;gt; || Eine Konstante, deren Wert die Größe (in Bytes) des Typs ist. &amp;lt;tt&amp;gt;sizeof&amp;lt;/tt&amp;gt; ist auch auf Objekte anwendbar wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, Arrays bekannter Größe, Strukturen und Unions,  Array-, Struktur- und Union-Komponenten, Pointer, etc. Beispiel:&amp;lt;br/&amp;gt;&lt;br /&gt;
 int i, sum=0, array[] = { 1, -13, 4, 0, sizeof (int*) };&lt;br /&gt;
 &lt;br /&gt;
 for (i=0; i&amp;lt; sizeof (array) / sizeof (array[0]); i++)&lt;br /&gt;
    sum += array[i];&lt;br /&gt;
Alle Elemente des Arrays werden aufaddiert, ohne daß deren Anzahl explizit in der Schleife genannt ist.&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zeiger und Adressen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;* {{Adresse}}&amp;lt;/tt&amp;gt; || der Inhalt an Adresse&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp; {{Lvalue}}&amp;lt;/tt&amp;gt; || Adresse von&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Strukturen, Unions, Arrays&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Struct&amp;gt;}}.{{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Zeiger-auf-Struct&amp;gt;}} -&amp;gt; {{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union, deren Adresse man hat&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Adresse}}&amp;amp;#91;{{Ausdruck|}}&amp;amp;#93;&amp;lt;/tt&amp;gt; || Array-Element&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bedingte Auswertung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Bedingung}}) ? {{Ausdruck|}} : {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Auswahl des Wertes abhängig von der Bedingung&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zuweisung und Operatoren mit Nebeneffekt&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die Unterschiede der post- und pre-Varianten der Increment/Decrement kommen in Konstrukten wie &amp;lt;tt&amp;gt;x = *p++&amp;lt;/tt&amp;gt; zum tragen:&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *p++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; p = p+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *++p;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; p = p+1; x = *p;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = (*p)++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; *p = (*p)+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = ++(*p);&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; *p = (*p)+1; x = *p;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} = {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Zuweisung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++ {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-- {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Decrement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ++&amp;lt;/tt&amp;gt; || Post-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} --&amp;lt;/tt&amp;gt; || Post-Decrement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Kurzschreibweisen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Für ganz Faule gibt es anstatt&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a = a @ b&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
für viele Operatoren (hier dargestellt durch ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;@&amp;lt;/tt&amp;gt;) die abkürzende Schreibweise&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a @= b&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} += {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} -= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} *= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} /= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} %= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ^= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;lt;&amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;gt;&amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Autoren'''&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
* Kernighan und Ritchie - Buch&lt;br /&gt;
* Christian Wirth , C Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://wwwuser.gwdg.de/~kboehm/ebook/inhalt.html C-Programmieren unter Linux]&lt;br /&gt;
* [http://www.gdv.uni-hannover.de/documentation.php Skripte zum Selbststudium: C, C++, Java, etc]&lt;br /&gt;
* [http://info.baeumle.com/ansic.html Einführung in ANSI-C]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Quellcode C|!]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Inrfb2</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10387</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=10387"/>
				<updated>2007-03-13T10:40:01Z</updated>
		
		<summary type="html">&lt;p&gt;Inrfb2: /* Das Hauptprogramm main */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Programmiersprache C wurde 1971 als Gundlage für das Betriebssystem UNIX in den USA entwickelt (UNIX ist zu über 90% in C geschrieben). 1978 wurde von Brian Kernighan und Dennis Ritchie eine eindeutige Sprachdefinition entwickelt. Mittlerweile ist C von ANSI und ISO standardisiert.&lt;br /&gt;
&lt;br /&gt;
Heute sind C und ihr Nachfolger C++ die dominierenden Programmiersprachen. Sehr viele Anwendungen sind in C geschrieben, was inzwischen auch auf eingebettete Systeme zutrifft, die lange in Assembler programmiert werden mussten, da keine ausreichend leistungsfähigen Compiler zur Verfügung standen. &lt;br /&gt;
&lt;br /&gt;
Leider ist C nicht einfach zu lernen &amp;amp;ndash; es wurde weder von noch für Hobby-Programmierer entwickelt &amp;amp;ndash; und eignet sich daher nur bedingt für den Einsteiger. Mit etwas Übung und einem optimierenden Compiler kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
Vom Design her ist C eine Hardware-unabhängig Sprache. Das bedeutet, daß C-Programme mit vertretbarem Aufwand auf ein anderes System portiert werden können. Dazu benötigt man lediglich einen anderen Compiler, und Inline-Assembler-Anweisungen (Assembleranweisungen innerhalb eines C-Programmes) müssen der neuen Hardware (Prozessor) angepasst werden. &lt;br /&gt;
&lt;br /&gt;
==Geschichte==&lt;br /&gt;
;1971: C wird entwickelt&lt;br /&gt;
;1978: Kernighan und Ritchie definieren die Sprache.&lt;br /&gt;
;1983: ANSI und ISO standardisieren C.&lt;br /&gt;
;1992: Bjarne Stroustrup enwickelt die Nachfolgesprache C++.&lt;br /&gt;
&lt;br /&gt;
=Aufbau eines C-Programmes=&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
   C-Programme haben keinen fixen Aufbau wie z.B. Pascal. Es gibt zwar gewisse Regeln, aber sonst sind dem Programmierer alle Freiheiten überlassen. Der folgende &amp;quot;Beispiel-Aufbau&amp;quot; ist daher nicht zwingend und kann durchaus verändert werden.&lt;br /&gt;
&lt;br /&gt;
   Natürlich haben C-Programme einen fixen Aufbau! Ebenso wie Pascal-Programme auch unterliegen sie einer strikten Grammatik! &lt;br /&gt;
Auskommentiert --[[Benutzer:SprinterSB|SprinterSB]] 10:23, 17. Feb 2006 (CET)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Ein einfaches C-Programm könnte folgendermassen aussehen. Das Programm tut eigentlich nichts, aber das Beispiel zeigt den prinzipiellen Aufbau. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 int Zahl1;&lt;br /&gt;
 char Zeichen1;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int zahl2;&lt;br /&gt;
 &lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Beschreibung:'''&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndash; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
 {{comment|void-Definition von main ist nur beim Controller ueblich}}&lt;br /&gt;
 {{comment|spezielle Compilereinstellungen sind noetig, damit bei dieser Definition von main}}&lt;br /&gt;
 {{comment|kein Fehler/Warnung erzeugt wird.}}&lt;br /&gt;
 void main ()&lt;br /&gt;
 {&lt;br /&gt;
     ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
 int main (void)&lt;br /&gt;
 {  {{comment|der Block &amp;quot;main&amp;quot; beginnt}}&lt;br /&gt;
    int zahl;&lt;br /&gt;
    &lt;br /&gt;
    {   {{comment|ein Block beginnt}}&lt;br /&gt;
        {{comment|hier koennen Deklarationen und Anweisungen stehen}}&lt;br /&gt;
    }   {{comment|der Block endet}}&lt;br /&gt;
   &lt;br /&gt;
    return 0;&lt;br /&gt;
 }  {{comment|&amp;quot;main&amp;quot; endet}}&lt;br /&gt;
&lt;br /&gt;
=Datentypen=&lt;br /&gt;
==Elementare Datentypen==&lt;br /&gt;
Der Datentyp einer Variable gibt an, welche Werte eine Variable enthalten kann, welcher Art diese Daten sind und wie sie verarbeitet werden, etwa in arithmetischen Operationen wie einer Addition. So ist es zum Beispiel möglich, in eine Variable vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ganze Zahlen zwischen ca. -32000 und +32000 einzutragen. In einer char-Variable können ASCII-Zeichen gespeichert werden (alles, was Sie mit der Tastatur erzeugen können) oder ganze Zahlen von -128 bis 127.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da C plattformabhängig ist, hängt die Größe eines Datentypes zum Teil von der genutzten Hardware (z.B. 8, 16 oder 32 Bit-Controller) und dem Compiler und dessen Einstellungen ab!&lt;br /&gt;
&lt;br /&gt;
===int, char, short, long (ganze Zahlen)===&lt;br /&gt;
In Variable dieser Typen können Sie ganze Zahlen abspeichern, also z.B. 1, &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;2, 100, 12345. Jeden dieser Typen gibt es in zwei Ausprägungen: als &amp;quot;&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;quot;, also als vorzeichenbehafteten Typ, und als &amp;quot;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&amp;quot;, also ohne Vorzeichen, d.h. das Vorzeichen wird als 0 oder +1 genommen. &lt;br /&gt;
&lt;br /&gt;
Vorzeichenbehaftete Ganzzahl-Typen werden intern im &amp;lt;tt&amp;gt;n-1&amp;lt;/tt&amp;gt;-Komplement dargestellt, das Vorzeichen selbst findet sich also im höchstwertigen Bit. Werden zur Speicherung ''b'' Bits verwendet, dann reicht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;*zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==Enum==&lt;br /&gt;
&lt;br /&gt;
Über &amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt; können Aufzählungen definiert werden. Die Werte sind &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Werte und beginnen mit&amp;amp;nbsp;0. Der folgende enum hat einen um&amp;amp;nbsp;1 grösseren Wert. Mit einer Zuweisung können auch andere Werte zugeordnet werden. Klarer wird's im Beispiel:&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
 enum Farben&lt;br /&gt;
 {&lt;br /&gt;
    ROT,&lt;br /&gt;
    GRUEN,&lt;br /&gt;
    BLAU,&lt;br /&gt;
    BRAUN = 5,&lt;br /&gt;
    SCHWARZ&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/tt&amp;gt;&lt;br /&gt;
Dies definiert die Konstanten &amp;lt;tt&amp;gt;ROT=0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;GRUEN=1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BLAU=2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BRAUN=5&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;SCHWARZ=6&amp;lt;/tt&amp;gt; und den Typ &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void foo (enum Farben farbe)&lt;br /&gt;
{&lt;br /&gt;
   switch (farbe)&lt;br /&gt;
   {&lt;br /&gt;
      case ROT:&lt;br /&gt;
         ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit kann man anstatt &amp;quot;magischer&amp;quot; Zahlen sprechende Namen im Code verwenden, etwa in Berechnungen und Zuweisungen, Vergleichen oder als Konstante hinter einem &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zusammengesetzte Datentypen==&lt;br /&gt;
===Arrays===&lt;br /&gt;
Oft muß man sehr viele Werte gleichzeitig abspeichern und betrachten, die alle der selben Aufgabe dienen. Man schreibt z.B. ein Programm, das 10 Zahlen einlesen und anschließend wieder ausgeben soll. Man könnte das natürlich mit 10 einzelnen Variablen bewerkstelligen, aber es ist sinnvoller, dabei Arrays &amp;amp;ndash; teilweise auch als ''Felder'' bezeichnet &amp;amp;ndash; zu verwenden.&lt;br /&gt;
&lt;br /&gt;
In einem Array werden mehrere Variablen gleichen Typs zusammengefasst und hintereinander im Speicher abgelegt. So kann man viele tausend Variablen anlegen mit nur einer Zeile Code. Doch es gibt noch größere Vorteile: Sie können das Array mit einer Schleife ganz einfach nach Werten durchsuchen. Stellen Sie sich vor, Sie müssten mit 100 verschiedenen Variablen &amp;lt;tt&amp;gt;Zahl_00&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;Zahl_99&amp;lt;/tt&amp;gt; arbeiten!&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}}&amp;amp;#91;{{Konstante}}&amp;amp;#93;;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 unsigned int werte[100];&lt;br /&gt;
&lt;br /&gt;
Der Name muß natürlich ein gültiger Bezeichner sein, als Datentyp kann jeder Typ genommen werden &amp;amp;ndash sowohl elementare Datentypen als auch Zeiger, Strukturen, Unions oder selbst definierte Datentypen. In der eckigen Klammer wird die Anzahl der Elemente bekanntgegeben. Ein mit [3] definiertes Array hat Platz für drei Variablen. Da der Index immer bei 0 beginnt, greift man also mit &amp;lt;tt&amp;gt;[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;[1]&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;[2]&amp;lt;/tt&amp;gt; auf den jeweilige Inhalt zu. Um auf eine der im Array enthaltenen Variablen zugreifen zu können, müssen Sie den Variablennamen und in eckigen Klammern den Index (die &amp;quot;Nummer&amp;quot;) der Variablen angeben. Diese Variable verhält sich dann wie eine ganz normale Variable des jeweiligen Datentypes. &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #define NZAHLEN 10&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int i;&lt;br /&gt;
    int zahlen[NZAHLEN];  {{comment|zahlen[0] ... zahlen[9]}}&lt;br /&gt;
  &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++)&lt;br /&gt;
    {&lt;br /&gt;
       printf (&amp;quot;Bitte Zahl %d eingeben: &amp;quot;, i);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; zahlen[i]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    for (i=0; i &amp;lt; NZAHLEN; i++) &lt;br /&gt;
       printf (&amp;quot;Zahl %d ist: %d\n&amp;quot;, i, zahlen[i]);&lt;br /&gt;
      &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 10 int-Variablen großes Array angelegt. &lt;br /&gt;
In dieses wird nun der Reihe nach 10 Zahlen eingelesen. &lt;br /&gt;
Anschließend werden alle 10 Zahlen ausgegeben. &lt;br /&gt;
&lt;br /&gt;
Dabei wird die Größe der Arrays und das Schleifenende über das Define &amp;quot;&amp;lt;tt&amp;gt;NZAHLEN&amp;lt;/tt&amp;gt;&amp;quot; angegeben. Dadurch muss nur ''eine Stelle'' im Code geändert werden, wenn die Größe des Arrays einmal einen anderer Wert als 10 haben soll &amp;amp;ndash; dies vermeidet Fehler die dadurch entstehen, wenn man beim Anpassen der Array-Größe eine Codestelle vergisst, zudem wird der Code lesbarer als wenn irgendwo die Zahl &amp;quot;10&amp;quot; auftaucht.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
:Wird ein ungültiger Index angeben (einer, der in der Deklaration nicht enthalten ist) können  undefinierte Dinge passieren, wenn dadurch andere Variableninhalte oder Programmcode überschrieben wird, der hinter oder vor dem Array im Speicher liegt. Schlimmstenfalls kann sogar der Computer/Controller abstürzen. Also darauf achten, daß keine ungültigen Werte als Index auftreten!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Strings (Zeichenketten)===&lt;br /&gt;
Ein String ist nichts anderes als ein Array, das aus einzelnen Zeichen (&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;) gebildet wird. Die Ausgabe auf dem Bildschirm funktioniert am einfachsten mittels Strings.&lt;br /&gt;
&lt;br /&gt;
Die Definition eines Strings erfolgt also genauso wie bei Arrays:&lt;br /&gt;
 char string[21];&lt;br /&gt;
&lt;br /&gt;
Nun haben Sie eine String, in dem Sie 21 Zeichen speichern können. Ganz richtig ist das jedoch nicht. C arbeitet mit &amp;quot;null-terminierten Strings&amp;quot;. Das beudeutet, dass die Länge des Strings nicht abgespeichert wird, sondern das Zeichen mit dem ASCII-Wert 0 das Stringende kennzeichnet. Daher auch die Bezeichnung  &amp;quot;null terminiert&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Das letzte Zeichen eines Strings muß daher immer das ASCII-Zeichen Nr. 0 sein. Ist es das nicht, hat der String kein definiertes Ende, und wenn Sie versuchen, ihn durch eine Standard-Funktion auszugeben zu lassen, könnte es eine Weile dauern, bis sich im Speicher zufällig irgendwo eine 0 befindet. Es stehen ihnen daher bei dem Beispiel nur 20 Zeichen zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
===Mehrdimensionale Arrays===&lt;br /&gt;
Manchmal benötigt man mehr als nur ein eindimensionales Array, wie Sie es bisher kennengelernt haben. Auch dies ist kein Problem. In der Deklaration geben Sie einfach mehrere eckige Klammern hintereinander an. Aber Vorsicht: der Speicherplatz ist begrenzt, ein &amp;quot;&amp;lt;tt&amp;gt;char feld[1024][1024]&amp;lt;/tt&amp;gt;&amp;quot; hat die Speicherplatzgrenzen vermutlich bereits weit überschritten, und der Compiler wird einen (bei gewissen Einstellung auch keinen) Fehler liefern.&lt;br /&gt;
Beim Zugriff auf mehrdimensionale Felder müssen auch mehrere Indizes angeben werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  int x,y;&lt;br /&gt;
  int feld[3][5];&lt;br /&gt;
 &lt;br /&gt;
  for (x=0; x&amp;lt;3; x++) &lt;br /&gt;
  {&lt;br /&gt;
     for (y=0; y&amp;lt;5; y++)&lt;br /&gt;
     {&lt;br /&gt;
       printf (&amp;quot;Feldwert x: %d,  y: %d &amp;quot;, x, y);&lt;br /&gt;
       scanf  (&amp;quot;%d&amp;quot;, &amp;amp; feld[x][y]);&lt;br /&gt;
       printf (&amp;quot;\n&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  for(x=0; x&amp;lt;3; x++) &lt;br /&gt;
     for (y=0; y&amp;lt;5; y++) &lt;br /&gt;
        printf (&amp;quot;Wert: feld[%d][%d] = %d\n&amp;quot;, x, y, feld[x][y]);&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein 3 mal 5 &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array angelegt. &lt;br /&gt;
Dann werden die Werte eingegeben: zuerst &amp;lt;tt&amp;gt;feld[0][0]&amp;lt;/tt&amp;gt;, dann &amp;lt;tt&amp;gt;feld[0][1]&amp;lt;/tt&amp;gt;, usw. bis &amp;lt;tt&amp;gt;feld[2][4]&amp;lt;/tt&amp;gt;. &lt;br /&gt;
Zum Schluß werden alle Werte noch einmal ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===Strukturen===&lt;br /&gt;
In C können Sie sogenannte &amp;quot;Strukturen&amp;quot; definieren. Dabei handelt es sich um eine Zusammenfassung mehrerer Datentypen zu einem größeren. Im Unterschied zu Feldern können in Strukturen unterschiedliche Datentypen zusammengestellt und gespeichert werden: &lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 struct {{Bezeichner}}&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 {{comment|Definition der Struktur 'Person'}}&lt;br /&gt;
 struct Person &lt;br /&gt;
 {&lt;br /&gt;
    int id;&lt;br /&gt;
    char vname[20], nname[20];&lt;br /&gt;
    char telnr[15];&lt;br /&gt;
    int alter;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;lt;tt&amp;gt;struct Person {&amp;lt;/tt&amp;gt;&amp;quot; leitet die Definition der Struktur mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;Person&amp;lt;/tt&amp;gt;&amp;quot; ein. &lt;br /&gt;
Dann werden in dieser Struktur fünf Komponenten definiert: drei Strings und zwei &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. &lt;br /&gt;
mit &amp;lt;tt&amp;gt;}&amp;lt;/tt&amp;gt; wird die Definition abgeschlossen. Sie haben damit einen Datentyp erstellt. Um eine Variable des Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach an&lt;br /&gt;
 struct Person {{Bezeichner}};&lt;br /&gt;
&lt;br /&gt;
Zum Zugriff auf eine Komponente der Struktur gibt man den Namen der Struktur-Variablen an (im folgenden Beispiel also &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;klaus&amp;lt;/tt&amp;gt;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
 {{comment|Definition zweier Struktur-Variablen}}&lt;br /&gt;
 struct Person hubert, klaus;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Zugriff auf Struktur-Komponenten}}&lt;br /&gt;
 hubert.alter = 32;&lt;br /&gt;
 klaus.alter = hubert.alter + 1;&lt;br /&gt;
&lt;br /&gt;
===Unions===&lt;br /&gt;
Eine Union wird ganz analog zu einer Struktur deklariert und verwendet. Sie unterscheidet sich von einer Struktur jedoch dadurch, daß ihre Elemente nicht nacheinander im Speicher abgelegt werden, sondern sich überlagern. Auf die in einer Union enthaltenen Daten gibt es also verschiedene Sichten: je nachdem, welche Sicht bzw. Interpretation der Daten man gerne hätte, wählt man den gewünschten Zugriff.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
union Daten &lt;br /&gt;
{&lt;br /&gt;
   int id;&lt;br /&gt;
&lt;br /&gt;
   struct Person u_person;&lt;br /&gt;
&lt;br /&gt;
   struct u_double&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      double wert;&lt;br /&gt;
   };&lt;br /&gt;
&lt;br /&gt;
   struct u_pointer&lt;br /&gt;
   {&lt;br /&gt;
      int id;&lt;br /&gt;
      union Daten * p1;&lt;br /&gt;
      union Daten * p2;&lt;br /&gt;
   };&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
union Daten data;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies definiert eine Union mit den vier Zugriffsmöglichkeiten &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_double&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Größe der Union richtet sich dabei nach der grössten Komponente. In diesem Beispiel sind alle Komponenten so angelegt worden, daß sie an erster Stelle ein &amp;lt;tt&amp;gt;int id&amp;lt;/tt&amp;gt; enthalten. In &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; könnte man sich also merken, wie die Daten in der Union zu interpretieren sind. Würde &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; nicht dieses &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; enthalten, so würde sich &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; mit &amp;lt;tt&amp;gt;data.u_person.vname&amp;lt;/tt&amp;gt; überlagern. Ein Ändern der ersten Buchstaben von &amp;lt;tt&amp;gt;vname&amp;lt;/tt&amp;gt; hätte also ein Ändern von &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; zur Folge, und man könnte es nicht mehr als Merker verwenden. Mit diesem Feld überlagert das &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; die &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;-Felder der anderen Sichten, z.B. ist &amp;lt;tt&amp;gt;data.id&amp;lt;/tt&amp;gt; der selbe Zugriff wie auf &amp;lt;tt&amp;gt;data.u_person.id&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein anderes Beispiel ist eine Union, die es ermöglicht, auf die einzelnen Bytes eines &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; zuzugreifen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef union&lt;br /&gt;
{&lt;br /&gt;
   unsigned long  as_long;&lt;br /&gt;
   unsignen short as_short[2];&lt;br /&gt;
   unsignen char  as_byte[4];&lt;br /&gt;
} data32_t;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dies überlagert einen &amp;lt;tt&amp;gt;unsigned long&amp;lt;/tt&amp;gt; &amp;amp;ndash; also eine 32-Bit-Zahl &amp;amp;ndash; mit vier Bytes bzw. zwei Shorts.&lt;br /&gt;
 data32_t wert;&lt;br /&gt;
 &lt;br /&gt;
 wert.as_long = 0x12345678;&lt;br /&gt;
 wert.as_byte[0] = 0xab;&lt;br /&gt;
 {{comment|nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform)}}&lt;br /&gt;
&lt;br /&gt;
==Eigene Datentypen==&lt;br /&gt;
&lt;br /&gt;
=Variablen=&lt;br /&gt;
Eine Variable ist ein Synonym (=anderer Name) für eine Speicherstelle in einem Computer. Einfacher gesagt, eine Variable bietet Raum, um Daten wie Zahlen oder Zeichen zu speichern und wieder zu lesen.&lt;br /&gt;
&lt;br /&gt;
==Variablennamen==&lt;br /&gt;
Ein Variablenname kann zusammengesetzt werden aus den Buchstaben &amp;lt;tt&amp;gt;'''A'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''Z'''&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;'''a'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''z'''&amp;lt;/tt&amp;gt;, den Ziffern &amp;lt;tt&amp;gt;'''0'''&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;'''9'''&amp;lt;/tt&amp;gt;, sowie dem Sonderzeichen &amp;quot;Unterstrich&amp;quot; (underscore) &amp;lt;tt&amp;gt;'''_'''&amp;lt;/tt&amp;gt;. Dabei darf an erster Stelle keine Ziffer stehen. Die Bezeichner &amp;lt;tt&amp;gt;hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALLO&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Hallo&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;HALL0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;_123&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_HALLO&amp;lt;/tt&amp;gt; sind also alle gültige und unterschiedliche Variablennamen.&lt;br /&gt;
&lt;br /&gt;
==Anlegen von Variablen==&lt;br /&gt;
Um eine Variable verwenden zu können, muss sie zuerst vereinbart (&amp;quot;erzeugt&amp;quot;) werden. Dies wird auch als &amp;quot;''Definition der Variablen''&amp;quot; bezeichnet und geht so: Schreiben Sie zuerst den Datentyp, dann den Namen der Variablen. Zum Schluß kommt noch der Strichpunkt, wie nach jeder C-Anweisung oder Deklaration. Und nicht vergessen: C unterscheidet zwischen  Groß- und Kleinschreibung! &lt;br /&gt;
 int Zahl1, Zahl2;&lt;br /&gt;
 char Zeichen;&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    float gleitZahl;&lt;br /&gt;
    {{comment|Anweisungen}}&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:'''&lt;br /&gt;
In einer Zeile können auch mehrere Variablen gleichen Types vereinbart werden, wenn man ein Komma dazwischen setzt. Variablen können in jedem Block vereinbart werden. Siehe [[#Gültigkeitsbereich|Gültigkeitsbereich]].&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen==&lt;br /&gt;
Man kann einer vereinbarten Variable Werte [[#Zuweisungen|zuweisen]]. Dazu schreibt man zuerst den Variablennamen, ein Gleichheitszeichen &amp;quot;&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;&amp;quot; und anschliessend den zuzuweisenden [[#Ausdrücke|Ausdruck]]. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, zahl2 = 12;&lt;br /&gt;
  char zeichen1 = 'A';&lt;br /&gt;
&lt;br /&gt;
  zahl1 = 52;&lt;br /&gt;
  zeichen1 = zeichen1 + 1; &lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Zuerst werden drei Variablen angelegt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt;: wird gleich bei der Vereinbarung der Wert 12 zugewiesen. &lt;br /&gt;
;&amp;lt;tt&amp;gt;zahl1 = 52&amp;lt;/tt&amp;gt;: Hier wird der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; der Wert 52 zugewiesen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt;: wird um 1 erhöht. Da in der Variablen &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; gespeichert ist, gibt sich ihr neuer Wert aus &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt;. Weil &amp;lt;tt&amp;gt;'A'&amp;lt;/tt&amp;gt; dem Wert 65 entspricht, ist &amp;lt;tt&amp;gt;'A' + 1&amp;lt;/tt&amp;gt; gleich 66, was dem Wert für &amp;lt;tt&amp;gt;'B'&amp;lt;/tt&amp;gt; entspricht.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei float==&lt;br /&gt;
Das funktioniert genau wie bei normale Zuweisungen. Nachkommastellen werden durch einen Punkt abgegrenzt: &lt;br /&gt;
 floatVariable = 3.14;&lt;br /&gt;
Zusätzlich kann eine Zehnerpotenz angegeben werden:&lt;br /&gt;
 floatVariable2 = -1.234E-6;&lt;br /&gt;
Dadurch wird der erst Wert mit 10&amp;lt;sup&amp;gt;&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;6&amp;lt;/sup&amp;gt; multipliziert, der Wert der Variablen ist also &lt;br /&gt;
:&amp;lt;math&amp;gt;-1{,}234\cdot10^{-6} = -0.000001234&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen bei logischen Variablen==&lt;br /&gt;
Wie bereits erwähnt, besitzt C keinen logischen Datentyp. Es müssen also &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; dafür genutzt werden. Die Zuweisung entpricht der Standard-Zuweisung. Wird der Wert 0 zugewiesen, dann ist die Variable &amp;quot;unwahr&amp;quot;, ansonsten ist sie &amp;quot;wahr&amp;quot;. &lt;br /&gt;
 intVariable = !0;   /* entspricht &amp;quot;wahr&amp;quot;   */&lt;br /&gt;
 intVariable = 0;    /* entspricht &amp;quot;unwahr&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
==Konstanten==&lt;br /&gt;
Konstanten können als Variable angesehen werden, die nicht beschrieben, sondern nur gelesen werden können. Ein typisches Beispiel dafür ist die Zahl &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; (rund 3,141592654). Niemand würde in der realen Welt versuchen, ihr einen anderen Wert zuzuweisen. Würde man &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; jedoch wie eine normale Variable anlegen, wäre dies ohne weiteres möglich. Um dies zu verhindern, gibt es das Schlüsselwort &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in C:&lt;br /&gt;
 const {{Type}} {{Bezeichner}} = {{Konstante}};  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Wichtig dabei ist, dass man Konstanten nur bei der Vereinbarung einen Wert zuweisen kann. &lt;br /&gt;
Da Konstanten gewöhnlich im gesamten Programm, zumindest einer Quelldatei genutzt werden, definiert man diese allerdings gewöhnlich außerhalb des main-Blockes entweder am Anfang eines Programmes, oder in einer sogenannten Header-Datei, die per &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; eingebunden wird.&lt;br /&gt;
 const float PI = 3.141592;  {{comment|Zuweisung bei der Defininition der Variablen}}&lt;br /&gt;
&lt;br /&gt;
Es sei jedoch erwähnt, daß auch einer Konstanten nachträglich ein anderer Wert zugewieden werden kann. Im obigen Beispiel könnte mit&lt;br /&gt;
 * ((float*) &amp;amp;PI) = 2;&lt;br /&gt;
der Wert von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; im Nachhinein verändert werden. Es wird die Adresse von &amp;lt;tt&amp;gt;PI&amp;lt;/tt&amp;gt; genommen und diese Adresse durch den Cast in eine ganz normale &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;-Adresse umgewandelt, über welche der Wert geändert wird. Die sei der Vollständigkeit halber erwähnt.&lt;br /&gt;
&lt;br /&gt;
Je nachdem, an welcher Stelle sich das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; bei einer Pointer-Deklaration befindet, markiert es den Pointer als konstant oder das Objekt, auf das dieser Pointer zeigt. Eine häufige Parameterdeklaration in Ausgabe-Funktionen, die einen String erhalten, ist&lt;br /&gt;
 void foo (const char * str, ...);&lt;br /&gt;
Dadurch ist &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; der Zeiger auf eine Zeichenkette, die innerhalt der Funktion nicht verändert wird bzw. verändert werden darf. Eine Zuweisung wie &amp;lt;tt&amp;gt;*str = 'a'&amp;lt;/tt&amp;gt; ergibt also einen Fehler. &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; selbst kann aber sehr wohl verändert werden, etwa mit &amp;lt;tt&amp;gt;str++&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Soll ausgedrückt werden, daß &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; unveränderlich ist, dann so:&lt;br /&gt;
 void foo (char * const str, ...);&lt;br /&gt;
Jetzt wäre eine Änderung des Strings in Ordnung, etwa durch &amp;lt;tt&amp;gt;str[10] = 'a'&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Um sich zu merken, worauf das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; wirkt, trennt man die Deklaration in Gedanken beim&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf: Steht das &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; links vom&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, dann gehört es zum &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, steht es rechts davon, dann gehört es zum Pointer. Natürlich ist es auch denkbar, beides &amp;amp;ndash; also den Zeiger und sein Ziel &amp;amp;ndash; als konstant zu markieren.&lt;br /&gt;
&lt;br /&gt;
==Gültigkeitsbereich==&lt;br /&gt;
In C können mehrere Variablen den gleichen Namen haben, solange eindeutig ist, welche in welchen Block gültig ist. Dabei gelten folgende Regeln: &lt;br /&gt;
&lt;br /&gt;
;Lokale Variablen: sind Variablen, die innerhalb eines Blockes definiert werden. Jede Variable ist nur in dem Block gültig, in dem sie vereinbart wurde, sowie in allen darin enthaltenen Blöcken; es sei denn, in einem Unter-Block wird eine Variable gleichen Namens definiert. Dann bezieht sich in diesem Unter-Block der Bezeichner auf die im Unter-Block angelegte Variable.&lt;br /&gt;
;Globale Variablen: werden ausserhalb jedes Blockes definiert und gelten ab der Stelle, an der sie deklariert werden, siehe auch [[#Deklaration und Definition|Deklaration und Definition]]. Wird jedoch in einem Block eine Variable gleichen Namens angelegt, gilt ab hier bis zum Ende des Blocks nicht mehr die globale Variable, sondern die im Block deklarierte. Das Spiel kann man weiterspielen: wird in einem Unter-Block wieder eine namensgleiche Variable angelegt, gilt diese in dem Unterblock.&lt;br /&gt;
&lt;br /&gt;
==Speicherklassen==&lt;br /&gt;
Jede Variable in C gehört zu einer bestimmten Speicherklasse&lt;br /&gt;
;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;: Lokale Variablen sind in aller Regal sogenannte ''automatische Variablen''. Das bedeutet, sie werden automatisch angelegt, wenn ein Block bzw. eine Funktion betreten wird und danach wieder entfernt. Das Schlüsselwort &amp;quot;&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;&amp;quot; wird praktisch nie hingeschrieben, denn lokale Variablen ohne die ausdrückliche Angabe einer Speicherklasse, sind automatisch automatische Variablen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;: Eine externes Symbol ist im ganzen Programm bekannt bzw. in dem Block, in der die Deklaration steht. In unterschiedlichen Blöcken stehende Deklarationen beziehen sich auf das gleiche Symbol! Obgleich das Datum global zugreifbar ist, ist der Gültigkeitsbereich auf den deklarierenden Block begrenzt bzw. auf das deklarierende Quell-Modul, sofern das Symbol ausserhalb jedes Blocks des Moduls deklariert wird. Siehe auch [[#Deklaration und Definition|Deklaration und Definition]].&lt;br /&gt;
;&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;: Die Variable ist im Block gültig bzw. im Quell-Modul (also in der C-Datei, in der die angelegt wurde), wenn sie nicht innerhalb eines Blockes angelegt wurde. Statische Variablen werden nicht in Registern oder im Frame der Funktion angelegt, sondern im selben Speicherbereich, in dem auch die globalen Variablen liegen; Konstanten evtl. auch im Flash. Eine lokale Variable, die als &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; angelegt wird, &amp;quot;überlebt&amp;quot; also das Verlassen des Blocks und hat beim neuerlichen Betreten des Blockes ihren bisherigen Wert. In unterschiedlichen Blöcken angelegte lokale statische Variablen beziehen sich auf unterschiedliche Speicherstellen, genau wie bei lokalen Variablen auch.&lt;br /&gt;
;&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;: Durch diese Speicherklasse wird eine Variable &amp;amp;ndash; falls möglich &amp;amp;ndash; als Registervariable angelegt, also in einem Maschinenregister des Computer/Controllers gehalten. Dadurch kann auf solche Variablen besonders schnell zugegriffen werden. Dieses Schlüsselwort ist bei modernen Compilern weitgehend überflüssig, da die entsprechenden Optimierungen selbständig vorgenommen werden, wenn ausreichend Register vorhanden sind. Auch globale Variablen können als Register angelegt werden, davon ist dem Anfänger aber dringend abzuraten, weil leicht schwerauffindbare Fehler und Abstürze auftreten, wenn man nicht genau weiss, welche Implikationen in einer solchen Definition stecken!&lt;br /&gt;
;&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;: (FIXME: volatile ist ein Qualifier und keine Speicherklasse) Dies ist das genaue Gegenteil von &amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt; und bewirkt, dass die Variable auf keinen Fall in einem Register zwischengespeichert werden darf, sondern immer aus dem RAM gelesen und ins RAM geschrieben werden soll. &amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt; müssen alle ''globalen'' Variablen markiert werden, die in [[ISR | Interrupt-Handlern]] verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Ausdrücke=&lt;br /&gt;
Eine Variable oder eine Konstante in C stellen einfache Ausdrücke dar.&lt;br /&gt;
Diese elementaren Ausdrücke können durch Operatoren miteinander verknüpft werden und so zu neuen, komplexeren Ausdrücken zusammen gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Einfache Beispiele für Ausdrücke sind also z.B.:&lt;br /&gt;
 1&lt;br /&gt;
 a&lt;br /&gt;
 'a'&lt;br /&gt;
 1 + a&lt;br /&gt;
 a == 1&lt;br /&gt;
&lt;br /&gt;
Auch Funktionen können einen Wert zurückliefern und in Ausdrücken weiter benutzt werden.&lt;br /&gt;
In den folgenden Abschnitten wird gezeigt, welche Operatoren in C vorhanden sind,&lt;br /&gt;
und wei man damit neue Ausdrücke aufbauen kann.&lt;br /&gt;
&lt;br /&gt;
==Lvalues==&lt;br /&gt;
&lt;br /&gt;
Ein Lvalue in C ist ein Ausdruck, dem ein anderer Ausdruck zugewiesen werden kann, dessen Wert also durch eine Zuweisung verändert werden kann.&lt;br /&gt;
das 'L' leitet sich ab von 'left' bwz. 'links' und das 'value' bedeutet Wert: Ein Lvalue ist ein Ausdruck, der auf der linken Seite einer Zuweisung stehen darf. Ein Lvalue ist also immer auch ein gültiger Ausdruck, aber die Umkehrung gilt in alles Regel nicht.&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für einen Lvalue ist eine &amp;quot;normale&amp;quot; Variable, die nicht mit &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; als Konstante markiert ist:&lt;br /&gt;
 a = 1;&lt;br /&gt;
Hingegen ist der Ausdruck &amp;lt;tt&amp;gt;a+1&amp;lt;/tt&amp;gt; kein Lvalue, denn eine Zuweisung wie&lt;br /&gt;
 a+1 = 2;&lt;br /&gt;
die mathematisch durchaus sinnvoll ist, erzeugt einen Compilerfehler, der etwa lauten könnte &amp;quot;illegal lvalue in assignment&amp;quot;:&lt;br /&gt;
&amp;quot;ungültiger Wert in Zuweisung&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Andere Beipiele für Lvalues sind die Komponenten von (nicht-konstanten) [[#Strukturen|Strukturen]] und [[#Unions|Unions]], [[#Arrays|Array]]-Elemente und die Dereferenzierungen von Pointern: Die Konstante&amp;amp;nbsp;4 wird durch den Cast in eine Adresse umgewandelt. Über die Dereferenzierung&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; wird an die Adresse&amp;amp;nbsp;4 im Speicher eine&amp;amp;nbsp;3 geschrieben. Ob das erlaubt bzw. sinnvoll ist, ist abhängig von der jeweiligen Architektur.&lt;br /&gt;
 * ((unsigned int *) 4) = 3;&lt;br /&gt;
Hier ist der gesamte &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;-Ausdruck ein Lvalue&lt;br /&gt;
&lt;br /&gt;
==Logische (boolsche) Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp;amp;&amp;amp;amp; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wahr oder &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; wahr&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; || gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; || ungleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;= b&amp;lt;/tt&amp;gt; || kleiner oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt; b&amp;lt;/tt&amp;gt; || kleiner als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt;= b&amp;lt;/tt&amp;gt; || glösser oder gleich&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;gt; b&amp;lt;/tt&amp;gt; || grösser als&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; || wahr, wenn &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; nicht wahr und vice versa&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine interessante Eigenschaft der Operatoren &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;amp;amp;&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; ist, dass&lt;br /&gt;
sie die Auswertung abbrechen, sobald das Ergebnis feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet. Ein oft anzutreffendes Codestück sieht so aus, dabei sei &amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
  if (p &amp;amp;&amp;amp; *p == 5)&lt;br /&gt;
  {&lt;br /&gt;
     {{comment|mach was}}&lt;br /&gt;
  }&lt;br /&gt;
Zuerst wird in der Bedinung geprüft, ob Zeiger&amp;amp;nbsp;&amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; einen Wert ungleich Null hat, also ob er überhaupt einen gültigen Wert enthält. Es ist weit verbreitete Konvention in C, daß Zeiger, die keinen gültigen Wert haben, die Adresse&amp;amp;nbsp;0 enthalten. '''Nur dann, wenn ein Zeiger nicht ein Null-Pointer ist, darf überhaupt ein Zugriff über ihn erfolgen!'''&lt;br /&gt;
&lt;br /&gt;
==Vergleich von Variablen==&lt;br /&gt;
Skalare Variablen (also ganze Zahlen, Gleitkommazahlen, Zeiger) können miteinander verglichen werden. Dazu gibt es die folgenden Operatoren in C: &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; || ist nicht gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;lt;=&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;gt;=&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das Ergebnis der Auswertung ist eine ganze Zahl. Ist die Bedingung erfüllt, dann ist der Wert ungleich&amp;amp;nbsp;0. Ist die Bedingung nicht erfüllt, dann ist ihr Wert gleich&amp;amp;nbsp;0.&lt;br /&gt;
Meistens wird man diese Operatoren in &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Konstrukten finden wie zum Beispiel&lt;br /&gt;
 if (x &amp;gt;= 10)&lt;br /&gt;
    x = 10;&lt;br /&gt;
oder in Abbruchbedingungen von Schleifen, wie sie weiter unten erklärt werden.&lt;br /&gt;
&lt;br /&gt;
Es ist auch möglich, das Ergebnis der Auswertung in einer &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Variablen zu speichern:&lt;br /&gt;
 int i;&lt;br /&gt;
 int z1, z2;&lt;br /&gt;
 &lt;br /&gt;
 z1 = 5;&lt;br /&gt;
 z2 = 100;&lt;br /&gt;
 i = z1 &amp;lt;= z2;  {{comment|Ein Vergleich. i wird &amp;quot;wahr&amp;quot;, da z1 kleinergleich z2 ist}}&lt;br /&gt;
&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich&amp;amp;nbsp;0 (&amp;quot;wahr&amp;quot;), wenn &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; kleiner oder gleich &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt; ist. Ist &amp;lt;tt&amp;gt;z1&amp;lt;/tt&amp;gt; jedoch größer als &amp;lt;tt&amp;gt;z2&amp;lt;/tt&amp;gt;, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich&amp;amp;nbsp;0 (&amp;quot;unwahr&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
==Arithmetische Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a + b&amp;lt;/tt&amp;gt; || Summe (Addition)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a - b&amp;lt;/tt&amp;gt; || Differenz (Subtraktion)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a * b&amp;lt;/tt&amp;gt; || Produkt (Multiplikation)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a / b&amp;lt;/tt&amp;gt; || Quotient (Division, evtl. mit Rest)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a % b&amp;lt;/tt&amp;gt; || Rest bei Division (Modulo)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;-a&amp;lt;/tt&amp;gt; || Vorzeichenumkehr (Zweierkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Bit-Operatoren==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;amp; b&amp;lt;/tt&amp;gt; || bitweise und (and)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; b&amp;lt;/tt&amp;gt; || bitweise oder (or)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a ^ b&amp;lt;/tt&amp;gt; || bitweise exclusiv-oder (xor, exor)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;~a&amp;lt;/tt&amp;gt; || jedes Bit in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; invertieren (not, Einerkomplement)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
==Index-Operator bei Arrays==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a[b]&amp;lt;/tt&amp;gt; || das (b+1)ste Element des Feldes a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Folgendes gilt es bei der Verwendung des Indexoperators zu beachten:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; muss ein [[C-Tutorial#Felder | Feld]] oder [[C-Tutorial#Zeiger | Zeiger]] sein&lt;br /&gt;
# &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; muss ein Integer sein oder ein Datentyp, der sich in einen int umwandeln läßt (z.B. char)&lt;br /&gt;
# Es wird nicht geprüft, ob der Index &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; im Feld &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gültig ist!&lt;br /&gt;
# Der erste Index eines Feldes ist immer 0. Daher ''(b+1)stes Element'' in der Beschreibung&lt;br /&gt;
&lt;br /&gt;
==Komponenten-Auswahl bei Structs und Unions==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;a.b&amp;lt;/tt&amp;gt; || Element b der [[C-Tutorial#Strukturen | Struktur]] oder des Unions a&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adress-Operator und Dereferenzierung==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|Ausdruck ||Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&amp;amp;amp;a&amp;lt;/tt&amp;gt; || Speicheradresse der Variablen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;*a&amp;lt;/tt&amp;gt; || Wert, der an der Adresse &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;tt&amp;gt;a-&amp;amp;gt;b&amp;lt;/tt&amp;gt; || Wert des Elements &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; der Struktur, deren Adresse in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; steht&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Adressoperator &amp;amp; kann auf Variablen angewendet werden und&lt;br /&gt;
gibt die Startadresse der Variablen im Speicher zurück.&lt;br /&gt;
&lt;br /&gt;
Handelt es sich bei einer Variable um einen [[C-Tutorial#Zeiger | Zeiger]], so enthält&lt;br /&gt;
sie eine Speicheradresse. Um an den '''Wert''' zu gelangen, der&lt;br /&gt;
an dieser Adresse steht, wird der Operator * vorangestellt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
&lt;br /&gt;
 {{comment|x ist eine Integervariable und hat den Wert 5}}&lt;br /&gt;
 int x = 5;&lt;br /&gt;
     &lt;br /&gt;
 {{comment|z ist ein Zeiger auf eine Integer-Variable und enthaelt somit}}&lt;br /&gt;
 {{comment|die Speicheradresse einer Integer-Variablen}}&lt;br /&gt;
 int *z;       &lt;br /&gt;
  &lt;br /&gt;
 {{comment|Verwendung des Adress-Operators: weist an z die Adresse von x zu}}&lt;br /&gt;
 z = &amp;amp;x;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Verwendung der Dereferenzierung}}&lt;br /&gt;
 {{comment|erhoehe den Wert, der bei Adresse z steht, um eins}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
 &lt;br /&gt;
 {{comment|da z auf x zeigt, hat x jetzt den Wert 6}}&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff auf Struktir- und Union-Elemente eine abkürzende Schreibweise möglich:&lt;br /&gt;
&lt;br /&gt;
Statt &lt;br /&gt;
  (*strukturZeiger).element&lt;br /&gt;
kann geschrieben werden&lt;br /&gt;
  strukturZeiger-&amp;gt;element&lt;br /&gt;
Beide Schreibweisen sind absolut gleichbedeutend, die Klammern bei der ersteren sind notwendig.&lt;br /&gt;
&lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
:Bei der Dereferenzierung durch &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; findet keine Prüfung statt, ob der Zeiger auch auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu einer Änderung '''irgendeiner''' Speicherstelle!&lt;br /&gt;
&lt;br /&gt;
 int *z; {{comment|z ist ein Zeiger auf einen int}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.}}&lt;br /&gt;
 {{comment|z enthaelt irgendeine ungueltige Adresse!!}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|&amp;quot;Erhoehe einen Integer _irgendwo_ im Speicher um 1&amp;quot; -&amp;gt; CRASH !!!}}&lt;br /&gt;
 *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
&lt;br /&gt;
==Cast-Operator==&lt;br /&gt;
&lt;br /&gt;
Der Cast Operator dient dazu, den Datentyp eines Wertes zu ändern. Dafür wird einfach der neue Datentyp in Klammern vor den Wert geschrieben.&lt;br /&gt;
&lt;br /&gt;
Um zum Beispiel aus einem Float ein Integer zu machen:&lt;br /&gt;
 var  = (int) 5.60;&lt;br /&gt;
Dabei wird der Wert aber auch gerundet, und es findet somit ein Informationsverlust statt.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Umwandeln einer ganzen Zahl in eine Adresse:&lt;br /&gt;
 int * addr;&lt;br /&gt;
 addr = (int*) 0x1234;&lt;br /&gt;
Damit ist &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ein Zeiger auf einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; an Adresse 0x1234.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
Der Cast-Operator selbst führt ''keine Konvertierung'' von Darstellungen durch, etwa die Umwandlung der ganzen Zahl 123 ein den String &amp;lt;tt&amp;gt;&amp;quot;123&amp;quot;&amp;lt;/tt&amp;gt;, der diese Zahl darstellt! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
  int main(int argc, char ** argv)&lt;br /&gt;
  {&lt;br /&gt;
        char text[] = &amp;quot;5.6&amp;quot;;&lt;br /&gt;
        int zahl = (int) text;&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, zahl);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Anfangsadresse des Strings &amp;lt;tt&amp;gt;&amp;quot;5.6&amp;quot;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Komma-Operator==&lt;br /&gt;
Mit einem &amp;lt;tt&amp;gt;,&amp;lt;/tt&amp;gt; können mehrere Ausdrücke nacheinander ausgewertet werden.&lt;br /&gt;
Die Auswertung erfolgt von links nach rechts.&lt;br /&gt;
&lt;br /&gt;
Solche Konstrukte sieht man manchmal in Abfragen wie&lt;br /&gt;
 FILE  *file;&lt;br /&gt;
 if (file = fopen (&amp;quot;foo.exe&amp;quot;, &amp;quot;r&amp;quot;), file != NULL)&lt;br /&gt;
was erst an &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; einen Wert zuweist und den &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Block nur betritt,&lt;br /&gt;
wenn &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; nicht der Nullpointer ist.&lt;br /&gt;
&lt;br /&gt;
Bequem kann das auch in einer [[#for-Schleife|for-Schleife]] sein, wenn man zwei (oder mehr) Laufvariablen hat oder so:&lt;br /&gt;
 for (i=0, j=0; i &amp;lt; 10; i++, j += 2)&lt;br /&gt;
    &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&lt;br /&gt;
&lt;br /&gt;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Zuweisung===&lt;br /&gt;
=== ++ und -- ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; stellen einfachere Schreibweisen dar zum Addieren bzw. Subtrahieren von&amp;amp;nbsp;1.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; (Inkrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo++; &lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo + 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; 3}}&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; (Dekrementieren)'''&lt;br /&gt;
 int foo = 1; &lt;br /&gt;
 foo--;&lt;br /&gt;
 {{comment|entspricht}}&lt;br /&gt;
 foo = foo - 1;&lt;br /&gt;
 {{comment|jetzt ist foo &amp;amp;#61; -1}}&lt;br /&gt;
&lt;br /&gt;
Die beiden Operatoren können sowohl in der Präfix-Schreibweise (vor der Variablen) als auch als Postfix-Schreibweise (hinter der Variablen) notiert werden. &lt;br /&gt;
Der Unterschied liegt darin, dass beim Präfix der Wert zuerst neu berechnet wird und die Variable dann verwendet wird. Beim Postfix wird die Variable zuerst verwendet und erst nach Auswertung des Ausdrucks, in dem sie enthalten ist, neu berechnet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 int ausgabe1, ausgabe2, var1 = 10, var2 = 10;&lt;br /&gt;
 ausgabe1 = 3 * ++var1; {{comment|ausgabe1 &amp;amp;#61; 33; var1 &amp;amp;#61; 11;}}&lt;br /&gt;
 ausgabe2 = 3 * var2++; {{comment|ausgabe2 &amp;amp;#61; 30; var2 &amp;amp;#61; 11;}}&lt;br /&gt;
&lt;br /&gt;
Für Zeiger arbeiten diese Operatoren etwas anders, siehe dazu [[#Zeiger-Arithmetik|Zeiger-Arithmetik]].&lt;br /&gt;
&lt;br /&gt;
===Bedingter Ausdruck===&lt;br /&gt;
 ({{Bedingung}}) ? {{Ausdruck|1}} : {{Ausdruck|2}}&lt;br /&gt;
Wenn &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; erfüllt ist, dann wertet dieser Ausdruck aus zu &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt;. Ist er nicht erfüllt, dann wertet er aus zu &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 x = (x &amp;gt;= 3) ? 0 : x+1;&lt;br /&gt;
Startet man &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; mit dem Wert 0, dann nimmt es bei mehrfacher Anwendung dieser Zeile (z.B. in einer Schleife) nacheinander die folgende Werte an:&lt;br /&gt;
:&amp;lt;tt&amp;gt;1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, ...&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
Eine Kontrollanweisung ist eine Anweisung, die Einfluss auf den Programmfluss hat. Normalerweise werden Anweisungen so ausgeführt, wie sie in der Quelldatei stehen: Von links nach rechts (falls mehrere Anweisungen in einer Zeile stehen sollten, wovon i.A. abzuraten ist) und von oben nach unten. Mit einer Kontrollanweisung kann dieser lineare Programmfluss durchbrochen werden: Die Codeausführung kann kann abhängig von einer Bedingung gemacht werden (&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;), kann wiederholt werden (Schleife) oder an einer anderen Stelle der Funktion fortgesetzt werden (&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==if-Anweisung==&lt;br /&gt;
Mit Hilfe des if-Befehls kann man Codeteile abhängig davon einer Bedingung ausführen lassen:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
oder mit else-Teil&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 if (x &amp;gt; 100)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;gt; 100 ist: Fehlerausgabe}}&lt;br /&gt;
    printf (&amp;quot;x = %d ist zu gross fuer die Berechnung!\n&amp;quot;, x);&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|falls x &amp;lt;&amp;amp;#61; 100 ist: Berechne Summe der Zahlen 1...x}}&lt;br /&gt;
    {{comment|Die lokale Variable x2 lebt nur innerhalb dieses alse-Blocks}}&lt;br /&gt;
    int x2 = x;&lt;br /&gt;
 &lt;br /&gt;
    for (x = 0; x2 &amp;gt; 0; x2--)&lt;br /&gt;
       x += x2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Wenn die Bedingung wahr ist (&amp;lt;tt&amp;gt;x &amp;gt; 100&amp;lt;/tt&amp;gt;), dann wird eine Meldung ausgegeben; danach ist die if-Anweisung beendet. Der else-Block wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung nicht erfüllt (&amp;lt;tt&amp;gt;x &amp;amp;le; 100&amp;lt;/tt&amp;gt;), dann wird gleich zum else-Teil gesprungen, und nach dessen Ausführung der if-Befehl beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Ein häufiger Fehler ist es, statt &amp;lt;tt&amp;gt;if (a &amp;amp;#61;&amp;amp;#61; 23)&amp;lt;/tt&amp;gt; etwas wie &amp;lt;tt&amp;gt;if (a &amp;amp;#61; 23)&amp;lt;/tt&amp;gt; zu schreiben. &lt;br /&gt;
Dann wird allerdings nicht geprüft, ob die Variable&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; gleich 23 ist, sondern der Variablen&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; wird der Wert 23 zugewiesen. Der Ausdruck &amp;lt;tt&amp;gt;a &amp;amp;#61; 23&amp;lt;/tt&amp;gt; hat den Wert&amp;amp;nbsp;23 und ist damit immer &amp;quot;wahr&amp;quot;! Daher ist diese if-Bedingung immer erfüllt!&lt;br /&gt;
&lt;br /&gt;
Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken sondern bestenfalls eine Warnung. Damit ist dieser Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise &amp;lt;tt&amp;gt;if (23 &amp;amp;#61;&amp;amp;#61; a)&amp;lt;/tt&amp;gt;. Wenn man dort anstatt des Vergleichsoperators '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;amp;#61;&amp;lt;/tt&amp;gt;' den Zuweisungsoperator '&amp;lt;tt&amp;gt;&amp;amp;#61;&amp;lt;/tt&amp;gt;' verwendet, spuckt der Compiler sehr wohl einen Fehler aus! Ist die Zuweisung jedoch erwünscht und eine Compiler-Warnung lästig, dann wählt man eine Schreibweise wie &amp;lt;tt&amp;gt;if ((a &amp;amp;#61; b))&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;if (a &amp;amp;#61; b, a)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist zu schreiben &amp;lt;tt&amp;gt;if (Bedingung);&amp;lt;/tt&amp;gt; Richtig muss es heissen &amp;quot;&amp;lt;tt&amp;gt;if(Bedingung)&amp;lt;/tt&amp;gt;&amp;quot; Das Semikolon im ersten Fall ist eine leere Anweisung, die im if-Falle ausgeführt wird &amp;amp;ndash; sie bleibt also ohne Resultet. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt; ein auf das Semikolon folgende Anweisung die eigentlich zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören soll wird immer ausgeführt, die sie nicht mehr zum &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; dazu gehört.&lt;br /&gt;
}}&lt;br /&gt;
Bei verschachtelten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Konstrukten gehört ein &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zu letzten &amp;quot;freien&amp;quot; &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;. Soll in einer &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;-Folge das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; zum ersten &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehören, dann ist das so zu hinzuschreiben:&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Ohne die geschweiften Klammern um das zweite &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; gehörte das &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; dort hinzu.&lt;br /&gt;
&lt;br /&gt;
==switch-Anweisung==&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
&lt;br /&gt;
 switch ({{Ausdruck|}}) &lt;br /&gt;
 {&lt;br /&gt;
     case konstante1:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
    &lt;br /&gt;
     case konstante2:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 &lt;br /&gt;
     {{comment|weitere case-Marken}}&lt;br /&gt;
 &lt;br /&gt;
     default:&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         {{Anweisung}}&lt;br /&gt;
         ...&lt;br /&gt;
 } {{comment|Ende von switch}} &lt;br /&gt;
&lt;br /&gt;
Der Ausdruck muss ein skalarer Typ sein, er wird in die nächste ganze Zahl gewandelt und mit den Werten hinter den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Marken verglichen. Bei einer Übereinstimmung werden alle Befehle ab dem zutreffenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; ausgeführt. Stimmt der Ausdruck mit keinem der Werte überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt falls vorhanden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der nachfolgenden &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;- und des &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitts werden ausgeführt, wenn die Anweisungen des &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitts nicht mit dem Befehl &amp;lt;tt&amp;gt;break;&amp;lt;/tt&amp;gt; beendet werden!&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es dürfen beliebig viele &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitte angegeben werden, pro Vergleichswert jedoch nur einer.&lt;br /&gt;
Der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ist optional. Die Reihenfolge, in der &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt; angegeben werden, ist unerheblich.&lt;br /&gt;
&lt;br /&gt;
==Schleifen==&lt;br /&gt;
Um Anweisungen mehrmals hintereinander auszuführen, benötigt man Schleifen. Diese führen Anweisungen aus, bis oder solange Bedingungen erfüllt sind.&amp;lt;br&amp;gt; &lt;br /&gt;
Wichtig ist also, ob die Bedingung '''vor''' oder '''nach''' den Schleifen-Anweisungen geprüft wird. &lt;br /&gt;
&lt;br /&gt;
===while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 while ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Die while-Schleife wird solange durchlaufen, wie die Bedingung erfüllt ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Die Anweisung kann natürlich auch ein Block sein, der aus mehreren Deklarationen und Anweisungen besteht. &lt;br /&gt;
&lt;br /&gt;
 int zahl1 = 0;&lt;br /&gt;
 int zahl2 = 1;&lt;br /&gt;
 &lt;br /&gt;
 while (zahl1 &amp;lt; 3)&lt;br /&gt;
 {&lt;br /&gt;
    zahl1 = zahl1 + 1;&lt;br /&gt;
    zahl2 = zahl2 * 2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife drei mal durchlaufen. Zu Beginn des vierten Durchlaufs ist die Bedingung nicht mehr erfüllt (&amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
&lt;br /&gt;
===do-while-Schleife===&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
Die do-while-Schleife wird auf jeden Fall einmal durchlaufen und dann solange wiederholt, wie die Bedingung erfüllt ist.&lt;br /&gt;
 int i = 2;&lt;br /&gt;
 &lt;br /&gt;
 do &lt;br /&gt;
 {&lt;br /&gt;
     i = i*i;   {{comment|i quadrieren}}&lt;br /&gt;
     printf (&amp;quot;i = %d\n&amp;quot;, i);&lt;br /&gt;
 }&lt;br /&gt;
 while (i &amp;lt; 20);&lt;br /&gt;
&lt;br /&gt;
Die Schleife wird durchlaufen und wiederholt, solange &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; kleiner als 20 ist. Es werden also nacheinander die Werte 2, 4 und 16 ausgegeben. Nach der Schleife hat&amp;amp;nbsp;&amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; den Wert 256.&lt;br /&gt;
&lt;br /&gt;
===for-Schleife===&lt;br /&gt;
'''Syntax:''' &lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
Bei den Ausdrücken wird es sich um einen Ausdrücke mit Nebeneffekt handeln wie etwa &amp;lt;tt&amp;gt;i=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;i=i+2&amp;lt;/tt&amp;gt;. Es werden folgende Aktionen ausgeführt:&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# &amp;lt;tt&amp;gt;Bedingung&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# falls die Bedingung wahr ist, dann führe &amp;lt;tt&amp;gt;Anweisung&amp;lt;/tt&amp;gt; aus.&lt;br /&gt;
# falls die Bedingung unwahr ist, dann sprinte zu 7 (Ende).&lt;br /&gt;
# &amp;lt;tt&amp;gt;Ausdruck2&amp;lt;/tt&amp;gt; wird ausgewertet&lt;br /&gt;
# gehe zu 2&lt;br /&gt;
# nächste Anweisung nach der for-Schleife&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int lauf, summe;&lt;br /&gt;
 &lt;br /&gt;
 for (lauf=1, summe=0; lauf &amp;lt;= 10; lauf += 2) &lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel ist &amp;lt;tt&amp;gt;Ausdruck1&amp;lt;/tt&amp;gt; ein [[#Komma-Operator|Komma-Ausdruck]], der zwei Anweisungen kombiniert und daher sogar zwei Nebeneffente hat: er setzt &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;1 und &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; auf&amp;amp;nbsp;0.&lt;br /&gt;
&lt;br /&gt;
Das Äquivalent als while-Schleife:&lt;br /&gt;
&lt;br /&gt;
 int lauf  = 1;                 {{comment|Anfangswerte}}&lt;br /&gt;
 int summe = 0;&lt;br /&gt;
 &lt;br /&gt;
 while (lauf &amp;lt;= 10)             {{comment|Bedingung}}&lt;br /&gt;
 {&lt;br /&gt;
    summe += lauf;&lt;br /&gt;
    lauf  += 2;                 {{comment|Inkrement}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; in jedem Schleifendurchlauf um die Laufvariable &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; erhöht. Da &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nacheinander die ungeraden Werte von&amp;amp;nbsp;1 bis&amp;amp;nbsp;10 annimmt, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von&amp;amp;nbsp;1 bis kleinergleich 10 gespeichert, also der Wert&amp;amp;nbsp;25. &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; hat nach der Schleife den Wert&amp;amp;nbsp;11.&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf = 1&amp;lt;/tt&amp;gt; bedeutet, dass der Variablen &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; vor dem ersten Schleifendurchlauf der Wert&amp;amp;nbsp;1 zugewiesen wird. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf &amp;lt;= 10&amp;lt;/tt&amp;gt; ist die Schleifenbedingung; ist sie nicht erfüllt, wird die Schleife beendet. &lt;br /&gt;
&amp;lt;tt&amp;gt;lauf += 2&amp;lt;/tt&amp;gt; bedeutet, dass &amp;lt;tt&amp;gt;lauf&amp;lt;/tt&amp;gt; nach jedem Durchlauf um&amp;amp;nbsp;2 erhöht wird.&lt;br /&gt;
&lt;br /&gt;
===continue-Anweisung===&lt;br /&gt;
Innerhalb einer Schleife darf die &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die nachfolgenden Anweisungen übersprungen werden und mit dem nächsten Schleifendurchlauf fortgesetzt wird &amp;amp;ndash; vorausgesetzt die Schleifenbedingung ist noch erfüllt. Ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; etc. stehen, wenn dieses innerhalb einer Schleife steht.&lt;br /&gt;
&lt;br /&gt;
==break-Anweisung==&lt;br /&gt;
Innerhalb einer Schleife oder eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; darf die &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;-Instruktion stehen. Sie bewirkt, daß die Schleifen-/Switch-Anweisung sofort verlassen wird und das Programm dahinter weiter macht. Bei mehrfach geschachtelten Schleifen wird nur die innere verlassen. Ein &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; darf natürlich auch innerhalb eines &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; stehen, wenn dieses innerhalb einer Schleife/Switch-Anweisung steht.&lt;br /&gt;
&lt;br /&gt;
==goto-Anweisung==&lt;br /&gt;
&lt;br /&gt;
Innerhalb ein und derselben Funktion kann mit &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; an eine andere Stelle gesprungen werden. Dazu gibt man hinter dem &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einen Bezeichner an, der dadurch als Label fungiert:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 goto {{Bezeichner}};&lt;br /&gt;
Die Bezeichner selbst steht irgendwo in der Funktion und wird dadurch zur Sprungmarke (Label), daß er von einem Doppelpunkt (und mindestens einer C-Anweisung, die auch leer sein darf) gefolgt wird.&lt;br /&gt;
&lt;br /&gt;
Das Beispiel durchsucht das 2-dimensionale &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;-Array &amp;lt;tt&amp;gt;feld&amp;lt;/tt&amp;gt; mit den &amp;lt;tt&amp;gt;SIZE_X &amp;amp;times; SIZE_Y&amp;lt;/tt&amp;gt; Werten nach dem Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;. Wird er gefunden, dann wird die 2-fach geschachtelte Suchschleife verlassen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 int x, y;&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y; y++)&lt;br /&gt;
       if (feld[x][y] == 0)&lt;br /&gt;
          goto done;&lt;br /&gt;
 {{Label|done:}};&lt;br /&gt;
&lt;br /&gt;
Der folgende Code hat die gleiche Funktion, arbeitet jedoch ohne &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int x, y;&lt;br /&gt;
 int found = 0; {{comment|FALSE}}&lt;br /&gt;
 &lt;br /&gt;
 for (x=0; x &amp;lt; SIZE_X &amp;amp;&amp;amp; !found; x++)&lt;br /&gt;
    for (y=0; y &amp;lt; SIZE_Y &amp;amp;&amp;amp; !found; y++)&lt;br /&gt;
       found = (0 == feld[x][y]);&lt;br /&gt;
Der Nachteil der &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-losen Variante ist, daß man eine Variable, die merkt, ob das Suchziel gefunden wurde, mitschleppen und in ''jedem'' Schleifendurchlauf abtesten muss. Dies bedeutet einen höheren Programmier- und Laufzeitaufwand und ist nicht so klar formuliert wie das &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;-Beispiel.&lt;br /&gt;
&lt;br /&gt;
Gleichwohl sei angemerkt, daß die Verwendung von &amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt; einem gewissen Dogmatismus unterliegt, der sich wie folgt subsummieren liesse:&lt;br /&gt;
:''goto ist böse und sollte keinesfalls verwendet werden! Wer es dennoch tut, offenbart dadurch seinen schlechten Geschmach sowie mangelhafte C-Kenntnis.'' &amp;lt;div align=&amp;quot;right&amp;quot;&amp;gt;http://www.roboternetz.de/phpBB2/images/smiles/icon_wink.gif&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Funktionen=&lt;br /&gt;
Stellen Dir vor, Du hast eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben &amp;amp;ndash; was Dich Zeit beim Erstellen des Programms und Speicherplatz im ausführbaren Programm kostet &amp;amp;ndash; kannst Du den Code-Abschnitt in eine Funktion schreiben und diese von jeder Stelle des Programms aus verwenden. Die Hauptgründe, um Funktionen zu verwenden, sind:&lt;br /&gt;
;Wiederverwendung von Code: Mehrfach verwendete Codestücke müssen nicht mehrfach implementiert werden. Oft unterscheiden sich die Codesequenzen nur in Kleinigkeiten, die man der Funktion über Parameter mitteilen kann.&lt;br /&gt;
;Übersichtlichkeit: Ein gut gegliedertes C-Programm implementiert klar umrissene Aufgaben in einer Funktion, auch wenn diese Funktion nur einmal im Code aufgerufen wird! Dadurch bleibt der Code um die Aufrufstelle besser verständlich, und man kann auf verschiedenen &amp;quot;Ebenen&amp;quot; denken. Eine Funktion wie &amp;quot;Datei öffnen&amp;quot; kann recht komplex sein. Auf höherer Ebene interessieren die Innereien nicht mehr, man möchte sich um andere Dinge kümmern und will den Code an der Stelle garnicht sehen...&lt;br /&gt;
;Rekursive Funktionen: Eine Funktion kann sich auch selbst aufrufen. In dem Falle nennt man die Funktion ''rekursiv''. Zwar lässt sich das, was eine rekursive Funktion tut, auch mit anderen Mitteln formulieren, die keine rekursiven Funktionen brauchen, aber oft ist der rekursive Weg knackiger und klarer formulierbar als eine nicht-rekursiven Ansatz, auch wenn es etwas mehr Resourcen verbraucht.&lt;br /&gt;
;Modulare Programmierung: Funktionen können anhand ihres Aufgabenbereichs auf verschiedene C-Quellen &amp;amp;ndash; sogenannte ''Module'' &amp;amp;ndash; verteilt werden. Funktionen, die etwas mit dem USB-Bus anstellen, werden in einem anderen Modul sein als mathematische Funktionen. Dies erhöht die Übersichtlichkeit und vereinfacht die Entwicklung im Team.&lt;br /&gt;
;Bibliotheken: Standard-Funktionen wie das hier oft auftauchende &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; sind in Bibliotheken gespeichert. Wenn das eigene Programm übersetzt wird, dann müssen nicht mehr alle Standard-Funktionen übersetzt werden, sondern werden nur noch aus der Bibliothek gelesen und ihr Code zum Programm dazugelinkt. Die Bibliotheks-Funktionen wurden schon zu einem früheren Zeitpunkt compiliert und liegen in dieser compilerten Form in der Bibliothek. Das spart mächtig Entwicklungszeit. Man kann auch selbst solche Bibliotheken erstellen und in diversen Projekten wiederverwenden.&lt;br /&gt;
;Generische Programmierung: In C ist es möglich, einer Funktion eine andere Funktion zu übergeben. (Damit ist nicht gemeint, ihr deren ''Rückgabewert'' zu übergeben (was auch ginge), sondern ''die Funktion selbst'' wird als Parameter übergeben und kann aufgerufen werden.) Ein typisches Beispiel dafür sind Sortieralgorithmen. Einem Sortieralgorithmus kann es egal sein, ''was'' er sortiert. Er muss lediglich wissen, ''wie'' er das Zeug zu sortieren hat: aufsteigend, absteigend, als Zahl, in lexikographischer Ordnung, nach der Quersumme, Körper nach Oberfläche, Durchmesser, Gewicht oder Volumen... Diese Vergleichsfunktion, die für zwei Objekte entscheidet, welches davon &amp;quot;kleiner&amp;quot; ist, kann man dem Sortierer übergeben. Will er zwei Werte vergleichen, dann muss er nur die Vergleichsfunktion aufrufen, ohne zu wissen, was diese tut. Damit kann der Sortieralgorithmus unanhängig von den Objekten gehalten werden, mit denen er hantieren soll.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Definition==&lt;br /&gt;
&lt;br /&gt;
In der ''Definition'' der Funktion wird gesagt, welche Werte sie liefern kann, wie sie heisst (Bezeichner) und wieviele und welche Parameter sie hat. Danach folgt ihre Implementierung:&lt;br /&gt;
&lt;br /&gt;
'''Syntax:'''&lt;br /&gt;
 {{Type}} {{Bezeichner}} ({{Parameterliste}})&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
 &lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
Für Funktionen, die keinen Wert zurückliefern, gibt es den speziellen Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der besagt, daß die Funktion nichts zurückgibt. Die einfachste denkbare Funktion ist eine solch void-Funktion. Sie bekommt keine Parameter, gibt nicht zurück und ihr Body ist leer:&lt;br /&gt;
 void dummy()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==return-Anweisung==&lt;br /&gt;
An jeder Stelle des Programmflusses einer Funktion kann diese mit &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; beendet werden.&lt;br /&gt;
&lt;br /&gt;
'''bei void-Funktionen:'''&lt;br /&gt;
 return;&lt;br /&gt;
'''Funktionen mit Rückgabe-Wert:'''&lt;br /&gt;
 return {{Ausdruck|}};&lt;br /&gt;
Die zweite Variante gibt an, welcher Wert zurückgegeben wird.&lt;br /&gt;
 int main (int argc, char * argv[])&lt;br /&gt;
 {&lt;br /&gt;
    if (argc &amp;lt; 2)&lt;br /&gt;
       return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
Falls die letzte Anweisung einer void-Funktion ein &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; ist, kann es auch weggelassen werden wie oben bei der Funktion &amp;lt;tt&amp;gt;dummy&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Aufruf==&lt;br /&gt;
Um die Funktion aufzurufen gibt man ihren Namen an, gefolgt von den durch Komma getrennten Argumenten in runden Klammern wie im Beispiel unten das&lt;br /&gt;
 quadrat (5) &lt;br /&gt;
Da &amp;lt;tt&amp;gt;quadrat&amp;lt;/tt&amp;gt; einen Wert liefert, kann man damit weiter rechnen wie mit einem normalen Ausdruck:&lt;br /&gt;
 if (quadrat (a) + quadrat (b) == quadrat (c))&lt;br /&gt;
    c = quadrat (quadrat (a)); {{comment|c &amp;amp;#61; a hoch 4}}&lt;br /&gt;
&lt;br /&gt;
==Rekursive Funktionen==&lt;br /&gt;
Eine Funktion die sich selbst &amp;amp;ndash; möglicheweise auch über andere Zwischenfunktionen &amp;amp;ndash; wieder selbst aufruft, wird als ''rekursive Funktion'' bezeichnet. In der Definition ist nichts besonderes zu beachten. Ist die Verschachtelungstiefe im laufenden Programm zu tief, dann gibt das natürlich Probleme, aber das gilt bei tief verschachtelten 'normalen' Funktionen abenso...&lt;br /&gt;
&lt;br /&gt;
Das Beispiel berechnet den Größten Gemeinsamen Teiler zweier Zahlen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int ggT (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
     if (0 == a)&lt;br /&gt;
        return b;&lt;br /&gt;
 &lt;br /&gt;
    return ggT (b % a, a);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Ein komplettes kleines Programm:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int quadrat (int param1)&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  zahl = param1 * param1;&lt;br /&gt;
  return zahl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl, ergebnis;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Bitte Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = quadrat (zahl);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, zahl, ergebnis);&lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;, 5, quadrat (5));&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur ausserhalb von Blöcken. Geschachtelte Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen beim Aufruf die Klammern angeben werden:&lt;br /&gt;
 dummy();&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Prototypen==&lt;br /&gt;
Wie oben erwähnt, kann ein Unterprogramm an jeder beliebigen Stelle im Programm stehen. Damit ist jedoch eine Bedingung verknüpft: Das Unterprogramm muß in der Datei oberhalb des ersten Aufrufes definiert worden sein. Wenn Sie ein Unterprogramm in Zeile 10 zum ersten mal aufrufen, müssen Sie die Deklaration davor erledigt haben. Verstanden?&lt;br /&gt;
Um dies zu erreichen, gibt es zwei Möglichkeiten: &lt;br /&gt;
&lt;br /&gt;
Entweder Sie schreiben alle Unterprogramme vor &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; in die Datei. Dies muß jedoch wiederum so geschehen, dass Funktionen zum Zeitpunkt ihres Aufrufes bereits bekannt sind! &lt;br /&gt;
Wo dies nicht möglich ist (z.B. sich gegenseitig aufrufende Unterprogramme), oder wenn Sie das stört, müssen Sie Prototypen verwenden. &lt;br /&gt;
Wie definiert man nun Prototypen? Sie kopieren einfach die erste Zeile des Unterprogrammes (z.B. &amp;quot;&amp;lt;tt&amp;gt;void ausgeben (int zahl)&amp;lt;/tt&amp;gt;&amp;quot;), fügen einen Strichpunkt&amp;amp;nbsp;&amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;an und fügen es an einer geeigneten Stelle ein (so, dass alle Aufrufe später in der Datei kommen). &lt;br /&gt;
Solche Definitionen stehen gewöhnlich am Anfang der Quelldatei oder in einer Header-Datei, die eingebunden wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl);  /* Der Prototyp */&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
   ausgeben (12);&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void ausgeben (int zahl)   /* Die eigentliche Prozedur */&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Ausgabe: %d\n&amp;quot;, zahl);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Parameterübergabe==&lt;br /&gt;
&lt;br /&gt;
Alle Werte, die an Prozeduren und Funktionen übergeben werden, werden grundsätzlich '''kopiert'''.&lt;br /&gt;
Das hat folgende Auswirkungen:&lt;br /&gt;
&lt;br /&gt;
# Änderungen an einem Parameter in einer Funktion erscheinen ''nicht'' beim Aufrufer!&lt;br /&gt;
# Möchte man, dass eine Funktion einen Wert trotzdem dauerhaft ändern soll, so muss die Adresse des Wertes via [[#Zeiger|Zeiger]] übergeben werden.&lt;br /&gt;
# Werden [[#Strukturen|Strukturen]] übergeben, so wird von ihnen eine Kopie erstellt, was bei großen Strukturen viel Zeit und Arbeitsspeicher kostet. Deshalb wird häufig nur die Adresse von Strukturen übergeben, da die Adresse viel schneller und platzsparender als die Struktur selbst kopiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele:'''&lt;br /&gt;
 void erhoehe (int x)&lt;br /&gt;
 {&lt;br /&gt;
    x = x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main (void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe(a);&lt;br /&gt;
    {{comment|a ist immer noch 0}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Beim Aufruf von &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; wird eine Kopie des Wertes von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; (im Beispiel also 0) erstellt und der Prozedur als Parameter &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; übergeben. Weil dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat dies keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|erhoehe den Wert an der Adresse x um eins}}&lt;br /&gt;
    *x = *x + 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    int a = 0;&lt;br /&gt;
    erhoehe (&amp;amp;a);&lt;br /&gt;
    {{comment|a ist jetzt 1}}&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Jetzt wird im Hauptprogramm mittels [[#Adress-Operator und Dereferenzierung|Adress-Operator]] &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; die Speicheradresse von &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; bestimmt. Dann wird eine ''Kopie der Adresse'' an das Unterprogramm &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; übergeben. Jetzt kennt das Unterprogramm die&lt;br /&gt;
Adresse des Originals &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und kann direkt mit dem Inhalts-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&lt;br /&gt;
'''Besonderheit bei Feldern'''&lt;br /&gt;
&lt;br /&gt;
Bei der Übergabe von [[#Felder|Feldern]] gibt es eine Besonderheit. Schreibt man nämlich den Namen eines Feldes, so ist das nichts anderes als die '''Speicheradresse des ersten Elements'''.&lt;br /&gt;
Bei der Übergabe eines Feldes wird also eine Kopie der Startadresse übergeben. Somit kann das Unterprogramm auf den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel:'''&lt;br /&gt;
 void erhoehe (int x[])&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
   int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
   erhoehe (a);&lt;br /&gt;
   {{comment|a hat jetzt folgenden Inhalte: 11, 23, 35}}&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Dass die Übergabe einer Adresse erfolgt, sieht man an folgendem Beispiel, das von der Funktionsweise '''absolut identisch''' mit dem vorhergehenden ist:&lt;br /&gt;
&lt;br /&gt;
 {{comment|Bei Parametern gibt es keinen Unterschied zwischen Zeiger und Feld}}&lt;br /&gt;
 void erhoehe (int *x)&lt;br /&gt;
 {&lt;br /&gt;
    x[0] = x[0] + 1;&lt;br /&gt;
    x[1] = x[1] + 3;&lt;br /&gt;
    x[2] = x[2] + 5;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
    int a[] = {10, 20, 30};&lt;br /&gt;
   &lt;br /&gt;
    erhoehe (a);&lt;br /&gt;
 &lt;br /&gt;
    {{comment|a hat jetzt folgenden Inhalt: 11, 23, 35}}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
Die Länge des Feldes wird nicht automatisch übergeben. Dafür ist ggf. ein zusätzlicher Parameter notwendig.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Variable Argumentanzahl==&lt;br /&gt;
== Funktionen indirekt aufrufen ==&lt;br /&gt;
Siehe [[#Zeiger auf Funktionen|Zeiger auf Funktionen]]&lt;br /&gt;
&lt;br /&gt;
=Zeiger II=&lt;br /&gt;
&lt;br /&gt;
Zeiger haben wir bereits weiter oben kennen gelernt. Zeiger sind ein zentrales Konzept in C und sollen hier etwas eingehender behandelt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger-Arithmetik==&lt;br /&gt;
In C kann man den Wert eines Zeigers verändern. Betrachten wir dazu die Funktion &amp;lt;tt&amp;gt;suche_0&amp;lt;/tt&amp;gt;, die einen Zeiger auf einen &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; erhält. Die Funktion soll ab der gegebenen Adresse nach dem ersten long-Wert suchen, der 0 ist, und dessen Adresse zurückgeben:&lt;br /&gt;
 long * suche_0 (long * addr)&lt;br /&gt;
 {&lt;br /&gt;
    while (*addr != 0)&lt;br /&gt;
       addr = addr + 1;&lt;br /&gt;
 &lt;br /&gt;
    return addr;&lt;br /&gt;
 }&lt;br /&gt;
In der Bedingung der while-Schleife wird der Inhalt an der Speicherstelle &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf 0 getestet. Ist der Wert 0, dann wird die Schleife beendet und die Adresse zurückgeliefert. Ist der Wert ungleich 0, dann wird &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; auf den nächste long gesetzt, &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; also um 4 Bytes weitergezählt. &amp;lt;tt&amp;gt;addr&amp;lt;/tt&amp;gt; ist ja ein Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, und ein &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; ist 4 Bytes lang.&lt;br /&gt;
&lt;br /&gt;
Die Bedeutung von&lt;br /&gt;
 address + n&lt;br /&gt;
ist also, die Adresse um das &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;-fache der Größe des Typs, auf den &amp;lt;tt&amp;gt;address&amp;lt;/tt&amp;gt; zeigt, zu erhöhen. Dabei ist &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; eine ganze Zahl und darf auch negativ sein.&lt;br /&gt;
&lt;br /&gt;
Hier noch ein Beispiel einer Funktion, die nach einer Person mit einer bestimmten ID sucht (für die Definition von &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; siehe [[#Strukturen|Strukturen]]). Der Parameter &amp;lt;tt&amp;gt;person&amp;lt;/tt&amp;gt; ist dabei ein Array von Strukturen. Eine Person mit der gesuchten ID muss existieren, ansonsten hat die Suchfunktion kein definiertes Verhalten.&lt;br /&gt;
 {{comment|Sucht nach einer Person mit der ID person_id}}&lt;br /&gt;
 struct Person * &lt;br /&gt;
 suche_person_id (struct Person * person, int person_id)&lt;br /&gt;
 {&lt;br /&gt;
    while (person-&amp;gt;id != person_id)&lt;br /&gt;
       person++;&lt;br /&gt;
 &lt;br /&gt;
    return person;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:1em; padding:1em; border:solid 2px #FF0040;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- Vorlage:FarbigerRahmen funzt hier net --&amp;gt;&lt;br /&gt;
Beachte, daß es nicht sinnvoll ist, zwei Zeiger zu addieren oder zu multiplizieren. Ausserdem ist das &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt; der Zeiger-Arithmetik nicht kommutativ. Eine Zeiger auf &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;, der an Adresse 1 im Speicher zeigt, wird man schreiben als&lt;br /&gt;
 (long *) 1&lt;br /&gt;
Addiert man darauf eine ganze Zahl, dann haben die entstehenden Ausdrücke unterschiedliche Werte:&lt;br /&gt;
 (long *) 1 + 2    {{comment|zeigt zu Adresse 9}}&lt;br /&gt;
 (long *) 2 + 1    {{comment|zeigt zu Adresse 6}}&lt;br /&gt;
 (long *) (1 + 2)  {{comment|zeigt zu Adresse 3}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==void-Pointer==&lt;br /&gt;
Eine besondere Art von Zeiger ist der void-Pointer&lt;br /&gt;
 void * addr;&lt;br /&gt;
Ein void-Pointer ist ein &amp;quot;Zeiger auf irgendwas&amp;quot;, dementsprechend kann er nicht dereferenziert werden, Anwenden von &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf einen solchen Zeiger gibt also einen Fehler. Ausserdem ist es nicht möglich, mit einem void-Pointer Zeigerarithmetik zu machen, weil er nicht auf eine definierte Art von Objekt zeigt. Der Vorteil eines void-Pointers ist, daß er jede Art von Zeiger aufnehmen kann.&lt;br /&gt;
&lt;br /&gt;
Dazu betrachten wir die Funktion &amp;lt;tt&amp;gt;send_buf&amp;lt;/tt&amp;gt;, die eine Adresse erhält und ab dieser Adresse &amp;lt;tt&amp;gt;num&amp;lt;/tt&amp;gt; Bytes versenden soll. Wir könnten die Funktion so schreiben:&lt;br /&gt;
 void send_buf (unsigned char * buf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   ...&lt;br /&gt;
Das ist jedoch hässlich, wenn wir damit etwas anderes verschicken wollen als &amp;lt;tt&amp;gt; unsigned char&amp;lt;/tt&amp;gt;, etwa eine Struktur wie &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; (vom Typ &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;):&lt;br /&gt;
 send_buf ((unsigned char*) &amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
Ohne den Cast der Adresse von &amp;lt;tt&amp;gt;hubert&amp;lt;/tt&amp;gt; zu einem Zeiger auf &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt; bekommt man eine Warnung oder gar einen Compilerfehler.&lt;br /&gt;
Dieses Zeiger gecaste ist mühsam und hässlich, es muss bei jedem Aufruf der Funktion explizit hingeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Besser ist es, den ersten Parameter der Funktion als void-Pointer zu definieren und den Cast in der Funktion zu machen:&lt;br /&gt;
 void send_buf (void * vbuf, unsigned int num)&lt;br /&gt;
 {&lt;br /&gt;
   unsigned char *buf = (unsigned char*) vbuf;&lt;br /&gt;
   ...&lt;br /&gt;
Durch den Cast in der Funktion kann auf den Inhalt des Zeigers zugegriffen werden. Man muss nur festlegen, ''wie'' man zugreifen will, nämlich als &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Der Aufruf kann jetzt ohne Pointer-Cast erfolgen: &lt;br /&gt;
 send_buf (&amp;amp; hubert, sizeof (struct Person));&lt;br /&gt;
&lt;br /&gt;
==Null-Pointer==&lt;br /&gt;
==Zeiger als Parameter==&lt;br /&gt;
Wenn Sie ein Unterprogramm aufrufen, können Sie diesem Parameter übergeben, aber keine Werte zurückgekommen (außer den Funktionswert bei Funktionen). Dies hat einen guten Grund: beim Aufruf werden nicht die aufgerufenen Parameter benutzt, sondern es werden deren Werte in neue Variablen kopiert. Diese Variablen werden am Ende des Unterprogrammes &amp;quot;zerstört&amp;quot;, ohne ihre Werte an die aufrufenden Parameter zu übergeben. Jede Veränderung eines Parameters hat daher keine Auswirkung auf den Parameter.&lt;br /&gt;
&lt;br /&gt;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der C-Compiler legt dann immer noch Kopien an. In dieser Kopie steht aber kein Wert, sondern die Adresse einer Varaiblen. Und auf diese können Sie dann zugreifen. Denken Sie nur an &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; &amp;amp;ndash; da übergeben Sie ja auch die Adresse einer Variablen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void erhoehe (int *zeiger)&lt;br /&gt;
{&lt;br /&gt;
  *zeiger = 1 + *zeiger;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main ()&lt;br /&gt;
{&lt;br /&gt;
  int zahl;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;Zahl eingeben: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl);&lt;br /&gt;
  erhoehe (&amp;amp;zahl);&lt;br /&gt;
  printf (&amp;quot;\nDie erhoehte Zahl lautet: %d\n&amp;quot;, zahl);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Zeiger auf Funktionen==&lt;br /&gt;
&lt;br /&gt;
Stell dir vor, du willst einen Sortieralgorithmus wie Bubble-Sort oder Quick-Sort oder wie sie alle heissen implementieren. Für den Sortieralgorithmus ist eigentlich egal, ''was'' er zu sortieren hat. Ihm ist es egal, ob er Zahlen aufwärts sortieren soll oder Strings in lexikographischer Reihenfolge, ob Objekte nach Größe oder Gewicht, Personen nach Alter oder Adressen nach Postleitzahl. Das einzige, was der Algorithmus wissen muss, ist ''wie'' er zwei Objekte zu vergleichen hat und wann eines davon &amp;quot;kleiner&amp;quot; (im Sinne der Ordnung, nach der sortiert werden soll) ist. &lt;br /&gt;
&lt;br /&gt;
Eine einfache Sortierfunktion, die nur zwei Zahlen sortiert, könnte man also so schreiben: &lt;br /&gt;
 {{comment|Sortiert ein Array von 2 int-Zeigern nach den Inhalten &lt;br /&gt;
  * an den Zeiger-Adressen}}&lt;br /&gt;
 void sort2_a (int * p[])&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Inhalte vergleichen...}}&lt;br /&gt;
    if (*p[0] &amp;gt; *p[1])&lt;br /&gt;
    {&lt;br /&gt;
       {{comment|... und ggf. Dreieckstausch der 2 Zeiger}}&lt;br /&gt;
       int * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Die Funktion bekommt ein Array der Länge&amp;amp;nbsp;2. In diesem Array stehen Zeiger auf die zu sortierenden Zahlen. Ein Array mit Zeigern zu verwenden und nicht ein Array von &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; scheint recht umständlich, und das ist es hier auch. Aber stell dir vor, du willst Strukturen wie &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; sortieren. Das Tauschen zweier Strukturen würde bedeuten, ihre kompletten Inhalte umzukopieren! Das wäre sehr aufwändig. Viel einfacher ist das Kopieren, wenn nur die Adressen zu kopieren sind.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; könnte dann so aussehen:&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void sortiere (int a, int b)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|p[] enthält 2 int-Zeiger: die Adressen von a und b}}&lt;br /&gt;
    int * p[2];&lt;br /&gt;
    p[0] = &amp;amp;a; &lt;br /&gt;
    p[1] = &amp;amp;b; &lt;br /&gt;
 &lt;br /&gt;
    {{comment|Sortiere die Zeiger}} &lt;br /&gt;
    sort2_a (p);&lt;br /&gt;
 &lt;br /&gt;
    printf (&amp;quot;Sortiert: %d, %d\n&amp;quot;, *p[0], *p[1]);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Für den nächsten Schritt überlegen wir uns, daß das Array in &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; ebensogut void-Pointer enthalten kann. Die einzige Stelle, an der wir auf die endgültigen int-Objekte zugreifen, ist der Vergleich. Diesen Vergleich lagern wir in die Funktion &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; aus:&lt;br /&gt;
 {{comment|Bekommt zwei void-Pointer und vergleicht die Inhalte.&lt;br /&gt;
  * Liefert 0 bei Gleichheit,&lt;br /&gt;
  * -1 wenn der erste Wert kleiner ist als der zweite und&lt;br /&gt;
  * 1  wenn der erste Wert größer ist als der zweite}}&lt;br /&gt;
 int compare_int (void * p0, void * p1)&lt;br /&gt;
 {&lt;br /&gt;
    {{comment|Um über die Zeiger zugreifen zu können müssen wir diese&lt;br /&gt;
     * erst zu int-Zeigern casten}}&lt;br /&gt;
    int a0 = * (int*) p0;&lt;br /&gt;
    int a1 = * (int*) p1;&lt;br /&gt;
 &lt;br /&gt;
    if (a0 &amp;gt; a1)  return  1;&lt;br /&gt;
    if (a0 &amp;lt; a1)  return -1;&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void sort2_b (void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare_int (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Ein Aufruf von &amp;lt;tt&amp;gt;sort2_b&amp;lt;/tt&amp;gt; sieht dann genauso aus wie ein Aufruf von &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt definieren wir uns den neuen Datentyp &amp;lt;tt&amp;gt;comparator_t&amp;lt;/tt&amp;gt;. Dieser ist ein Zeiger auf eine Funktion, die zwei void-Pointer erhält und einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; zurückliefert, also analog arbeitet zu &amp;lt;tt&amp;gt;compare_int&amp;lt;/tt&amp;gt; von oben. &lt;br /&gt;
&lt;br /&gt;
Unsere Sortierfunktion bekommt nun neben dem zu sortierenden Zeiger-Array auch eine Vergleichsfunktion &amp;lt;tt&amp;gt;compare&amp;lt;/tt&amp;gt; mitgeliefert, die sie aufruft, wenn sie zwei Objekte vergleichen will&lt;br /&gt;
 {{comment|comparator_t sind Zeiger auf Funktionen, die 2 void-Pointer&lt;br /&gt;
  * erhalten und einen int zurückliefern}}&lt;br /&gt;
 typedef int (*comparator_t) (void*, void*);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Der Sortierer bekommt einen Funktionszeiger auf den Vergleicher.&lt;br /&gt;
  * Der Aufruf vom compare geht so als wäre es eine &amp;quot;normale&amp;quot; Funktion&lt;br /&gt;
  * (ist es im Endeffekt ja auch)}}&lt;br /&gt;
 void sort2_c (comparator_t compare, void * p[])&lt;br /&gt;
 {&lt;br /&gt;
    if (compare (p[0], p[1]) &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
       void * p0 = p[0];&lt;br /&gt;
       p[0] = p[1];&lt;br /&gt;
       p[1] = p0;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Bei einem Aufruf von &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; muss man dann einen Komparator mit angeben. In einem Beispiel analog zu &amp;lt;tt&amp;gt;sort2_a&amp;lt;/tt&amp;gt; von oben ist das:&lt;br /&gt;
 sort2_c (compare_int, p);&lt;br /&gt;
Um zwei Strings lexikographisch zu sortieren nehmen wie die Standard-Funktion &amp;lt;tt&amp;gt;strcmp&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 void foo()&lt;br /&gt;
 {&lt;br /&gt;
    char * worte[] = { &amp;quot;Wort1&amp;quot;, &amp;quot;Wort2&amp;quot; };&lt;br /&gt;
 &lt;br /&gt;
    sort2_c ((comparator_t) strcmp, (void**) worte);&lt;br /&gt;
 }&lt;br /&gt;
Die Casts sind hier erforderlich. Alternativ könnte man &amp;lt;tt&amp;gt;sort2_c&amp;lt;/tt&amp;gt; mit reinen void-Pointern versorgen und diese dann dort umcasten.&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
&lt;br /&gt;
Die Syntax zur Definition/Deklaration von Funktionszeigern ist etwas verzwackt. Zur Verdeutlichung ein paar Beispiele. Dabei legt das linke &amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt; jeweils den Return-Typ fest.&lt;br /&gt;
 {{comment|definiert einen neuen Funktionszeiger-Typ}}&lt;br /&gt;
 typedef {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert einen Funktionszeiger}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}) ({{type}}, {{type}}, ...);&lt;br /&gt;
 &lt;br /&gt;
 {{comment|deklariert ein Array von Funktionszeigern (mit Initializer)}}&lt;br /&gt;
 {{type}} (*{{bezeichner}}[]) ({{type}}, {{type}}, ...) = { wert1, wert2, ... };&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer}}&lt;br /&gt;
 ({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}&lt;br /&gt;
 &lt;br /&gt;
 {{comment|Castet Bezeichner zu einem Funktionspointer und ruft die Funktion auf}}&lt;br /&gt;
 (({{type}}(*)({{type}}, {{type}}, ...)) {{bezeichner}}) (arg1, arg2, ...);&lt;br /&gt;
&lt;br /&gt;
=Standard-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==String-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===strcpy===&lt;br /&gt;
Bei vielen Compilern können sie einem String nicht direkt einen Wert (Text) zuweisen. Dazu müssen Sie dann die Prozedur strcpy() benutzen. Diese erwartet als ersten Parameter den Namen einer String-Variablen (ohne eckige Klammern) und als zweiten Parameter den eines (anderen) Strings. Letzterer kann auch ein in doppelten Hochkommas (&amp;quot;) eingeschlossener Text sein. Die Funktion fügt am Ende automatisch ein 0-Zeichen ein. Um diese Funktion nutzen zu können, müssen Sie die Datei string.h includieren! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri1[21], eingabe[21];&lt;br /&gt;
&lt;br /&gt;
  strcpy (stri1, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Der 1. String: %s\n&amp;quot;, stri1);&lt;br /&gt;
  printf (&amp;quot;Bitte geben Sie maximal 20 Zeichen ein: &amp;quot;);&lt;br /&gt;
  scanf  (&amp;quot;%s&amp;quot;, eingabe);&lt;br /&gt;
  strcpy (stri1, eingabe);&lt;br /&gt;
  printf (&amp;quot;\n%s = %s&amp;quot;, stri1, eingabe);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis:''' &lt;br /&gt;
Da ein String, wie jedes Feld, eigentlich ein Zeiger ist, dürfen Sie kein &amp;lt;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; bei &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; angeben!&lt;br /&gt;
&lt;br /&gt;
'''Erklärung:''' &lt;br /&gt;
Es werden zwei gleich große Strings definiert: &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;eingabe&amp;lt;/tt&amp;gt;, mit je 20 &amp;quot;nutzbaren&amp;quot; Zeichen. &lt;br /&gt;
In &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; wird die Zeichenkette &amp;lt;tt&amp;gt;&amp;quot;hallo&amp;quot;&amp;lt;/tt&amp;gt; hineinkopiert. Das 0-Zeichen am Ende wird automatisch angefügt. &lt;br /&gt;
Der String wird ausgegeben. Als neues &amp;quot;Sonderzeichen&amp;quot; kommt &amp;lt;tt&amp;gt;%s&amp;lt;/tt&amp;gt; ins Spiel. Es hat die gleiche Aufgabe wie &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt;, nur für Strings. &lt;br /&gt;
Sie werden gebeten, eine String einzugeben. &lt;br /&gt;
Dieser String wird danach in die Variable &amp;lt;tt&amp;gt;stri1&amp;lt;/tt&amp;gt; kopiert. &lt;br /&gt;
Beide Strings, die ja nun die gleiche Zeichenkette enthalten, werden ausgegeben.&lt;br /&gt;
&lt;br /&gt;
===strlen===&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;strlen&amp;lt;/tt&amp;gt;, die als Parameter eine String-Variable erwartet, liefert die Länge diese Strings zurück. Sie werden jetzt vermutlich sagen: &amp;quot;Das ist doch klar, wie lang der String ist. Ich habe es ja bei der Deklaratin angegeben&amp;quot;. Das stimmt schon, aber denken Sie noch einmal an die null-terminierten Strings. Das 0-Zeichen steht am Ende des Strings (am Ende der gültigen Zeichenfolge), aber nicht unbedingt am Ende des reservierten Speicherplatzes. Haben Sie eine Variable &amp;quot;char Variable[21];&amp;quot;, und ihr den Wert &amp;quot;hallo&amp;quot; zugewiesen, dann steht das null-Zeichen in Variable[5]. Der &amp;quot;gültige&amp;quot; String ist also 5 Zeichen (0-4) lang. Und genau das (5) würde strlen zurück liefern. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  char stri[21];&lt;br /&gt;
  &lt;br /&gt;
  strcpy (stri, &amp;quot;hallo&amp;quot;);&lt;br /&gt;
  printf (&amp;quot;Der String ist %d Zeichen lang&amp;quot;, strlen (stri));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion wird vor allem gebraucht, wenn Sie direkt auf den String zugreifen, mittels &amp;lt;tt&amp;gt;stri[0]&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;stri[1]&amp;lt;/tt&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
==Ein- und Ausgabe-Funktionen==&lt;br /&gt;
&lt;br /&gt;
===Bildschirm-Ausgabe===&lt;br /&gt;
Bisher war das Tutorial trotz aller Beispiele reine Theorie. Sie konnten zwar Programme schreiben, aber die Funktion nicht testen. Hier lernen Sie nun, wie Sie etwas am Bildschirm ausgeben.&lt;br /&gt;
&lt;br /&gt;
Die dazu notwendige Funktione heisst &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (das '&amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt;' ist kein Fehler!). Diese Anweisung gibt die ihr übergebenen Parameter auf das Standard-Ausgabegerät aus, in der Regel also auf den Bildschirm. Sie kann beliebig viele Parameter übernehmen. Es müssen jedoch Standard-Datentypen (z.B. &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;...) sein! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
    int zahl1 = 12;&lt;br /&gt;
    char zeichen1 = 'A';&lt;br /&gt;
    &lt;br /&gt;
    printf (&amp;quot;Das ist Text, und er wird als solcher ausgegeben. \n&amp;quot;);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zahl1' ist: %d \n&amp;quot;, zahl1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %c \n&amp;quot;, zeichen1);&lt;br /&gt;
    printf (&amp;quot;Der Wert der Variablen 'zeichen1' ist: %d \n&amp;quot;, zeichen1);&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt Text aus. Das Zeichen am Ende (&amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;) bedeutet &amp;quot;New Line&amp;quot;, es bewegt den Cursor an den Anfang der nächsten Zeile. &lt;br /&gt;
&lt;br /&gt;
Der zweite &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;-Befehl gibt auch Text aus, am Ende befindet sich wieder das &amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;, um einen Zeilenvorschub zu erreichen. Das &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; wird vom Compiler durch den ersten Parameter ersetzt, der nach dem Text angegeben wird. In diesem Fall wird &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; also durch den Wert der Variablen &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; ersetzt. Das &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; im &amp;lt;tt&amp;gt;%d&amp;lt;/tt&amp;gt; bedeutet &amp;quot;Dezimalzahl&amp;quot;, der Computer gibt also eine ganze Zahl aus. &lt;br /&gt;
&lt;br /&gt;
In der dritten Ausgabe wird ein Zeichen ausgegeben. Diesmal bedeutet &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; &amp;quot;char&amp;quot; (Zeichen). Es wird also &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; durch ein &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt; ersetzt, denn die Variable &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; wird als Character interpretiert. &lt;br /&gt;
&lt;br /&gt;
Die letzte Ausgabe interpretiert den Inhalt von &amp;lt;tt&amp;gt;zeichen1&amp;lt;/tt&amp;gt; als Zahl, und gibt dager den ASCII-Wert von &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, also 65 aus. Das ist ein typisches Beispiel für das mögliche unterschiedliche Interpretieren einer  Variablen!&lt;br /&gt;
&lt;br /&gt;
===Tastatur-Eingabe===&lt;br /&gt;
&lt;br /&gt;
Um ein &amp;quot;gscheites&amp;quot; Programm schreiben zu können, muß man wissen, wie der Benutzer über die Tastatur Befehle eingeben kann. Die dafür notwendigen Funktionen stelle ich in diesem Kapitel vor.&lt;br /&gt;
Die wichtigste Funktion ist &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt;. Er liest Daten von der Tastatur. Die Syntax entspricht derer von &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int  zahl1;&lt;br /&gt;
char zeichen1;&lt;br /&gt;
&lt;br /&gt;
printf (&amp;quot;Bitte geben Sie eine Zahl ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%d&amp;quot;, &amp;amp;zahl1);&lt;br /&gt;
printf (&amp;quot;Geben Sie einen Zeichen ein: &amp;quot;);&lt;br /&gt;
scanf  (&amp;quot;%c&amp;quot;, &amp;amp;zeichen1);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Programm gibt eine Eingabeaufforderung aus. Dann erwartet es vom Benutzer, daß er eine Zahl eingibt, die mit [ENTER] bestätigt wird. Dieser Wert wird in &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt; abgespeichert. Danach erfolgt wiederum eine Aufforderung zur Eingabe, diesmal eines einzelnen Zeichens. Dieses kann man nun eingeben und ebenfalls mit [ENTER] bestätigen.&lt;br /&gt;
&lt;br /&gt;
Macht man keine dem Datentyp der erwarteten Variable entsprechende Eingabe, dann bricht das Programm mit einer Fehlermeldung ab (wenn man z.B. &amp;quot;1_T2&amp;quot; eingibt, wenn eine Zahl erwartet wird)!&lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; vor den Parametern ist notwendig. Warum, das erfahren Sie im Kapitel &amp;quot;Unterprogramme&amp;quot;. Für die Profis eine Kurz-Erklärung: Das Unterprogramm &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; bekommt zwar einen Wert übergeben, kann aber keinen zurückliefern (&amp;quot;call by value&amp;quot;). Daher wird kein Wert, sondern ein Zeiger auf eine Variable übergeben. Mit dem &amp;amp; Zeichen bekommen Sie die Adresse einer Variablen (&amp;quot;call by reference&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=Parameter von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;=&lt;br /&gt;
Das Unterprogramm &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; kann, wie jede andere Funktion, Parameter besitzen. Doch keine selbst gewählten, sondern nur bestimmte. Doch warum braucht main Parameter? Denken Sie einmal an alle Betriebssystembefehle:&lt;br /&gt;
&amp;lt;tt&amp;gt;dir *.exe &amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;copy *.* a:&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;ls -la &amp;lt;/tt&amp;gt;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;&amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen!&lt;br /&gt;
&lt;br /&gt;
=Kurzreferenz=&lt;br /&gt;
==Syntax-Bausteine==&lt;br /&gt;
&lt;br /&gt;
Die Erklärung des Aufbaus von C-Befehlen erfolgt neben einfachen Beispielen auch durch ihren prinzipellen Aufbau. In diesen Syntax-Beschreibungen finden sich immer wieder die gleichen Bausteine, die hier näher erklärt werden sollen. Falls die solch ein Syntax-Baustein begegnet, kannst Du ihn anclicken und kommst dann zu seiner Erläuterung. &lt;br /&gt;
&lt;br /&gt;
In den Beispielen selbst gehören auch die spitzen Klammern zu dem Baustein (was daran zu erkennen ist, daß auch die Klammern eingefärbt sind). Die Klammern dürfen in einem konkreten C-Programm daher nicht eingetippt werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bezeichner&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Bezeichner in C dienen dazu, Variablen zu identifizieren und ihnen sprechende Namen zu geben, um die Quelle lesbarer zu machen. Man braucht Bezeichner auch, um selbstdefinierte Datentypen zu benennen und zum Benennen von Struct- und Union-Komponenten sowie als Namen für Funktionen und Sprungmarken (Labels).&lt;br /&gt;
&lt;br /&gt;
Bezeichner dürfen aus den Kleinbuchstaben &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;z&amp;lt;/tt&amp;gt;, den Großbuchstaben &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;Z&amp;lt;/tt&amp;gt;, dem Unterstrich&amp;amp;nbsp;&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt; und den Ziffern &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;...&amp;lt;tt&amp;gt;9&amp;lt;/tt&amp;gt; aufgebaut werden, wobei an erster Stelle jedoch keine Ziffer stehen darf.&lt;br /&gt;
&lt;br /&gt;
Es wird zwischen Groß- und Kleinschreibung unterschieden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Ausdruck in C ist ein Konstrukt, das einen Wert hat. Ob dieser Wert eine ganze Zahl ist, eine Kommazahl oder ein Zeiger, etc. ist dabei egal. Die einfachsten Ausdrücke sind Konstanten wie&lt;br /&gt;
 2&lt;br /&gt;
oder Variablen wie&lt;br /&gt;
 ein_zahl&lt;br /&gt;
Mehrere Ausdrücke können durch [[#Liste der Operatoren|Operatoren]] zu komplexeren Ausdrücken kombiniert werden, etwa&lt;br /&gt;
 eine_zahl + andere_zahl == 2&lt;br /&gt;
oder &lt;br /&gt;
 eine_zahl = 2&lt;br /&gt;
Letzterer hat den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; und den Nebeneffekt, daß er diesen Wert an &amp;lt;tt&amp;gt;eine_zahl&amp;lt;/tt&amp;gt; zuweist.&lt;br /&gt;
&lt;br /&gt;
Auch der Aufruf einer Funktion, die einen Rückgabewert liefert, ist ein Ausdruck:&lt;br /&gt;
 sin (1.2)&lt;br /&gt;
und kann zum Aufbau komplexerer Ausdrüche verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Bedingung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Bedingung ist ein Ausdruck, bei der nur interessiert, ob dieser zu&amp;amp;nbsp;0 (unwahr) auswertet oder zu ungleich&amp;amp;nbsp;0 (wahr). Solche Ausdrücke findet man in if-Anweisungen, in Schleifenbedingungen und bedingten Zuweisungen&lt;br /&gt;
 (ein_wert &amp;lt; 2) || (ein_wert &amp;gt; 40)&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Ein Lvalue ist ein Ausdruck, dem etwas zugewiesen werden kann. Der Name ''Lvalue'' kommt aus dem Englischen. Das ''L'' steht abkürzend für left. Ein Lvalue ist damit ein Ausdruck, der auf der linken Seite eine Zuweisung in C stehen darf. Das &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; in den folgenden Beispiel-Ausdrücken muss ein Lvalue sein:&lt;br /&gt;
 x = y-1&lt;br /&gt;
&lt;br /&gt;
 x++&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Konstante&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Konstante ist ein Ausdruck, dessen Wert dem Compiler bekannt ist. Beispiele für Konstanten sind etwa&lt;br /&gt;
 7&lt;br /&gt;
 'B'&lt;br /&gt;
 -13.98e12&lt;br /&gt;
 1+(2*3)&lt;br /&gt;
und die Werte von [[#Enum|Enum]]s. &lt;br /&gt;
&lt;br /&gt;
Das &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; aus dem folgenden Codestück definiert jedoch keine Konstante in diesem Sinne&lt;br /&gt;
 const double Pi = 3.14159256;&lt;br /&gt;
denn in einem anderen Quellmodul könnte durch die Deklaration&lt;br /&gt;
 extern const double Pi;&lt;br /&gt;
das Symbol &amp;lt;tt&amp;gt;Pi&amp;lt;/tt&amp;gt; bekannt sein, ohne daß sein Wert bekannt ist!&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Adresse&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Eine Adresse ist ein Ausdruck, der einen Speicherort (physikalisch oder virtuell) halten kann. Adressen erhält man dadurch, daß man einem Bezeichner den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt;voranstellt, Adressen durch Arithmetik berechnet oder Zahlen zu Adressen castet. Folgende Ausdrücke sind Adressen (eine sinnvolle Deklaration der auftretenden Variablen vorausgesetzt)&lt;br /&gt;
 &amp;amp; eine_zahl&lt;br /&gt;
 &amp;amp; ein_array[10]&lt;br /&gt;
 &amp;amp; ein_struct&lt;br /&gt;
 &amp;amp; ein_struct.komponente&lt;br /&gt;
 (int *) 0x1234&lt;br /&gt;
 (int *) eine_zahl&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Deklaration&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Anweisungen sind gewissermassen die Atome (oder Moleküle?), aus denen ein C-Programm besteht. Jedes C-Programm ist eine Abfolge von Deklarationen und Anweisungen. Einfache Anweisungen erhält man, in dem man einen Ausdruck nimmt und einen Strichpunkt dahinter schreibt:&lt;br /&gt;
 {{Ausdruck|}};&lt;br /&gt;
wie in&lt;br /&gt;
 x = x+1;&lt;br /&gt;
&lt;br /&gt;
Andere Anweisungen sind die unten aufgeführten Schleifen und die if- sowie die switch-Anweisung.&lt;br /&gt;
&lt;br /&gt;
Mehrere Deklarationen und Anweisungen können zu einem Block zusammengefasst werden. Dieser Block stellt dann wieder eine einzelne Anweisung dar und kann genau so gehandhabt werden!&lt;br /&gt;
 {&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    {{Deklaration}}&lt;br /&gt;
    ...&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
In diesem Sinne ist auch z.B. die Syntax der if-Anweisung zu verstehen&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
besagt, daß der abhängig ausgeführte Code eine einzelne Anweisung sein darf oder eben ein kompletter Block oder die Verschachtelung mehrerer Blöcke etc.&lt;br /&gt;
&lt;br /&gt;
Eine Anweisung kann auch &amp;quot;leer&amp;quot; sein, also nichts tun. Diese Anweisungen sind der leere Block&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
und der Strichpunkt&lt;br /&gt;
 ;&lt;br /&gt;
die man gelegentlich in Schleifen findet:&lt;br /&gt;
 while (!timeout())&lt;br /&gt;
    {}&lt;br /&gt;
oder hinter Sprungmarken, die sonst direkt vor einer schliessenden Blockklammer stünden:&lt;br /&gt;
 {&lt;br /&gt;
    ...&lt;br /&gt;
    goto ein_label;&lt;br /&gt;
    ...&lt;br /&gt;
    {{Label|ein_label}}:;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Nicht jede Anweisung ist an jeder Stelle eines C-Programms erlaubt, so darf ein &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; nut innerhalb einer Schleife stehen. Gleiches gilt für &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;, das aber auch innerhalb eines &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; vorkommen darf.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
Dies steht für einen Datentyp. Es kann ein elementarer Typ sein wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;, ein Zeiger darauf wie &amp;lt;tt&amp;gt;char*&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;void*&amp;lt;/tt&amp;gt;, und auch Qualifier enthalten wie das &amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt; im Typ &amp;lt;tt&amp;gt;unsigned long long&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Zu den Typen gehören auch zusammengesetzte Datentypen wie Strukturen und Unions, mit &amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt; selbst definierte Typen und natürlich Zeiger darauf, wie aus dem Abschnitt [[#Datentypen|Datentypen]]:&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;struct Person *&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;data32_t&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;enum Farben&amp;lt;/tt&amp;gt;&lt;br /&gt;
und Zeiger auf Funktionen.&lt;br /&gt;
&lt;br /&gt;
=====&amp;lt;tt&amp;gt;&amp;lt;Parameterliste&amp;gt;&amp;lt;/tt&amp;gt;=====&lt;br /&gt;
&lt;br /&gt;
Die Parameterliste bei einer Funktionsdefinition gibt an, wieviel Übergabeparameter sie bekommt, wie diese heissen und welchen Typs diese sind. Der prinzipielle Aufbau ist&lt;br /&gt;
 {{Type}} {{Bezeichner}}, {{Type}} {{Bezeichner}}, ...&lt;br /&gt;
Falls die Funktion keine Parameter hat, dann ist die Parameterliste leer.&lt;br /&gt;
&lt;br /&gt;
Hier als Beispiel die zweiparametrige Funktion &amp;lt;tt&amp;gt;produkt&amp;lt;/tt&amp;gt;. Der erste Parameter heisst&amp;amp;nbsp;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und ist ein &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;. Der zweite namens&amp;amp;nbsp;&amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; ist vom Typ &amp;quot;Zeiger auf double&amp;quot;, der Inhalt &amp;lt;tt&amp;gt;*b&amp;lt;/tt&amp;gt; ist also auch ein double.&lt;br /&gt;
&lt;br /&gt;
'''Definition der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b)&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
In älteren C-Quellen findet man noch eine andere Syntax für die Deklaration der Parameter, die aber heute praktisch nicht mehr verwendet wird:&lt;br /&gt;
'''alte Definition der Funktion:'''&lt;br /&gt;
 double produkt (a, b)&lt;br /&gt;
 double a, *b;&lt;br /&gt;
 {&lt;br /&gt;
    return a * (*b);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Um die Funktion bekannt zu machen, werdendet man eine Deklaration bzw. den Prototypen, der dem Compiler nur mitteilt, welche Parameter die Funktion bekommt und was sie zurückliefert. Für den Aufruf der Funktion muss der Compiler nur diesen Prototyp kennen, ''was'' die Funktion im Endeffekt macht und wie sie implementiert wurde ist egal, sie wird als BlackBox angesehen.&lt;br /&gt;
&lt;br /&gt;
'''Prototyp der Funktion:'''&lt;br /&gt;
 double produkt (double a, double *b);&lt;br /&gt;
Hier dürfen die Bezeichner auch fehlen:&lt;br /&gt;
 double produkt (double, double*);&lt;br /&gt;
&lt;br /&gt;
==if==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==if-else==&lt;br /&gt;
 if ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 else&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==for==&lt;br /&gt;
 for ({{Ausdruck|1}}; {{Bedingung}}; {{Ausdruck|2}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
Eine for-Schleife entspricht folgendem Konstrukt. Dabei sind die drei Ausdrücke optional. Fehlt die Bedingung, dann wird diese als &amp;quot;wahr&amp;quot; angenommen. Die beiden anderen Ausdrücke wird man als Ausdrücke mit Nebeneffekt wählen wie z.B. &amp;lt;tt&amp;gt;x=0&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;x=x-2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
 {&lt;br /&gt;
    {{Ausdruck|1}};&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_loop}}:&lt;br /&gt;
    if ({{Bedingung}})&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
    else&lt;br /&gt;
       goto _break;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_continue}}:&lt;br /&gt;
    {{Ausdruck|2}};&lt;br /&gt;
    goto _loop;&lt;br /&gt;
 &lt;br /&gt;
    {{Label|_break}}:;&lt;br /&gt;
 }&lt;br /&gt;
Die Labels &amp;lt;tt&amp;gt;_break&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;_continue&amp;lt;/tt&amp;gt; entsprechen den Sprungzielen einer &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;-Anweisung innerhalb von &amp;lt;tt&amp;gt;&amp;lt;Anweisung&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==do-while==&lt;br /&gt;
 do&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
 while  ({{Bedingung}});&lt;br /&gt;
&lt;br /&gt;
==while==&lt;br /&gt;
 while  ({{Bedingung}})&lt;br /&gt;
    {{Anweisung}}&lt;br /&gt;
&lt;br /&gt;
==switch==&lt;br /&gt;
 switch  ({{Bedingung}})&lt;br /&gt;
 {&lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    case {{Konstante}}:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 &lt;br /&gt;
    ...&lt;br /&gt;
  &lt;br /&gt;
    default:&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       {{Anweisung}}&lt;br /&gt;
       ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#break-Anweisung|&amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt;]], &lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Konstanten|&amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#continue-Anweisung|&amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#do-while-Schleife|&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Enum|&amp;lt;tt&amp;gt;enum&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#for-Schleife|&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#goto-Anweisung|&amp;lt;tt&amp;gt;goto&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#if-Anweisung|&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#return-Anweisung|&amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;register&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Liste der Operatoren|sizeof]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Strukturen|&amp;lt;tt&amp;gt;struct&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#switch-Anweisung|&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Eigene Datentypen|&amp;lt;tt&amp;gt;typedef&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Unions|&amp;lt;tt&amp;gt;union&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Elementare Datentypen|&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#Speicherklassen|&amp;lt;tt&amp;gt;volatile&amp;lt;/tt&amp;gt;]],&lt;br /&gt;
[[#while-Schleife|&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund2}}&lt;br /&gt;
!| Operator || Bedeutung&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Arithmetische Operatoren&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Dies sind die &amp;quot;normalen&amp;quot; arithmetischen Operationen, wie man sie aus der Schule kennt. Man kann damit und allen anderen Operatoren auch komplexere Ausdrücke aufbauen. Die Prioritäten sind so, wie man sie kennt, also &amp;quot;Punktrechnung vor Strichrechnung&amp;quot;. Will man dies ändern, dann mit den runden Klammern:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;1+2*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 7&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(1+2)*3&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; 9&amp;lt;br/&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}}&amp;amp;nbsp;+&amp;amp;nbsp;{{Ausdruck|}}&amp;lt;/tt&amp;gt; || Addition&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} - {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Subtraktion&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} * {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Multiplikation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} / {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Division&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} % {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Rest der Division (modulo)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;- {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Vorzeichenumkehr, Zweier-Komplement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Logische Operatoren und Vergleiche&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die logischen und die vergleichenden Operatoren liefern als Ergebnis den Wert&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (wahr) oder einen Wert ungleich&amp;amp;nbsp;&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (falsch, um genau zu sein den Wert &amp;lt;tt&amp;gt;!0&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Man kann das Ergebnis zwar einer Variablen zuweisen, in aller Regel wird man solche Ausdrücke jedoch in Bedingungen zu &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; oder in Abbruch-Bedingungen von Schleifen finden.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;&amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches AND: beides wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124;&amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches OR: mind. eines ist wahr (ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;! {{Ausdruck|}}&amp;lt;/tt&amp;gt; || logisches NOT (0 &amp;amp;harr; ungleich 0)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} == {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} != {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist nicht gleich&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bitweise Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~ {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise NOT (Einser-Komplement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise AND&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || bitweise ODER&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} ^ {{Ausdruck|}}&amp;lt;/tt&amp;gt; ||bitweise XOR&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Shift-Operatoren&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;lt;&amp;lt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Bits nach links schieben&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Ausdruck|}} &amp;gt;&amp;gt; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Schieben nach rechts schieben&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Typen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Ein Cast in C kann dazu verwendet werden, den Typ eines Ausdruckes zu ändern oder den Ausdruck mit einer bestimmten Genauigkeit zu berechnen. Wird z.B. eine Berechnung standardmässig in 16 Bit ausgeführt, dann kann man mit einem Cast &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;(long) &amp;amp;middot;&amp;amp;middot;&amp;amp;middot;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
ausdrücken, daß die Berechnung in 32 Bit erfolgen soll. Des weiteren kann man Zeiger und ganze Zahlen und Gleitkommazahlen ineinander umwandeln.&lt;br /&gt;
&lt;br /&gt;
Casts können ''nicht'' dazu verwendet werden, um z.B. eine Zahl in einen String zu konvertieren, der diese Zahl darstellt! Dafür gibt es spezielle Funktionen wie &amp;lt;tt&amp;gt;itoa&amp;lt;/tt&amp;gt;!&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Type}}) {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Cast, Typwandlung&lt;br /&gt;
|-&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;| &amp;lt;tt&amp;gt;sizeof ({{Type}})&amp;lt;/tt&amp;gt; || Eine Konstante, deren Wert die Größe (in Bytes) des Typs ist. &amp;lt;tt&amp;gt;sizeof&amp;lt;/tt&amp;gt; ist auch auf Objekte anwendbar wie &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;, Arrays bekannter Größe, Strukturen und Unions,  Array-, Struktur- und Union-Komponenten, Pointer, etc. Beispiel:&amp;lt;br/&amp;gt;&lt;br /&gt;
 int i, sum=0, array[] = { 1, -13, 4, 0, sizeof (int*) };&lt;br /&gt;
 &lt;br /&gt;
 for (i=0; i&amp;lt; sizeof (array) / sizeof (array[0]); i++)&lt;br /&gt;
    sum += array[i];&lt;br /&gt;
Alle Elemente des Arrays werden aufaddiert, ohne daß deren Anzahl explizit in der Schleife genannt ist.&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zeiger und Adressen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;* {{Adresse}}&amp;lt;/tt&amp;gt; || der Inhalt an Adresse&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp; {{Lvalue}}&amp;lt;/tt&amp;gt; || Adresse von&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Strukturen, Unions, Arrays&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Struct&amp;gt;}}.{{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{blau|&amp;lt;Zeiger-auf-Struct&amp;gt;}} -&amp;gt; {{Bezeichner}}&amp;lt;/tt&amp;gt; || Komponente einer Struktur/Union, deren Adresse man hat&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Adresse}}&amp;amp;#91;{{Ausdruck|}}&amp;amp;#93;&amp;lt;/tt&amp;gt; || Array-Element&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Bedingte Auswertung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;({{Bedingung}}) ? {{Ausdruck|}} : {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Auswahl des Wertes abhängig von der Bedingung&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Zuweisung und Operatoren mit Nebeneffekt&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|Die Unterschiede der post- und pre-Varianten der Increment/Decrement kommen in Konstrukten wie &amp;lt;tt&amp;gt;x = *p++&amp;lt;/tt&amp;gt; zum tragen:&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *p++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; p = p+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = *++p;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; p = p+1; x = *p;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = (*p)++;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; x = *p; *p = (*p)+1;&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;x = ++(*p);&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/tt&amp;gt;&amp;amp;rarr; &amp;lt;tt&amp;gt; *p = (*p)+1; x = *p;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} = {{Ausdruck|}}&amp;lt;/tt&amp;gt; || Zuweisung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++ {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-- {{Lvalue}}&amp;lt;/tt&amp;gt; || Pre-Decrement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ++&amp;lt;/tt&amp;gt; || Post-Increment&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} --&amp;lt;/tt&amp;gt; || Post-Decrement&lt;br /&gt;
&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Kurzschreibweisen&lt;br /&gt;
|- &lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;| Für ganz Faule gibt es anstatt&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a = a @ b&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
für viele Operatoren (hier dargestellt durch ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;@&amp;lt;/tt&amp;gt;) die abkürzende Schreibweise&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;a @= b&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} += {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} -= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} *= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} /= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} %= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} ^= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;amp;#124; {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;lt;&amp;lt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;{{Lvalue}} &amp;gt;&amp;gt;= {{Ausdruck|}}&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Autoren'''&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
* Kernighan und Ritchie - Buch&lt;br /&gt;
* Christian Wirth , C Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://wwwuser.gwdg.de/~kboehm/ebook/inhalt.html C-Programmieren unter Linux]&lt;br /&gt;
* [http://www.gdv.uni-hannover.de/documentation.php Skripte zum Selbststudium: C, C++, Java, etc]&lt;br /&gt;
* [http://info.baeumle.com/ansic.html Einführung in ANSI-C]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Quellcode C|!]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Inrfb2</name></author>	</entry>

	</feed>