<?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=Tuffig</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=Tuffig"/>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Spezial:Beitr%C3%A4ge/Tuffig"/>
		<updated>2026-04-11T20:44:55Z</updated>
		<subtitle>Benutzerbeiträge</subtitle>
		<generator>MediaWiki 1.25.1</generator>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_I2C_Master&amp;diff=12860</id>
		<title>Bascom I2C Master</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Bascom_I2C_Master&amp;diff=12860"/>
				<updated>2007-10-30T18:49:09Z</updated>
		
		<summary type="html">&lt;p&gt;Tuffig: /* Software I2C */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Artikel folgen verschiedene Programmbeispiele um einen [[AVR]] mit [[Bascom]] zu einem [[I2C]]-Master zu schlumpfen.&lt;br /&gt;
&lt;br /&gt;
In allen Beispielen wird einem PCF8574 jeweils der Wert &amp;amp;HAA nach einer Pause &amp;amp;H55 gesendet, was als Blinken, evtl. auch als Lauflicht zu erkennen sein kann, falls LEDs an dessen Ports angeschlossen sind.&lt;br /&gt;
&lt;br /&gt;
[[Bild:RN-Control_PCF8574.JPG|thumb|Beispielumgebung mit PCF8574]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Software I2C ==&lt;br /&gt;
&lt;br /&gt;
Die Softwareversion der I2C-Implementierung kann auf allen AVR programmiert werden, man kann sich die Ports auf denen Data (SDA) und Clock (SCL) angeschlossen werden selbst aussuchen.&lt;br /&gt;
&lt;br /&gt;
Standardmäßig wird von Bascom die Software-Version verwendet um auf den I2C-Bus zuzugreifen, d.H. die einzelnen Bits der zu übertragenden Daten werden per Software auf High- oder Low-Pegel an den Ports ausgegeben. Der AVR kann in dieser Zeit keine anderen Aufgaben erledigen.&lt;br /&gt;
&lt;br /&gt;
Bei dieser Art I2C zu implementieren wird eine aktuelle Aktivität auf dem Bus nicht beachtet, dies kann zu Problemen führen falls mehr als ein Master am Bus hängt. Siehe Links unter &amp;quot;[[#Siehe_auch|Siehe auch]]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 $regfile = &amp;quot;M32def.dat&amp;quot;                           {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                               {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600&lt;br /&gt;
 &amp;lt;font color=&amp;quot;#a01010&amp;quot;&amp;gt;&lt;br /&gt;
 Config Scl = Portb.0                              {{vbcomment|Ports fuer IIC-Bus, nicht Standard !}}&lt;br /&gt;
 Config Sda = Portb.1&lt;br /&gt;
&amp;lt;!-- das &amp;quot;=&amp;quot; immer mit &amp;amp;#061; angeben, sonst gibts keinen Kommentar !! --&amp;gt;&lt;br /&gt;
 {{vbcomment|Config I2cdelay &amp;amp;#061; 10                  ' je höher der Wert umso langsamer der Bus}}&lt;br /&gt;
 &lt;br /&gt;
 I2cinit&lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
 Const Pcf_write = &amp;amp;H40                            {{vbcomment|Slaveadresse}}&lt;br /&gt;
 Const Pcf_read = &amp;amp;H41&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;I2C-Soft Demo mit PCF 8574&amp;quot;&lt;br /&gt;
 Print&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;HAA&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;H55&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
Mit ERR kann nach jedem gesendeten Byte abgefragt werden, ob es mit ACK quittiert wurde (=0), oder nicht (=1).&lt;br /&gt;
&lt;br /&gt;
Falls mehr als nur ein Byte an einen Slave gesendet werden sollte, und nach dem letzten Byte ERR=1 ist, sollte anschließend ein I2Cstop folgen, da der Slave kein weiteres Byte haben will !&lt;br /&gt;
&lt;br /&gt;
== Hardware TWI ==&lt;br /&gt;
&lt;br /&gt;
AVR Controller, die [[I2C]] hardwaremäßig Unterstützen, haben das [[TWI]]-Modul, die Ports für Data und Clock sind dabei vorgegeben. TWI ist bei den meisten ATMegas vorhanden, z.B. dem [[ATMega32]].&lt;br /&gt;
&lt;br /&gt;
Damit Bascom das TWI-Modul verwendet muss die &amp;lt;tt&amp;gt;i2c_twi.lib&amp;lt;/tt&amp;gt; (bzw. &amp;lt;tt&amp;gt;.lbx&amp;lt;/tt&amp;gt;, bei der Bascom-Demo) eingebunden werden, ansonsten ist, bis auf die Initialisierung, alles genauso wie bei Software-I2C.&lt;br /&gt;
Bei Verwendung der Bascom-I2C-Befehle macht es Performancemäßig keinen großen Unterschied, ob man Software-I2C oder TWI verwendet, denn bei beiden Versionen wird solange darauf gewartet, bis das Byte über den Bus gesendet ist, und ein ACK oder NACK empfangen ist.&lt;br /&gt;
&lt;br /&gt;
Der Vorteil von TWI ist aber, das es in Multimasterumgebungen besser verträglich ist (z.B. I2CStart). Gibt es nur einen Master, kann man sich für eine der beiden Versionen entscheiden.&lt;br /&gt;
&lt;br /&gt;
Der Master bestimmt wie schnell die Daten auf dem Bus übertragen werden (Ausnahme: [[Clock_Stretching]] ).&lt;br /&gt;
Dafür ist hier die Zeile mit '''&amp;lt;tt&amp;gt;Config TWI&amp;lt;/tt&amp;gt;''' zuständig, Bascom berechnet aus der angegebenen Taktfrequenz den richtigen Wert für TWBR um an den gewünschten I2C-Takt zu kommen.&lt;br /&gt;
&lt;br /&gt;
 $regfile = &amp;quot;M32def.dat&amp;quot;                           {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                               {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600&lt;br /&gt;
 &amp;lt;font color=&amp;quot;#a01010&amp;quot;&amp;gt;&lt;br /&gt;
 $lib &amp;quot;i2c_twi.lbx&amp;quot;                                {{vbcomment|Für Hardware TWI}}&lt;br /&gt;
 &lt;br /&gt;
 Config Twi = 400000                               {{vbcomment|Init TWBR und TWSR}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI gleich einschalten, das macht Bascom ansonsten erst beim I2CStart !}}&lt;br /&gt;
 TWCR = TWEN  &lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
 Const Pcf_write = &amp;amp;H40                            {{vbcomment|Slaveadresse}}&lt;br /&gt;
 Const Pcf_read = &amp;amp;H41&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;I2C-TWI Demo mit PCF 8574&amp;quot;&lt;br /&gt;
 Print&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;HAA&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;H55&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
Mit ERR kann nach jedem gesendeten Byte abgefragt werden, ob es mit ACK quittiert wurde (=0), oder nicht (=1).&lt;br /&gt;
&lt;br /&gt;
Mit der TWI-Lib wird zwar die Hardware benutzt um die Bytes auf den I2C-Bus auszugeben bzw. von dort einzulesen, es wird aber kein Status von TWSR abgefragt, ob die erwartete Reaktion eingetreten ist !&lt;br /&gt;
&lt;br /&gt;
Unter Zuhilfenahme des Datenblattes könnte eine Highend-Version so aussehen:&lt;br /&gt;
&lt;br /&gt;
 $regfile = &amp;quot;M32def.dat&amp;quot;                           {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                               {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600&lt;br /&gt;
 &amp;lt;font color=&amp;quot;#a01010&amp;quot;&amp;gt;&lt;br /&gt;
 $lib &amp;quot;i2c_twi.lbx&amp;quot;                                {{vbcomment|Für Hardware TWI}}&lt;br /&gt;
 &lt;br /&gt;
 Config Twi = 400000                               {{vbcomment|Init TWBR und TWSR}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI gleich einschalten, das macht Bascom ansonsten erst beim I2CStart !}}&lt;br /&gt;
 TWCR = TWEN&lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
 Const Pcf_write = &amp;amp;H40                            {{vbcomment|Slaveadresse}}&lt;br /&gt;
 Const Pcf_read = &amp;amp;H41&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;I2C-TWI High-Demo mit PCF 8574&amp;quot;&lt;br /&gt;
 Print&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
     I2cstart&lt;br /&gt;
     If TWSR = &amp;amp;H08 Then                           {{vbcomment|Start wurde abgesetzt}}&lt;br /&gt;
         I2cwbyte Pcf_write                        {{vbcomment|Slaveadresse ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
         If TWSR = &amp;amp;H18 Then                       {{vbcomment|Slave hat sich gemeldet}}&lt;br /&gt;
             I2cwbyte &amp;amp;HAA                         {{vbcomment|Datenbyte ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
             If TWSR &amp;lt;&amp;gt; &amp;amp;H28 Then                  {{vbcomment|Byte erfolgreich übertragen}}&lt;br /&gt;
                 Print &amp;quot;Byte mit NACK quittiert !&amp;quot;&lt;br /&gt;
             End If&lt;br /&gt;
         Else&lt;br /&gt;
             Print &amp;quot;kein Slave !&amp;quot;&lt;br /&gt;
         End If&lt;br /&gt;
     Else&lt;br /&gt;
         Print &amp;quot;Fehler bei Start&amp;quot;&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Immer Stop, damit die Buspegel wieder stimmen}}&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print &amp;quot;E &amp;quot; ; Err                              {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 1500&lt;br /&gt;
 &lt;br /&gt;
     I2cstart&lt;br /&gt;
 &lt;br /&gt;
     If TWSR = &amp;amp;H08 Then                           {{vbcomment|Start wurde abgesetzt}}&lt;br /&gt;
         I2cwbyte Pcf_write                        {{vbcomment|Slaveadresse ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
         If TWSR = &amp;amp;H18 Then                       {{vbcomment|Slave hat sich gemeldet}}&lt;br /&gt;
             I2cwbyte &amp;amp;H55                         {{vbcomment|Datenbyte ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
             If TWSR &amp;lt;&amp;gt; &amp;amp;H28 Then                  {{vbcomment|Byte erfolgreich übertragen}}&lt;br /&gt;
                 Print &amp;quot;Byte mit NACK quittiert !&amp;quot;&lt;br /&gt;
             End If&lt;br /&gt;
         Else&lt;br /&gt;
             Print &amp;quot;kein Slave !&amp;quot;&lt;br /&gt;
         End If&lt;br /&gt;
     Else&lt;br /&gt;
         Print &amp;quot;Fehler bei Start&amp;quot;&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Immer Stop, damit die Buspegel wieder stimmen}}&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print &amp;quot;E &amp;quot; ; Err                              {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 1500&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
Die Printausgaben im Else-Teil sind natürlich nur in der Demo nützlich, in der Praxis entweder den Else-Teil ganz weglassen, oder entsprechende Variablen setzen um den Fehler später zu bearbeiten.&lt;br /&gt;
&lt;br /&gt;
Eine einfachere Version einen Fehler frühzeitig zu erkennen, ist statt TWSR nur ERR auf 0 zu prüfen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Hardware USI ==&lt;br /&gt;
&lt;br /&gt;
Kleinere AVR Controller, die zwar kein TWI-Modul haben, aber [[I2C]] hardwaremäßig Unterstützen, haben das [[USI (Avr)|USI]]-Modul, die Ports für Data und Clock sind dabei vorgegeben. USI ist bei den meisten ATTinys und einigen ATMegas vorhanden, z.B. dem [[ATtiny2313|ATTiny2313]].&lt;br /&gt;
&lt;br /&gt;
Das [[USI (Avr)|USI]]-Modul kann evtl. als eine Art von TWI-Light angesehen werden, denn es ist nicht so komfortabel wie TWI, es muss intern noch viel in Software erledigt werden, weshalb es Performancemäßig auch keinen großen unterschied macht, ob man Software-I2C oder USI beim Master verwendet.&lt;br /&gt;
&lt;br /&gt;
Am einfachsten benutzt man die Lib, die unter [[#Weblinks|Weblinks]] aufgeführt ist, denn dann kann man die von Bascom vorgegebenen Befehle benutzen.&lt;br /&gt;
&lt;br /&gt;
 $regfile = &amp;quot;attiny2313.dat&amp;quot;                       {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                               {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600&lt;br /&gt;
 &amp;lt;font color=&amp;quot;#a01010&amp;quot;&amp;gt;&lt;br /&gt;
 $lib &amp;quot;i2c_usi.lbx&amp;quot;                                {{vbcomment|Für Hardware USI-I2C}}&lt;br /&gt;
 &lt;br /&gt;
 Config Scl = Portb.7                              {{vbcomment|Ports fuer IIC-Bus}}&lt;br /&gt;
 Config Sda = Portb.5&lt;br /&gt;
 {{vbcomment|Config I2cdelay &amp;amp;#061; 5                  ' je höher der Wert umso langsamer der Bus}}&lt;br /&gt;
 &lt;br /&gt;
 I2cinit&lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
 Const Pcf_write = &amp;amp;H40                            {{vbcomment|Slaveadresse}}&lt;br /&gt;
 Const Pcf_read = &amp;amp;H41&lt;br /&gt;
  &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;I2C-USI Demo mit PCF 8574&amp;quot;&lt;br /&gt;
 Print&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;HAA&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;H55&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
Mit ERR kann nach jedem gesendeten Byte abgefragt werden, ob es mit ACK quittiert wurde (=0), oder nicht (=1).&lt;br /&gt;
&lt;br /&gt;
Nach I2Cstart (auch I2CStop) kann ERR kontrolliert werden, ob das Start (bzw. Stop) auch auf den Bus abgesetzt werden konnte.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[Avr]] - Infos zu AVR allgemein&lt;br /&gt;
* [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]] - Details zu I2C&lt;br /&gt;
* [[TWI]] - Two-wire Serial Interface&lt;br /&gt;
* [[SPI]] - Serial Peripheral Interface&lt;br /&gt;
* [[TWI Praxis]] - Bascom-Beispiele für Hardware TWI&lt;br /&gt;
* [[TWI Praxis Multimaster]] - Bascom-Beispiele für Hardware TWI&lt;br /&gt;
* [[Bascom und USI-Kommunikation]] - Bascom-Beispiele für Hardware USI&lt;br /&gt;
* [[Bascom Soft-I2c Library]] - weitere Tipps zu I2C mit Bascom&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==WebLinks==&lt;br /&gt;
&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=26774] - Forum-Artikel, in dem eine [[Bascom]]-Lib vorgestellt wird, um die Bascom-I2C-Befehle mit dem USI-Modul als Master zu verwenden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Linux 80|Linux 80]] 02:08, 28. Okt 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Quellcode Bascom]]&lt;/div&gt;</summary>
		<author><name>Tuffig</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=RN-Control&amp;diff=12859</id>
		<title>RN-Control</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=RN-Control&amp;diff=12859"/>
				<updated>2007-10-30T18:47:54Z</updated>
		
		<summary type="html">&lt;p&gt;Tuffig: /* Hier die Leistungsmerkmale auf einen Blick: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ein bewährtes Microcontrollerboard, das wie das RNBFRA-Board in der Roboternetz-Community infolge einer Diskussion entstand. Es sollte ein Board werden, das ein gutes Preis-Leistungs-Verhältnis bietet und für vielfältige Aufgaben geeignet ist. &lt;br /&gt;
Das Vorhaben ist dank der zahlreichen Anregungen gut gelungen, das Board gibt es inzwischen nicht nur als Bauanleitung mit Platine, sondern auch als Bausatz und sogar Fertigmodul.&lt;br /&gt;
Es hat sich als preiswertes Universalboard für Roboter, Steuerungsaufgaben etc. als auch als ideales Einsteigerboard einen guten Namen im Roboternetz gemacht, daher gibt es für dieses Board auch ein eigenes Unterforum im Roboternetz.  &lt;br /&gt;
Es gibt inzwischen unzählige Anwendungen, die mit RN-Control umgesetzt wurden.&lt;br /&gt;
Trotz günstigem Preis ist ein sehr flexibles Board für unzählige Anwendungsmöglichkeiten entstanden. Über den I2C-Bus stehen zahlreiche Erweiterungsboards zur Verfügung, so können beispielsweise die gleichen I2C-Erweiterungen wie beim großen RNBFRA-Board kombiniert werden (Relaiskarte, Sprachausgabe usw.) Roboternetz &lt;br /&gt;
&lt;br /&gt;
[[Bild:rncontrol1.4diagramm.jpg|thumb|Funktionen des Boards]]&lt;br /&gt;
&lt;br /&gt;
[[Bild:rncontrol1.4schaltplan.gif|thumb|Schaltplan zum Board]]&lt;br /&gt;
&lt;br /&gt;
[[Bild:rncontrol1.4bestückungsplan.gif|thumb|Bestückungsplan zum Board]]&lt;br /&gt;
&lt;br /&gt;
Besonders viel Wert wurde auch auf den einfachen Aufbau und viele Experimentier- und Einsatzmöglichkeiten gelegt. Mit diesem Board läßt sich u.a. schon ein recht ausgereifter Roboter konstruieren. Ultraschallsensoren, Infrarot-Entfernungssensoren, Motoren u.v.m. können direkt angeschlossen werden. Da das Board auch in der Community Roboternetz recht beliebt ist, findet man dort auch viele Tips und Programme. &lt;br /&gt;
&lt;br /&gt;
[[http://www.robotikhardware.de/bilder/rncontrol14diagrammmittel.jpg Diagramm hier]]&lt;br /&gt;
&lt;br /&gt;
==Hier die Leistungsmerkmale auf einen Blick:==&lt;br /&gt;
&lt;br /&gt;
*Wahlweise 8 oder 16 MHz Taktfrequenz (beide Quarze werden mitgeliefert, 16 MHz bereits eingesteckt) &lt;br /&gt;
*Schneller AVR Mega 32  Mikrocontroller,32K Speicher, 2K Ram und 1K EEPROM), 32 programmierbare I/O Pins,8 AD Ports u.v.m. &lt;br /&gt;
*8 Leuchtdioden per DIP-Schalter deaktivierbar und anderen Ports per Steckbrücke beliebig zuzuordnen &lt;br /&gt;
*alle Portleitungen sind über Stecker nach außen geführt. Die Steckernorm entspricht der Roboternetz-Definition als auch der des Atmel Entwicklungsboards STK500 &lt;br /&gt;
*alle Ports sowie +5V und GND sind zusätzlich über Steckbuchsen erreichbar. Ideal zum Experimentieren, da einfach Drähte (ca. 0,5mm) eingesteckt werden (kein Löten oder Schrauben). So können einfach andere LEDs zugeordnet werden oder ein Steckbrett verbunden werden &lt;br /&gt;
*Der wichtige Port A (wahlweise 8 digitale oder analoge Ein- o. Ausgänge) ist zusätzlich noch über eine Qualitätssteckklemme mit Hebel herausgeführt &lt;br /&gt;
*Motortreiber ca. 1 A belastbar - für zwei Getriebemotoren oder 1 Schrittmotor. Dieser kann auch für andere Zwecke (Relaisansteuerung, Lämpchen etc.) genutzt oder einfach entfernt werden &lt;br /&gt;
*Integrierter programmierbarer Mini-Lautsprecher, um Töne auszugeben &lt;br /&gt;
*1 Reset-Taster &lt;br /&gt;
*5 Taster für beliebige Verwendung. Sie belegen nur einen analogen Port! &lt;br /&gt;
*5 V Spannungsstabilisierung mit 2 A Belastbarkeit, auch herausgeführt für Erweiterungen; Eingangsspannung gegen Verpolung geschützt &lt;br /&gt;
*RS232 mit normgerechtem Pegelwandler (MAX232) - PC direkt anschließbar &lt;br /&gt;
*Batteriespannung kann im Programm abgefragt werden &lt;br /&gt;
*ISP-Programmierschnittstelle für übliche AVR-Programmieradapter (10polig) &lt;br /&gt;
*Betriebsspannung wahlweise zwischen 7 und 18V (empfohlen 7 bis 14 V) - wahlweise auch höhere Motorspannung bis 24 V möglich) &lt;br /&gt;
*Sehr kompakt, nur halbes Europaformat nach Roboternetz-Norm (ca. 100x75mm) &lt;br /&gt;
*I2C-Bus, über den zahlreiche Erweiterungsplatinen anschließbar sind (z.B. Sprachausgabe RN-Speak, Relaisboard RN-Relais, Servoboards, LCDs uvm.) &lt;br /&gt;
*Programmierbar in zahlreichen Sprachen, z.B. Basic (BASCOM Compiler, eingeschränkt bis 4K wird mitgeliefert), C (C-Compiler GCC wird mitgeliefert), Assembler, Pascal &lt;br /&gt;
*Deutsche Doku mit Basic-Programmbeispiel &lt;br /&gt;
*Preiswerter Bausatz erhältlich - einfacher Aufbau &lt;br /&gt;
*Kein Starter- oder Applikationsboard notwendig - bereits alles integriert! &lt;br /&gt;
*alle wichtigen Bauteile gesockelt, somit auch bei falscher Beschaltung durch Einsteiger immer kostengünstig reparierbar (einfach neues IC einstecken) &lt;br /&gt;
&lt;br /&gt;
http://www.robotikhardware.de/bilder/rncontro4.jpg&lt;br /&gt;
&lt;br /&gt;
==Belegung der RN-Control Steckklemmen==&lt;br /&gt;
Um auch schnell und praktisch mit RN-Control experimentieren zu können, verfügt dieses Board über Steckklemmen die alle Ports herausführen. 0,5mm Drähte lassen sich dort direkt einstecken, so das Sensoren und dergleichen schnell und einfach verdrahtet werden können. Die genaue Belegung lässt sich in nachfolgendem Ausschnitt aus dem Bestückungsplan gut entnehmen.&lt;br /&gt;
&lt;br /&gt;
[[Bild:rncontrolsteckklemmen.gif|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Steckerbelegung und Jumper-Funktionen==&lt;br /&gt;
Erläuterung der Anschlüsse, Regler und Kurzschlussbrücken&lt;br /&gt;
&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''Anschluss-Bezeichnung'''&lt;br /&gt;
|'''Erläuterung'''&lt;br /&gt;
|-&lt;br /&gt;
|'''Port A'''&lt;br /&gt;
|Digitaler I/O und analoger Port (PA 0 bis PA7 und ADC0 bis ADC7)&lt;br /&gt;
Über  eine Steckklemme werden hier die 8 Portleitungen PA0 bis PA 7 zur Verfügung gestellt. PA7 befindet sich dabei ganz links und PA0 ganz rechts. Anschlußdrähte können einfach eingesteckt werden, indem man mit einem Kugelschreiber oder Schraubenziehen den oberen weißen Hebel etwas nach unten drückt.&lt;br /&gt;
Die Ports PA7 bis PA0 können sowohl als normaler I/O-Port  (Ein- und Ausgabeport) oder als AD-Port´s programmiert werden. Somit könnten also auch bis zu 8 Spannungen quasi gleichzeitig gemessen werden. &lt;br /&gt;
&lt;br /&gt;
Ist der Kurzschlusstecker  UREF eingesteckt, dann können Spannungen bis zu 5V gemessen werden. Ist UREF offen, dann können Spannungen nur bis 2,5V gemessen werden. Durch geeignete Spannungsteiler kann der Meßbereich natürlich beliebig erhöht werden.&lt;br /&gt;
&lt;br /&gt;
Achtung: Die zulässige Höchstspannung 2,5V oder 5V darf am Port nicht überschritten werden, dieses würde den Port zerstören! &lt;br /&gt;
&lt;br /&gt;
Vorbelegung:&lt;br /&gt;
Port  PA7 wird auch für die Tastenabfrage genutzt. indem über einen Spannungsteiler verschiedene Spannungen per Tastendruck angelegt werden (siehe Schaltplan). &lt;br /&gt;
Solange keine Taste gedrückt ist, ist dieser jedoch frei Verfügbar.&lt;br /&gt;
Port PA6 wird über einen Spannungsteiler (22k und 5,1K) zur Batteriespannungsmessung benutzt  (siehe Schaltplan und Demoprogramm) wenn der Kurzschlusstecker UMESS eingesteckt ist.  Durch entfernen dieses Steckers steht der Port zur freien Verfügung.&lt;br /&gt;
&lt;br /&gt;
Der komplette Port steht auch nochmals über die Buchsenleiste JP2 zur Verfügung. Auch dort können Drähte zum experimentieren eingesteckt werden (möglichst 0,6mm²). &lt;br /&gt;
|-&lt;br /&gt;
|'''Port B'''&lt;br /&gt;
|Digitale I/O Port B  (PB0 bis PB 7)&lt;br /&gt;
Über einen Wannenstecker werden gemäß der Roboternetz-Definition 8 I/O Portleitungen mit Sonderfunktionen als auch GND und +5V bereitgestellt. &lt;br /&gt;
&lt;br /&gt;
Die genaue Belegung sieht wie folgt aus:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Pin 1   PB0  /  T0 / XCL / wird vom Motortreiber für Motor 2 Kanal 1 genutzt&lt;br /&gt;
Pin 2   PB1  /  T1 / wird vom Motortreiber für Motor 2 Kanal 2 genutzt&lt;br /&gt;
Pin 3   PB2  /  AIN0 / INT2  / wird auch vom I2C-Bus genutzt&lt;br /&gt;
Pin 4   PB3  /  AIN1 / OC0&lt;br /&gt;
Pin 5   PB4  /  SS&lt;br /&gt;
Pin 6   PB5  /  MOSI / wird auch vom ISP Anschluss genutzt&lt;br /&gt;
Pin 7   PB6  /  MISO / wird auch  vom ISP Anschluss genutzt&lt;br /&gt;
Pin 8   PB7  /  SCK / wird auch  vom ISP Anschluss genutzt&lt;br /&gt;
Pin 9   GND&lt;br /&gt;
Pin 10  +5V&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Durch entfernen des Motortreiber IC´s aus der Fassung, steht PB0 und PB1 zur freien Verfügung.&lt;br /&gt;
&lt;br /&gt;
Der komplette Port steht auch nochmals über die Buchsenleiste JP3 zur Verfügung. Auch dort können Drähte zum experimentieren eingesteckt werden (möglichst 0,6mm²).&lt;br /&gt;
|-&lt;br /&gt;
|'''Port C'''&lt;br /&gt;
|Digitale I/O Port C  (PC0 bis PC 7)&lt;br /&gt;
Über einen Wannenstecker werden gemäß der Roboternetz-Definition 8 I/O Portleitungen mit Sonderfunktionen als auch GND und +5V bereitgestellt. &lt;br /&gt;
&lt;br /&gt;
Die genaue Belegung sieht wie folgt aus:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Pin 1   PC0  /  SCL wird vom I2C-Bus genutzt&lt;br /&gt;
Pin 2   PC1  /  SDA wird vom I2C-Bus genutzt&lt;br /&gt;
Pin 3   PC2  /  TCK&lt;br /&gt;
Pin 4   PC3  /  TMS&lt;br /&gt;
Pin 5   PC4  /  TDO&lt;br /&gt;
Pin 6   PC5  /  TDI&lt;br /&gt;
Pin 7   PC6  /  TOSC1 / wird vom Motortreiber für Motor 1 Kanal 1 genutzt&lt;br /&gt;
Pin 8   PC7  /  TOSC2 / wird vom Motortreiber für Motor 1 Kanal 2 genutzt&lt;br /&gt;
Pin 9   GND&lt;br /&gt;
Pin 10  +5V&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Über den 8 fachen DIP Schalter können den Ports auch LED´s zugeschaltet werden! Die LED´s leuchten wenn Port LOW-Zustand annimmt!&lt;br /&gt;
&lt;br /&gt;
Durch entfernen des Motortreiber IC´s aus der Fassung, steht PC6 und PC7 zur freien Verfügung.&lt;br /&gt;
Der komplette Port steht auch nochmals über die Buchsenleiste JP4 zur Verfügung. Auch dort können Drähte zum experimentieren eingesteckt werden (möglichst 0,6mm²).&lt;br /&gt;
|-&lt;br /&gt;
|'''Port D'''&lt;br /&gt;
|Digitale I/O Port D  (PD0 bis PD 7)&lt;br /&gt;
Über einen Wannenstecker werden gemäß der Roboternetz-Definition 8 I/O Portleitungen mit Sonderfunktionen als auch GND und +5V bereitgestellt. &lt;br /&gt;
&lt;br /&gt;
Die genaue Belegung sieht wie folgt aus:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Pin 1   PD0  /  RXD / wird für RS232 Schnittstelle genutzt&lt;br /&gt;
Pin 2   PD1  /  TXD  / wird für RS232 Schnittstelle genutzt&lt;br /&gt;
Pin 3   PD2  /  INT0&lt;br /&gt;
Pin 4   PD3  /  INT1 &lt;br /&gt;
Pin 5   PD4  /  OC1B  / wird für PWM Motor 1 benutzt (Geschwindigkeitsregelung)&lt;br /&gt;
Pin 6   PD5  /  OC1A  / wird für PWM Motor 2 benutzt (Geschwindigkeitsregelung)&lt;br /&gt;
Pin 7   PD6  /  ICP&lt;br /&gt;
Pin 8   PD7  /  OC2&lt;br /&gt;
Pin 9   GND&lt;br /&gt;
Pin 10  +5V&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Durch entfernen des Motortreiber IC´s aus der Fassung, steht PD4 und PD5 zur freien Verfügung.&lt;br /&gt;
Der komplette Port steht auch nochmal über die Buchsenleiste JP5 zur Verfügung. Auch dort können Drähte zum experimentieren eingesteckt werden (möglichst 0,6mm²).&lt;br /&gt;
|-&lt;br /&gt;
|'''I2C-Bus'''&lt;br /&gt;
|I2C-Bus&lt;br /&gt;
Über diesen Bus lassen sich zahlreiche Erweiterungen an dieses Board anschließen. Zum Beispiel werden auf der Seite robotikhardware.de passende Boards mit Sprachausgabe, Relais, Schrittmotorsteuerung etc. angeboten.&lt;br /&gt;
Aber auch dieses Board kann selbst als Slave-Board, also als Erweiterung an ein anderes Hauptboard angeschlossen werden.&lt;br /&gt;
Der I2C-Bus benötig nur 2 Leitungen für alle Funktionen. Entsprechend der Roboternetz-Norm wird hier ein 2x5 poliger Stecker angeschlossen. Die Belegung entspricht exakt der anderer Roboternetz Boards.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Pin 1 SCL (Taktleitung)&lt;br /&gt;
Pin 3 SDA (Datenleitung)&lt;br /&gt;
Pin 5 +5V&lt;br /&gt;
Pin 7 +5V&lt;br /&gt;
Pin 9  Batteriespannung&lt;br /&gt;
Pin 2,4,6,8 GND&lt;br /&gt;
Pin 10  INT&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
INT - Diese Leitung kann von allen I2C-Bus Erweiterungen genutzt &lt;br /&gt;
werden um den Hauptcontroller darüber zu informieren das sich Daten (z.B. von Sensoren) verändert haben. In diesem Fall wird die Leitung solange auf Masse gelegt bis der entsprechende  I2C-Baustein ausgelesen wird.&lt;br /&gt;
Die Controller muß also immer alle I2C-Bausteine auslesen solange diese Leitung auf Masse liegt. Diese Leitung ist mit Port PD2 verbunden&lt;br /&gt;
&lt;br /&gt;
Die PIN´s 5,7,9 und 10 können über  herausnehmbare Kurzschlussbrücken (Jumper JP6) vom Board getrennt werden. Dies ist zum Beispiel dann notwendig, wenn bereits ein anderes Masterboard die Spannungen auf den Bus legt. Es darf immer nur ein Board die Spannungen bereitstellen.&lt;br /&gt;
|-&lt;br /&gt;
|'''ISP'''&lt;br /&gt;
|ISP – IN SYSTEM PROGRAMMING&lt;br /&gt;
Über diesen Anschluß kann der  Controller auf dem Sprachboard mit einem Standard ISP-Kabel direkt an einen Parallelport des PC´s angeschlossen und programmiert werden.&lt;br /&gt;
Die Belegung des ISP-Anschlusses ist zu dem weit verbreitetet STK200 Programmier Dongle kompatibel. Ein entsprechender Dongle kann man sich entweder selber basteln (siehe Artikel „ARV Einstieg leicht gemacht“ unter www.roboternetz.de) oder fertig bestellen (z.B. www.robotikhardware.de). &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Pin 1 MOSI&lt;br /&gt;
Pin 2 VCC&lt;br /&gt;
Pin 3 Nicht belegt&lt;br /&gt;
Pin 4 GND&lt;br /&gt;
Pin 5 RESET&lt;br /&gt;
Pin 6 GND&lt;br /&gt;
Pin 7 SCK&lt;br /&gt;
Pin 8 GND&lt;br /&gt;
Pin 9 MISO&lt;br /&gt;
Pin 10 GND &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|'''Power'''&lt;br /&gt;
|Spannungsversorgung&lt;br /&gt;
Über diese Schraubklemme wird das Board mit Spannung versorgt. Es reicht eine unstabilisierte Gleichspannung von 7 bis 14V aus (max. 18V wenn Kühlkörper verwendet wird)&lt;br /&gt;
+ und – sind auf der Platine markiert. Das Board ist jedoch auch gegen ein verpolen geschützt, so das nichts kaputt geht!&lt;br /&gt;
|-&lt;br /&gt;
|'''Motoren'''&lt;br /&gt;
|Motoren&lt;br /&gt;
Über diese 4 polige Schraubklemme können zwei Getriebemotoren (jeweils die beiden linken oder rechten Kontakte) oder ein Schrittmotor angeschlossen werden. &lt;br /&gt;
Der Motortreiber kann jedoch auch für andere Dinge genutzt werden, z.B zum Ansteuern von Relais, Lämpchen etc. verwendet werden. Die Belastbarkeit liegt bei 1A.  Sollen größere Motoren angeschlossen werden,  so kann z.B. über den I2C-Port eine andere Endstufe angeschlossen werden. &lt;br /&gt;
|-&lt;br /&gt;
|'''JP6'''&lt;br /&gt;
|I2C-Bus Belegung&lt;br /&gt;
Über drei Kurzschlussstecker können wahlweise die Bateriespannung (UB), +5V sowie INT mit dem I2C-Bus verbunden werden. Wenn INT nicht benötigt wird, kann man diesen Jumper offen lassen. Somit hat man einen Port zusätzlich frei zur Verfügung&lt;br /&gt;
Möchte man das Board über den I2C-Bus mit Spannung versorgen, dann kann man UB oder +5V Jumper einstecken. In diesem Fall braucht/darf keine Spannung an dem Power Schraubklemen angelegt werden. Möchte man umgekehrt andere Boards über den I2C-Bus mit Spannung versorgen, dann müssen die Jumper UB und/oder +5V eingesteckt werden. &lt;br /&gt;
Durch diesen Jumper ist man für alle Fälle gerüstet. Bei älteren RN-Control Versionen mußte man dazu noch das Kabel ändern.&lt;br /&gt;
|-&lt;br /&gt;
|'''JP8'''&lt;br /&gt;
|Über diesen Stecker kann die stabilisierte 5V Logikspannung für Erweiterungen oder Experimente entnommen werden. Wird mehr als 500mA entnommen, so sollte der Spannungsregler  mit einem kleinen Kühlkörper versehen werden.&lt;br /&gt;
|-&lt;br /&gt;
|'''UREF'''&lt;br /&gt;
|Referenzspannung&lt;br /&gt;
Über eine Kurzschlussstecker kann hier die Referenzspannung von 5V eingestellt werden. Wird der Stecker entfernt, so kann an den analogen Ports nur bis 2,5V gemessen werden (jedoch mit höherer Genauigkeit). &lt;br /&gt;
Sicherheitshalber sollten Sie den Stecker anfangs eingesteckt lassen!  Wird er entfernt, so sollte man daran denken das auch die Batteriespannung über einen analogen Port gemessen wird. Diese darf dann nicht viel höher als 13V  sein!&lt;br /&gt;
|-&lt;br /&gt;
|'''UMOT'''&lt;br /&gt;
|Motorspannung&lt;br /&gt;
Wenn dieser Kurzschlussstecker eingesteckt wird, dann wird die volle Batteriespannung auch für die Motoren benutzt. Ansonsten könnte man über einen PIN dieses Jumpers auch eine höhere Versorgungsspannung für die Motoren nutzen. Dazu sollte sie aber nochmals in den Schaltplan schaun.&lt;br /&gt;
In der Regel sollte hier ein Jumper eingesteckt sein!&lt;br /&gt;
|-&lt;br /&gt;
|'''UMESS'''&lt;br /&gt;
|Batteriespannungsmessung&lt;br /&gt;
Wenn diese Kurzschlussbrücke gesteckt ist, dann wird über Port PA6 die Batteriespannung überwacht. Ansonsten ist der Port frei!&lt;br /&gt;
|-&lt;br /&gt;
|'''S1'''&lt;br /&gt;
|DIP Schalter&lt;br /&gt;
Mit einem kleinen Schraubenzieher kann über diesen 8 poligen Schalter den Portleitungen PC0 bis PC7 eine LED zugeschaltet werden. Die LED´s leuchten immer dann wenn der Port LOW  (0 Pegel) führt.&lt;br /&gt;
Wenn die LED auf Off geschaltet wird, so kann die LED über eine Drahtbrücke von JP7 mit einem anderen Port verbunden werden.&lt;br /&gt;
|-&lt;br /&gt;
|'''RS232'''&lt;br /&gt;
|PC kompatible RS232 Schnittstelle&lt;br /&gt;
Über ein Adapterkabel kann die serielle Schnittstelle des PC direkt mit dem Board verbunden werden. Dies ist dann sinnvoll, wenn Fehler in Programmen gesucht . Einfache PRINT Anweisungen werden von einem Terminalprogramm angezeigt.&lt;br /&gt;
Hier kann Hyperterminal von Windows oder das eingebaute Terminalprogramm von Bascom empfohlen werden.&lt;br /&gt;
&lt;br /&gt;
Die Belegung ist kompatibel zum Conrad Roboter CCRP5:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Pin 1 RX&lt;br /&gt;
Pin 2 GND&lt;br /&gt;
Pin 3 TX&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ein geeignetes Anschlußkabel kann schnell selbst angefertigt werden oder gibt  es bei robotikhardware.de bereits fertig&lt;br /&gt;
|-&lt;br /&gt;
|'''JP7'''&lt;br /&gt;
|Über diese Buchse sind alle LED´s ganz einfach durch Einstecken eines Drahtes beschaltbar.&lt;br /&gt;
Bedenken muß man dabei das die Anode über einen Vorwiderstand immer mit 5V verbunden ist. Die LED leuchtet also nur wenn sie mit der Drahtbrücke auf GND bzw. einen Port mit 0 Pegel gelegt wird. &lt;br /&gt;
|-&lt;br /&gt;
|'''JP1'''&lt;br /&gt;
|Buchsenleiste die dreimal +5V und drei mal GND für Experimente bereitstellt&lt;br /&gt;
|-&lt;br /&gt;
|'''JP2'''&lt;br /&gt;
|Buchsenleiste die den gesamten Port A für steckbare Drähte bereitstellt&lt;br /&gt;
|-&lt;br /&gt;
|'''JP3'''&lt;br /&gt;
|Buchsenleiste die den gesamten Port B für steckbare Drähte bereitstellt&lt;br /&gt;
|-&lt;br /&gt;
|'''JP4'''&lt;br /&gt;
|Buchsenleiste die den gesamten Port C für steckbare Drähte bereitstellt&lt;br /&gt;
|-&lt;br /&gt;
|'''JP5'''&lt;br /&gt;
|Buchsenleiste die den gesamten Port D für steckbare Drähte bereitstellt&lt;br /&gt;
|-&lt;br /&gt;
|'''TASTER T1 bis T5'''&lt;br /&gt;
|Stehen zur freien Verfügung&lt;br /&gt;
Die Abfrage ist im Demoprogramm beschrieben&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Stückliste==&lt;br /&gt;
 Bauteil Wert       Beschreibung                   Reichelt Best.Nr.&lt;br /&gt;
 C1      100n       Keramik Kondensator            KERKO100N&lt;br /&gt;
 C2      100n       Keramik Kondensator            KERKO100N   &lt;br /&gt;
 C3      22pf       Keramik Kondensator            KERKO-500 22p           &lt;br /&gt;
 C4      22pf       Keramik Kondensator            KERKO-500 22p          &lt;br /&gt;
 C5      4,7uF      Elko                           SM 4,7/50RAD           &lt;br /&gt;
 C6      4,7uF      Elko                           SM 4,7/50RAD           &lt;br /&gt;
 C7      4,7uF      Elko                           SM 4,7/50RAD           &lt;br /&gt;
 C8      4,7uF      Elko                           SM 4,7/50RAD           &lt;br /&gt;
 C9      1uF        Elko                           SM 1,0/63RAD           &lt;br /&gt;
 C10     100n       Keramik Kondensator            KERKO100N              &lt;br /&gt;
 C11     100n       Keramik Kondensator            KERKO100N              &lt;br /&gt;
 C12     100n       Keramik Kondensator            KERKO100N              &lt;br /&gt;
 C13     1000uF     Elko                           RAD 1000/35            &lt;br /&gt;
 C14     100n       Keramik Kondensator            KERKO100N              &lt;br /&gt;
 C15     100n       Keramik Kondensator            KERKO100N              &lt;br /&gt;
 C16     100n       Keramik Kondensator            KERKO100N              &lt;br /&gt;
 C17     220uF      Elko                           RAD 220/35             &lt;br /&gt;
 C18     100n       Keramik Kondensator            KERKO100N              &lt;br /&gt;
 D1      1N4148     Diode                          1n 4148                &lt;br /&gt;
 D2      BYV27      Diode                          BYV 27/200             &lt;br /&gt;
 I2C-BUS I2C        Wannenbuchse                   WSL 10G                &lt;br /&gt;
 IC1     MAX232     RS232 Treiber                  MAX 232 CPE             &lt;br /&gt;
 IC2     7805       Spannungsregler                78S05                  &lt;br /&gt;
 IC3     L293D      Motortreiber                   L 293 D                &lt;br /&gt;
 IC4     MEGA16-P   Atmel Mega 16 oder 32          ATMEGA 16-16           &lt;br /&gt;
 ISP     AVR-ISP    Wannenbuchse                   WSL 10G                &lt;br /&gt;
 JP1                Kontaktbuchse (manuell kürzen) SPL20                  &lt;br /&gt;
 JP2                Kontaktbuchse (manuell kürzen) SPL 20                 &lt;br /&gt;
 JP3                Kontaktbuchse (manuell kürzen) SPL 20                  &lt;br /&gt;
 JP4                Kontaktbuchse (manuell kürzen) SPL 20                 &lt;br /&gt;
 JP5                Kontaktbuchse (manuell kürzen) SPL 20                 &lt;br /&gt;
 JP6                Stiftleiste                    Stiftl. 2x50g (teilen) &lt;br /&gt;
 JP7                Kontaktbuchse (manuell kürzen) SPL 20                 &lt;br /&gt;
 JP8                Stiftleiste                    LU 2,5 MS2             &lt;br /&gt;
 LED1               Leuchtdiode Low                LED 3MM 2MA GN         &lt;br /&gt;
 LED2               Leuchtdiode Low                LED 3MM 2MA GN         &lt;br /&gt;
 LED3               Leuchtdiode Low                LED 3MM 2MA GN         &lt;br /&gt;
 LED4               Leuchtdiode Low                LED 3MM 2MA GN         &lt;br /&gt;
 LED5               Leuchtdiode Low                LED 3MM 2MA GN         &lt;br /&gt;
 LED6               Leuchtdiode Low                LED 3MM 2MA GN         &lt;br /&gt;
 LED7               Leuchtdiode Low                LED 3MM 2MA GN         &lt;br /&gt;
 LED8               Leuchtdiode Low                LED 3MM 2MA GN         &lt;br /&gt;
 MOTOREN            Schraubklemme 4 polig          AKL 101-04             &lt;br /&gt;
 PORTA              Steckklemme 8 polig            WAGO 233-508           &lt;br /&gt;
 PORTB              Wannenbuchse                   WSL 10G                &lt;br /&gt;
 PORTC              Wannenbuchse                   WSL 10G                &lt;br /&gt;
 PORTD              Wannenbuchse                   WSL 10G                &lt;br /&gt;
 POWER              Schraubklemme 2 polig          AKL 101-02              &lt;br /&gt;
 Q1                 Quarz 16 Mhz                   16-HC18                &lt;br /&gt;
 R1      100k       Widerstand 100k                1/4W 100k              &lt;br /&gt;
 R2      1k         Widerstand 1k                  1/4W 1k                &lt;br /&gt;
 R3      10k        Widerstand 10k                 1/4W 10k               &lt;br /&gt;
 R4      1k         Widerstand 1k                  1/4W 1k                &lt;br /&gt;
 R5      1k         Widerstand 1k                  1/4W 1k                &lt;br /&gt;
 R6      1k         Widerstand 1k                  1/4W 1k                &lt;br /&gt;
 R7      1k         Widerstand 1k                  1/4W 1k                &lt;br /&gt;
 R8      1k         Widerstand 1k                  1/4W 1k                &lt;br /&gt;
 R9      22k        Widerstand 22k                 1/4W 22k               &lt;br /&gt;
 R10     5,1k       Widerstand 5,1k                1/4W 5,1k              &lt;br /&gt;
 R11     10k        Widerstand 10k                 1/4W 10k               &lt;br /&gt;
 R12     10k        Widerstand 10k                 1/4W 10k               &lt;br /&gt;
 R13     10k        Widerstand 10k                 1/4W 10k               &lt;br /&gt;
 R14     10k        Widerstand 10k                 1/4W 10k               &lt;br /&gt;
 RESET   TASTER3301 Minitaster liegend             TASTER 3301            &lt;br /&gt;
 RN1                Widerstandsnetzwerk            SIL 9-8 1,0k           &lt;br /&gt;
 RS232              Stiftleiste 3 polig            LU 2,5 MS3             &lt;br /&gt;
 S1                 DIP Schalter 8 polig           NT08                   &lt;br /&gt;
 SPEAKER F/CM12P    Mini Piezo Lautsprecher        SUMMER EPM 121         &lt;br /&gt;
 T1      TASTER3301 Minitaster liegend             TASTER 3301            &lt;br /&gt;
 T2      TASTER3301 Minitaster liegend             TASTER 3301            &lt;br /&gt;
 T3      TASTER3301 Minitaster liegend             TASTER 3301            &lt;br /&gt;
 T4      TASTER3301 Minitaster liegend             TASTER 3301            &lt;br /&gt;
 T5      TASTER3301 Minitaster liegend             TASTER 3301            &lt;br /&gt;
 UMESS              Stiftleiste                    LU 2,5 MS2             &lt;br /&gt;
 UMOT               Stiftleiste                    LU 2,5 MS2             &lt;br /&gt;
 UREF               Stiftleiste                    LU 2,5 MS2&lt;br /&gt;
&lt;br /&gt;
==Basic Beispieltestprogramm==&lt;br /&gt;
Das gleiche Demo findet man jetzt auch für C unter &amp;quot;[[RN-Control Demoprogramm in C]]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'################################################### &lt;br /&gt;
'rncontroltest.BAS &lt;br /&gt;
'für &lt;br /&gt;
'RoboterNetz Board RN-CONTROL ab Version 1.1 &lt;br /&gt;
'Das neue preiswerte Controllerboard zum Experimentieren &lt;br /&gt;
&lt;br /&gt;
' Achtung: &lt;br /&gt;
' Diese Demo ist mit Bascom Compiler 1.11.7.7 getestet &lt;br /&gt;
&lt;br /&gt;
' &lt;br /&gt;
'Aufgabe: &lt;br /&gt;
' Dieses Testprogramm testet gleich mehrere Eigenschaften auf dem Board &lt;br /&gt;
' Den verschiedenen Tasten sind bestimmte Funktionen zugeordnet &lt;br /&gt;
' Taste 1: Zeigt Batteriespannung über RS232 an &lt;br /&gt;
' Taste 2: Angeschlossene Motoren beschleunigen und abbremsen &lt;br /&gt;
' Taste 3: Einige Male Lauflicht über LEDs anzeigen. Am I2C-Bus &lt;br /&gt;
'          darf in diesem Moment nichts angeschlossen sein &lt;br /&gt;
' Taste 4: Zeigt analoge Messwerte an allen Port A PINs über RS232 an &lt;br /&gt;
''Taste 5: Zeigt digitalen I/O Zustand von PA0 bis PA5 an &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
' Sehr gut kann man aus dem Demo auch entnehmen wie Sound ausgegeben wird, &lt;br /&gt;
' wie Tasten abgefragt werden und wie Subroutinen und Funktionen angelegt werden &lt;br /&gt;
&lt;br /&gt;
'Autor: Frank &lt;br /&gt;
'####################################################### &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Declare Sub Batteriespannung() &lt;br /&gt;
Declare Sub Motortest() &lt;br /&gt;
Declare Sub Lauflicht() &lt;br /&gt;
Declare Sub Showporta() &lt;br /&gt;
Declare Sub Showdigitalporta() &lt;br /&gt;
Declare Function Tastenabfrage() As Byte &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
$regfile = &amp;quot;m32def.dat&amp;quot; &lt;br /&gt;
' bei Mega 16 $regfile = &amp;quot;m16def.dat&amp;quot; &lt;br /&gt;
$framesize = 32 &lt;br /&gt;
$swstack = 32 &lt;br /&gt;
$hwstack = 32 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dim I As Integer &lt;br /&gt;
Dim N As Integer &lt;br /&gt;
Dim Ton As Integer &lt;br /&gt;
&lt;br /&gt;
$crystal = 16000000                           'Quarzfrequenz &lt;br /&gt;
$baud = 9600 &lt;br /&gt;
&lt;br /&gt;
Config Adc = Single , Prescaler = Auto        'Für Tastenabfrage und Spannungsmessung &lt;br /&gt;
&lt;br /&gt;
Config Pina.7 = Input                         'Für Tastenabfrage &lt;br /&gt;
Porta.7 = 1                                   'Pullup Widerstand ein &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Const Ref = 5 / 1023                          'Für Batteriespannungsberechnung &lt;br /&gt;
&lt;br /&gt;
Dim Taste As Byte &lt;br /&gt;
Dim Volt As Single &lt;br /&gt;
&lt;br /&gt;
' Für Motorentest &lt;br /&gt;
'Ports für linken Motor &lt;br /&gt;
Config Pinc.6 = Output                       'Linker Motor Kanal 1 &lt;br /&gt;
Config Pinc.7 = Output                       'Linker Motor Kanal 2 &lt;br /&gt;
Config Pind.4 = Output                       'Linker Motor PWM &lt;br /&gt;
'Ports für rechten Motor &lt;br /&gt;
Config Pinb.0 = Output                       'Rechter Motor Kanal 1 &lt;br /&gt;
Config Pinb.1 = Output                       'Rechter Motor Kanal 2 &lt;br /&gt;
Config Pind.5 = Output                       'Rechter Motor PWM &lt;br /&gt;
Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down &lt;br /&gt;
Pwm1a = 0 &lt;br /&gt;
Pwm1b = 0 &lt;br /&gt;
Tccr1b = Tccr1b Or &amp;amp;H02                      'Prescaler = 8 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I = 0 &lt;br /&gt;
Sound Portd.7 , 400 , 450                    'BEEP &lt;br /&gt;
Sound Portd.7 , 400 , 250                    'BEEP &lt;br /&gt;
Sound Portd.7 , 400 , 450                    'BEEP &lt;br /&gt;
Print &lt;br /&gt;
Print &amp;quot;**** RN-CONTROL 1.4 *****&amp;quot; &lt;br /&gt;
Print &amp;quot;Das neue Experimentier- und Roboterboard&amp;quot; &lt;br /&gt;
Print &amp;quot;Weitere passende Zusatzboards bei www.robotikhardware.de&amp;quot; &lt;br /&gt;
Print &lt;br /&gt;
Do &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   Taste = Tastenabfrage() &lt;br /&gt;
   If Taste &amp;lt;&amp;gt; 0 Then &lt;br /&gt;
&lt;br /&gt;
      Select Case Taste &lt;br /&gt;
         Case 1 &lt;br /&gt;
            Call Batteriespannung    'Taste 1 Zeigt Bateriespannung über RS232 an &lt;br /&gt;
         Case 2 &lt;br /&gt;
            Call Motortest           'Taste 2 Motoren beschleunigen und abbremsen &lt;br /&gt;
         Case 3 &lt;br /&gt;
            Call Lauflicht           'Einige Male Lauflicht über LEDs anzeigen. &lt;br /&gt;
                                     'Am I2C-Port darf in diesem Moment nichts angeschlossen sein &lt;br /&gt;
         Case 4 &lt;br /&gt;
            Call Showporta           'Zeigt Messwerte an allen Port A PINs &lt;br /&gt;
         Case 5 &lt;br /&gt;
            Call Showdigitalporta    'Zeigt digitalen I/O Zustand von PA0 bis PA5 an &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      End Select &lt;br /&gt;
      Sound Portd.7 , 400 , 500      'BEEP &lt;br /&gt;
   End If &lt;br /&gt;
&lt;br /&gt;
   Waitms 100 &lt;br /&gt;
Loop &lt;br /&gt;
&lt;br /&gt;
End &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'Diese Unterfunktion fragt die Tastatur am analogen Port ab &lt;br /&gt;
Function Tastenabfrage() As Byte &lt;br /&gt;
Local Ws As Word &lt;br /&gt;
&lt;br /&gt;
   Tastenabfrage = 0 &lt;br /&gt;
   Ton = 600 &lt;br /&gt;
   Start Adc &lt;br /&gt;
   Ws = Getadc(7) &lt;br /&gt;
  ' Print &amp;quot;Tastenabfrage anpassen!ADC Wert ws=&amp;quot; ; Ws &lt;br /&gt;
   If Ws &amp;lt; 500 Then &lt;br /&gt;
      Select Case Ws &lt;br /&gt;
         Case 400 To 450 &lt;br /&gt;
            Tastenabfrage = 1 &lt;br /&gt;
            Ton = 550 &lt;br /&gt;
         Case 330 To 380 &lt;br /&gt;
            Tastenabfrage = 2 &lt;br /&gt;
            Ton = 500 &lt;br /&gt;
         Case 260 To 305 &lt;br /&gt;
            Tastenabfrage = 3 &lt;br /&gt;
            Ton = 450 &lt;br /&gt;
         Case 180 To 220 &lt;br /&gt;
            Tastenabfrage = 4 &lt;br /&gt;
            Ton = 400 &lt;br /&gt;
         Case 90 To 130 &lt;br /&gt;
            Tastenabfrage = 5 &lt;br /&gt;
             Ton = 350 &lt;br /&gt;
 '        Case Else &lt;br /&gt;
'              Print &amp;quot;Tastenabfrage anpassen!ADC Wert ws=&amp;quot; ; Ws &lt;br /&gt;
      End Select &lt;br /&gt;
      Sound Portd.7 , 400 , Ton                             'BEEP &lt;br /&gt;
&lt;br /&gt;
   End If &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
End Function &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'Diese Unterfunktion zeigt Batteriespannung an &lt;br /&gt;
Sub Batteriespannung() &lt;br /&gt;
Local W As Word &lt;br /&gt;
   Start Adc &lt;br /&gt;
   W = Getadc(6) &lt;br /&gt;
   Volt = W * Ref &lt;br /&gt;
   Volt = Volt * 5.2941 &lt;br /&gt;
   Print &amp;quot;Die aktuelle Spannung beträgt: &amp;quot; ; Volt ; &amp;quot; Volt&amp;quot; &lt;br /&gt;
&lt;br /&gt;
End Sub &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'Testet Motoren und Geschwindigkeitsreglung &lt;br /&gt;
Sub Motortest() &lt;br /&gt;
   'Linker Motor ein &lt;br /&gt;
   Portc.6 = 1                          'bestimmt Richtung &lt;br /&gt;
   Portc.7 = 0                          'bestimmt Richtung &lt;br /&gt;
   Portd.4 = 1                          'Linker Motor EIN &lt;br /&gt;
&lt;br /&gt;
   'Rechter Motor ein &lt;br /&gt;
   Portb.0 = 1                          'bestimmt Richtung rechter Motor &lt;br /&gt;
   Portb.1 = 0                          'bestimmt Richtung rechter Motor &lt;br /&gt;
   Portd.5 = 1                          'rechter Motor EIN &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   I = 0 &lt;br /&gt;
   Do &lt;br /&gt;
      Pwm1a = I &lt;br /&gt;
      Pwm1b = I &lt;br /&gt;
      Waitms 40 &lt;br /&gt;
      I = I + 5 &lt;br /&gt;
   Loop Until I &amp;gt; 1023 &lt;br /&gt;
&lt;br /&gt;
   Wait 1 &lt;br /&gt;
   Do &lt;br /&gt;
      Pwm1a = I &lt;br /&gt;
      Pwm1b = I &lt;br /&gt;
      Waitms 40 &lt;br /&gt;
      I = I - 5 &lt;br /&gt;
   Loop Until I &amp;lt; 1 &lt;br /&gt;
   Pwm1a = 0                            'Linker Motor aus &lt;br /&gt;
   Pwm1b = 0                            'rechter Motor aus &lt;br /&gt;
End Sub &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
' Einige Male Lauflicht über LEDs anzeigen. Am I2C-Port darf in diesem &lt;br /&gt;
' Moment nichts angeschlossen sein &lt;br /&gt;
Sub Lauflicht() &lt;br /&gt;
&lt;br /&gt;
   Config Portc = Output &lt;br /&gt;
   Portd = 0 &lt;br /&gt;
   For N = 1 To 10 &lt;br /&gt;
      For I = 0 To 7 &lt;br /&gt;
         Portc.i = 0 &lt;br /&gt;
         Waitms 100 &lt;br /&gt;
         Portc.i = 1 &lt;br /&gt;
      Next I &lt;br /&gt;
   Next N &lt;br /&gt;
   Config Portc = Input &lt;br /&gt;
End Sub &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'Zeigt die analogen Messwerte an Port A an &lt;br /&gt;
Sub Showporta() &lt;br /&gt;
Local Ws As Word &lt;br /&gt;
&lt;br /&gt;
   Config Porta = Input &lt;br /&gt;
   For I = 0 To 5                        ' Alle internen Pullup Widerstände ein, bis auf Batteriespannungsmessungsport &lt;br /&gt;
      Porta.i = 1 &lt;br /&gt;
   Next I &lt;br /&gt;
&lt;br /&gt;
   Print &lt;br /&gt;
   Print &amp;quot;Ermittelte Messwerte an Port A:&amp;quot; &lt;br /&gt;
   For I = 0 To 7                        ' Alle Eingänge inkl. messen &lt;br /&gt;
      Start Adc &lt;br /&gt;
      Ws = Getadc(i) &lt;br /&gt;
      Volt = Ws * Ref &lt;br /&gt;
      Print &amp;quot;Pin &amp;quot; ; I ; &amp;quot; ADC-Wert= &amp;quot; ; Ws ; &amp;quot; bei 5V REF waeren das &amp;quot; ; Volt ; &amp;quot; Volt&amp;quot; &lt;br /&gt;
   Next I &lt;br /&gt;
End Sub &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'Zeigt den Zustand einiger freier I/O von Die Analogen Messwerte An Port A An &lt;br /&gt;
Sub Showdigitalporta() &lt;br /&gt;
Local Zustand As String * 6 &lt;br /&gt;
   Config Porta = Input &lt;br /&gt;
   For I = 0 To 5                        ' Alle internen Pullup Widerstände ein, bis auf Batteriespannungsmessungsport &lt;br /&gt;
      Porta.i = 1 &lt;br /&gt;
   Next I &lt;br /&gt;
&lt;br /&gt;
   Print &lt;br /&gt;
   Print &amp;quot;Ermittelter I/O Zustand Port A:&amp;quot; &lt;br /&gt;
   For I = 0 To 5                        ' Alle Eingänge inkl. messen &lt;br /&gt;
      If Pina.i = 1 Then &lt;br /&gt;
         Zustand = &amp;quot;High&amp;quot; &lt;br /&gt;
      Else &lt;br /&gt;
         Zustand = &amp;quot;Low&amp;quot; &lt;br /&gt;
      End If &lt;br /&gt;
      Print &amp;quot;Pin &amp;quot; ; I ; &amp;quot; I/O Zustand= &amp;quot; ; Pina.i ; &amp;quot; &amp;quot; ; Zustand &lt;br /&gt;
   Next I &lt;br /&gt;
End Sub&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Programmierung per Druckerport, [[USB]] oder [[RS232]]==&lt;br /&gt;
RN-Control wird üblicherweise mit einem sogenannten [[ISP]]-Dongel programmiert. Die günstigste Ausführung gibt es für einen parallelen Druckerport, siehe auch unter [[AVR-ISP Programmierkabel]]. Etwas teurer aber auch schneller ist ein USBISP-Dongel. Wie genau der Ablauf vonstatten geht wird in der Anleitung (PDF-Dokument siehe Links) genau beschrieben.&lt;br /&gt;
Seit März 2007 wird RN-Control aber auch mit installiertem Bootloader ausgeliefert. Dies hat den Vorteil, dass das Board nun auch ohne ISP-Dongel per RS232 Kabel mit dem Bascom Compiler programmiert werden kann. Dies ist recht angenehm für Notebook Besitzer, die keinen parallelen Druckerport haben und denen der USBISP-Dongel am Anfang etwas zu teuer erscheint. Nähere Hinweise dazu sind ebenfalls in der überarbeiteten PDF-Anleitung (siehe Weblinks unten auf der Seite) zu finden.&lt;br /&gt;
&lt;br /&gt;
==Anschlussbeispiele==&lt;br /&gt;
Da sich Einsteiger mit dem Anschluss von Sensoren oder Verbrauchern manchmal etwas schwer tun, hier eine Skizze, wie man zum Beispiel bestimmte Dinge wie Entfernungssensoren, Servos, Lämpchen oder Helligkeits- bzw. Temperatursensoren anschließen könnte. Bei den Lämpchen sollte man beachten, dass sie zusammen weniger als 1A Strom benötigen, da ansonsten der zuständige Treiber (Motortreiber L293D) überhitzt würde. Natürlich könnte man auch größere Lasten schalten, indem man z.B. statt den Lämpchen Relais anschließt. Auch viele weitere Sensoren könnten natürlich an die noch freien Ports angeschlossen werden, beachten muss man nur, ob der Sensor einen Digital- oder Analogport benötigt.&lt;br /&gt;
Das Servo wird in der Skizze mit 5V versorgt, daher sollte man den Spannungsregler mit einem Kühlkörper versehen.&lt;br /&gt;
&lt;br /&gt;
[[Bild:rncontrolanschlussbeispiel.png|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:srf10anrncontrol.gif|framed|center|Ultraschallmodul am I2C-Bus (mehrere möglich)]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:kompassmodul_an_rncontrol.jpg|framed|center|Auch ein elektronischer Kompass läßt sich leicht am I2C Bus anschließen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:drehgeber_an_rncontrol.gif|center|framed|Beispielschaltung wenn man lediglich die Drehzahl ohne Drehrichtung auswerten möchte. Als Widerstand hat sich 330 Ohm als gut erwiesen. Als Sensor wurde hier ein GP1A30 verwendet]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:rnjoycontrolanrncontrol.jpg|center|framed|Auch passende Joysticks/Joypads lassen sich einfach an RN-Control anschließen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:rn_adapter_mit_rncontrol.jpg|center|framed|Über Adapter lassen sich die Wannenstecker auch durch Steckklemmen mit Portüberwachung ersetzen. Dadurch wird die Verdrahtung noch flexibler]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:rndigicontrol.jpg|thumb|center|Digitalanzeige an RN-Control]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:srf02_i2c_rncontrol.jpg|framed|center|Der neue Ultraschallsensor SRF02 im I2C Mode über Adapter an RN-Control]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:srf02_an_rncontrol_rs232mode.jpg|framed|center|Der neue Ultraschallsensor SRF02 im RS232 Mode an RN-Control]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:rn_lcd_adapter_rncontrol.gif|framed|center|Ein LCD mittels RN-LCDAdapter angeschlossen.]]&lt;br /&gt;
&lt;br /&gt;
==Projektbeispiel mit RN-Control==&lt;br /&gt;
&lt;br /&gt;
[[Bild:allwetterbot.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
*[[Beispiel Drehzahlmessung mit RN-Control]]&lt;br /&gt;
* [[Ultraschall SRF10 an RN-Control]]&lt;br /&gt;
* [[Ultraschallsensor SRF02 am RN-Board]]&lt;br /&gt;
* [[Bascom und Kompass CMPS03]]&lt;br /&gt;
* [[RN-Digi|4 stellige Digitalanzeige an RN-Control]]&lt;br /&gt;
* [[LCD an RN-Control]]&lt;br /&gt;
* [[RN-Control Demprogramm in C]]&lt;br /&gt;
*[[Bascom]]&lt;br /&gt;
*[[Bascom - Erstes Programm in den AVR Controller übertragen]]&lt;br /&gt;
* [[Versenden von Emails's direkt vom RN-Control aus]]&lt;br /&gt;
*[[RN-Definitionen]]&lt;br /&gt;
*[[RN-Board FAQ-Seite]]&lt;br /&gt;
* [[Avr]]&lt;br /&gt;
* [[RN-Mega8]] &lt;br /&gt;
* [[RNBFRA-Board]]&lt;br /&gt;
&lt;br /&gt;
==Weblinks==&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/dload.php?action=file&amp;amp;file_id=138 Ausführliche Anleitung und Bauplan als PDF-Datei]&lt;br /&gt;
&lt;br /&gt;
{{Platinenservice|http://www.robotikhardware.de}}&lt;br /&gt;
{{Bausatzservice|http://www.robotikhardware.de}}&lt;br /&gt;
{{Fertigservice|http://www.robotikhardware.de}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Robotikeinstieg]]&lt;br /&gt;
[[Category:Praxis]]&lt;br /&gt;
[[Category:Elektronik]]&lt;br /&gt;
[[Category:Projekte]]&lt;br /&gt;
[[Category:Microcontroller]]&lt;br /&gt;
[[Kategorie:Quellcode Bascom]]&lt;/div&gt;</summary>
		<author><name>Tuffig</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Sample&amp;diff=12857</id>
		<title>Sample</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Sample&amp;diff=12857"/>
				<updated>2007-10-29T20:49:54Z</updated>
		
		<summary type="html">&lt;p&gt;Tuffig: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier Soll eine Liste mit Unternehmen zusammengefasst werden welche kostenlose &amp;quot;samples&amp;quot; (Teile, in diesem Falle wohl vor allem IC's, die kostenlos zugesandt werden, sozusagen als Produktbeispiel) verschicken. Bei manchen dieser Firmen könnte es dabei zu Problemen kommen wie zum Beispiel eine benötigte Mailadresse von einer UNI oder so was, das kann ich hier allerdings nicht testen da ich bisher nur Microchip getestet haben und die brauchen wirklich seeehr lange um die Dinger zu schicken.&lt;br /&gt;
&lt;br /&gt;
'''Beachtet bitte:'''&lt;br /&gt;
Samples von Bauteilen sind für gewerbliche Entwickler oder - je nach Hersteller - auch für Studenten der entsprechenden Fachrichtungen gedacht und nicht für Privatpersonen bzw. Hobbyisten. &lt;br /&gt;
Daher werden oft als erste Filterstufe, Anfragen die über 'freie' Mailprovider wie hotmail, google etc. kommen verworfen.&lt;br /&gt;
Eine Registrierung der Firmenadresse und der persönlichen Daten sind notwendig. Wer hier einfach Angaben erfindet kann sich ggf. auch Ärger einhandeln (Vortäuschen falscher Tatsachen!).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-[http://sample.microchip.com Microchip]&lt;br /&gt;
 Lieferzeit &amp;gt; 7 Werktage - Uni Mailadresse nötig - kostenloser Versand&lt;br /&gt;
&lt;br /&gt;
-[http://www.analog.com/productSelection/orderSamples/index.html Analog Devices]&lt;br /&gt;
&lt;br /&gt;
-[http://ti.com/ Texas Instruments]&lt;br /&gt;
 Laufzeit ca. 2-5 Werktage - keine Uni Mailadresse nötig - Kostenloser Versand&lt;br /&gt;
&lt;br /&gt;
-[http://www.maxim-ic.com/ Maxim]&lt;br /&gt;
 Laufzeit ca. 3-7 Werktage - keine Uni Mailadresse nötig - Kostenloser Versand&lt;br /&gt;
&lt;br /&gt;
-[http://www.nxp.com/ NXP] (Philips)&lt;br /&gt;
&lt;br /&gt;
-[http://www.freescale.com/ Freescale] (Prozessor von Motorola)&lt;br /&gt;
&lt;br /&gt;
-[http://www.st.com/stonline/domains/buy/samples/index.htm ST Microelectronics] (z.B. den VNH2SP30)&lt;br /&gt;
 Laufzeit ca. 2-5 Werktage - keine Uni Mailadresse nötig - Kostenloser Versand&lt;br /&gt;
&lt;br /&gt;
-[http://www.vishay.com/ Vishay](stellt z.B. den CNY70 her)&lt;br /&gt;
 Wartezeit in Österreich: 1-mehrere Wochen.&lt;br /&gt;
&lt;br /&gt;
-[http://www.national.com/ National Semiconductor]&lt;br /&gt;
&lt;br /&gt;
-[http://www.cirrus.com/dispatch/setlang/en/forms/sup/sreq/sinfo/SinfoController.jpf Cirrus Logic]&lt;br /&gt;
&lt;br /&gt;
-[http://www.cypress.com/ Cypress Semiconductor]&lt;br /&gt;
&lt;br /&gt;
-[http://www.silabs.com/ Silicon Labratories]&lt;br /&gt;
&lt;br /&gt;
-[http://www.sensirion.com/de/ Sensorion] (aber nur einen Feuchigkeitssensor, dafür sehr gute Qualität)&lt;br /&gt;
&lt;br /&gt;
-[http://www.avagotech.com/ Avagotech] (früher HP)&lt;br /&gt;
&lt;br /&gt;
-[http://www.fairchildsemi.com/ Fairchild]&lt;br /&gt;
&lt;br /&gt;
-[http://rfmd.com/ RFMD] dürfte interessant für alle sein, die ein RF-Modul selber bauen möchten&lt;br /&gt;
&lt;br /&gt;
-[http://www.wolfsonmicro.com/ Wolfsonmicro] ADC's, DAC's, Codes und mehr&lt;br /&gt;
&lt;br /&gt;
-[http://www.macronix.com/ Macronix] Flash und ROM&lt;br /&gt;
&lt;br /&gt;
-[http://www.intersil.com/cda/home/ Intersil]&lt;br /&gt;
&lt;br /&gt;
{{Ausbauwunsch|Mehr Chiphersteller und eventuell könnte jemand anfangen seine Erfahrungen einzutragen, zum Beispiel bezüglich der Lieferzeiten oder Zuzahlungen.}}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Projekte]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Sensoren]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;/div&gt;</summary>
		<author><name>Tuffig</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Sample&amp;diff=12856</id>
		<title>Sample</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Sample&amp;diff=12856"/>
				<updated>2007-10-29T20:48:57Z</updated>
		
		<summary type="html">&lt;p&gt;Tuffig: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier Soll eine Liste mit Unternehmen zusammengefasst werden welche kostenlose &amp;quot;samples&amp;quot; (Teile, in diesem Falle wohl vor allem IC's, die kostenlos zugesandt werden, sozusagen als Produktbeispiel) verschicken. Bei manchen dieser Firmen könnte es dabei zu Problemen kommen wie zum Beispiel eine benötigte Mailadresse von einer UNI oder so was, das kann ich hier allerdings nicht testen da ich bisher nur Microchip getestet haben und die brauchen wirklich seeehr lange um die Dinger zu schicken.&lt;br /&gt;
&lt;br /&gt;
Beachtet bitte:&lt;br /&gt;
Samples von Bauteilen sind für gewerbliche Entwickler oder - je nach Hersteller - auch für Studenten der entsprechenden Fachrichtungen gedacht und nicht für Privatpersonen bzw. Hobbyisten. &lt;br /&gt;
Daher werden oft als erste Filterstufe, Anfragen die über 'freie' Mailprovider wie hotmail, google etc. kommen verworfen.&lt;br /&gt;
Eine Registrierung der Firmenadresse und der persönlichen Daten sind notwendig. Wer hier einfach Angaben erfindet kann sich ggf. auch Ärger einhandeln (Vortäuschen falscher Tatsachen!).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-[http://sample.microchip.com Microchip]&lt;br /&gt;
 Lieferzeit &amp;gt; 7 Werktage - Uni Mailadresse nötig - kostenloser Versand&lt;br /&gt;
&lt;br /&gt;
-[http://www.analog.com/productSelection/orderSamples/index.html Analog Devices]&lt;br /&gt;
&lt;br /&gt;
-[http://ti.com/ Texas Instruments]&lt;br /&gt;
 Laufzeit ca. 2-5 Werktage - keine Uni Mailadresse nötig - Kostenloser Versand&lt;br /&gt;
&lt;br /&gt;
-[http://www.maxim-ic.com/ Maxim]&lt;br /&gt;
 Laufzeit ca. 3-7 Werktage - keine Uni Mailadresse nötig - Kostenloser Versand&lt;br /&gt;
&lt;br /&gt;
-[http://www.nxp.com/ NXP] (Philips)&lt;br /&gt;
&lt;br /&gt;
-[http://www.freescale.com/ Freescale] (Prozessor von Motorola)&lt;br /&gt;
&lt;br /&gt;
-[http://www.st.com/stonline/domains/buy/samples/index.htm ST Microelectronics] (z.B. den VNH2SP30)&lt;br /&gt;
 Laufzeit ca. 2-5 Werktage - keine Uni Mailadresse nötig - Kostenloser Versand&lt;br /&gt;
&lt;br /&gt;
-[http://www.vishay.com/ Vishay](stellt z.B. den CNY70 her)&lt;br /&gt;
 Wartezeit in Österreich: 1-mehrere Wochen.&lt;br /&gt;
&lt;br /&gt;
-[http://www.national.com/ National Semiconductor]&lt;br /&gt;
&lt;br /&gt;
-[http://www.cirrus.com/dispatch/setlang/en/forms/sup/sreq/sinfo/SinfoController.jpf Cirrus Logic]&lt;br /&gt;
&lt;br /&gt;
-[http://www.cypress.com/ Cypress Semiconductor]&lt;br /&gt;
&lt;br /&gt;
-[http://www.silabs.com/ Silicon Labratories]&lt;br /&gt;
&lt;br /&gt;
-[http://www.sensirion.com/de/ Sensorion] (aber nur einen Feuchigkeitssensor, dafür sehr gute Qualität)&lt;br /&gt;
&lt;br /&gt;
-[http://www.avagotech.com/ Avagotech] (früher HP)&lt;br /&gt;
&lt;br /&gt;
-[http://www.fairchildsemi.com/ Fairchild]&lt;br /&gt;
&lt;br /&gt;
-[http://rfmd.com/ RFMD] dürfte interessant für alle sein, die ein RF-Modul selber bauen möchten&lt;br /&gt;
&lt;br /&gt;
-[http://www.wolfsonmicro.com/ Wolfsonmicro] ADC's, DAC's, Codes und mehr&lt;br /&gt;
&lt;br /&gt;
-[http://www.macronix.com/ Macronix] Flash und ROM&lt;br /&gt;
&lt;br /&gt;
-[http://www.intersil.com/cda/home/ Intersil]&lt;br /&gt;
&lt;br /&gt;
{{Ausbauwunsch|Mehr Chiphersteller und eventuell könnte jemand anfangen seine Erfahrungen einzutragen, zum Beispiel bezüglich der Lieferzeiten oder Zuzahlungen.}}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Projekte]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Sensoren]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;/div&gt;</summary>
		<author><name>Tuffig</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=UART_mit_avr-gcc&amp;diff=12855</id>
		<title>UART mit avr-gcc</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=UART_mit_avr-gcc&amp;diff=12855"/>
				<updated>2007-10-28T16:07:56Z</updated>
		
		<summary type="html">&lt;p&gt;Tuffig: /* Variante 1: Ohne Interrupts */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier werden zwei verschiedene Arten vorgestellt, wie die [[UART]] benutzt werden kann. Die erste Variante verzichtet auf [[Interrupt]]s und [[Interrupt#Unterschiede zum Polling|pollt]] permanent oder auf Wunsch nach eingehenden Daten. Diese Variante ist einfach, aber nicht effizient. Die zweite Variante arbeitet mit Interrupts und ermögliche eine nebenläufige Kommunikation.&lt;br /&gt;
&lt;br /&gt;
Die Routinen sind erstellt worden für den USART des [[ATmega8]]. Für andere AVR &amp;amp;ndash; neuere Modelle und solche, die mehrer UART-Module besitzen &amp;amp;ndash; haben die Register teilweise andere Namen. Dann gibt es z.B. Register &amp;lt;tt&amp;gt;UBRR0L&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;UBRR1L&amp;lt;/tt&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
= Variante 1: Ohne Interrupts =&lt;br /&gt;
&lt;br /&gt;
Hier eine der einfachsten Möglichkeiten, den Hardware-[[UART]] von [[AVR]] zu nutzen. Die Empfangs- und Sendefunktionen sind so kurz, daß sie am besten als inline-Funktionen definiert werden. Auf Zeichen bzw. Ereignisse zu warten bezeichnet man auch als &amp;quot;''polling''&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== C-Datei ==&lt;br /&gt;
&lt;br /&gt;
Der USART wird initialisiert als UART mit dem Datenformat 8N1 (8&amp;amp;nbsp;Datenbits, kein Parity, 1&amp;amp;nbsp;Stopbit). &lt;br /&gt;
&lt;br /&gt;
'''uart.c'''&lt;br /&gt;
 #include &amp;quot;uart.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #define BAUDRATE 38400&lt;br /&gt;
 &lt;br /&gt;
 void uart_init()&lt;br /&gt;
 {&lt;br /&gt;
     uint16_t ubrr = (uint16_t) ((uint32_t) F_CPU/(16*BAUDRATE) - 1);&lt;br /&gt;
  &lt;br /&gt;
     UBRRH = (uint8_t) (ubrr&amp;gt;&amp;gt;8);&lt;br /&gt;
     UBRRL = (uint8_t) (ubrr);&lt;br /&gt;
  &lt;br /&gt;
     {{ccomment|UART Receiver und Transmitter anschalten }}&lt;br /&gt;
     {{ccomment|Data mode 8N1, asynchron }}&lt;br /&gt;
     UCSRB = (1 &amp;lt;&amp;lt; RXEN) | (1 &amp;lt;&amp;lt; TXEN);&lt;br /&gt;
     UCSRC = (1 &amp;lt;&amp;lt; URSEL) | (1 &amp;lt;&amp;lt; UCSZ1) | (1 &amp;lt;&amp;lt; UCSZ0);&lt;br /&gt;
 &lt;br /&gt;
     {{ccomment|Flush Receive-Buffer (entfernen evtl. vorhandener ungültiger Werte) }}&lt;br /&gt;
     do&lt;br /&gt;
     {&lt;br /&gt;
         UDR;&lt;br /&gt;
     }&lt;br /&gt;
     while (UCSRA &amp;amp; (1 &amp;lt;&amp;lt; RXC));&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
== Benutzer-Schnittstelle und Header ==&lt;br /&gt;
&lt;br /&gt;
Im Header &amp;lt;tt&amp;gt;uart.h&amp;lt;/tt&amp;gt; werden die Funktionen veröffentlicht und stehen in anderen Modulen zur Verfügung:&lt;br /&gt;
;&amp;lt;tt&amp;gt;extern void uart_init()&amp;lt;/tt&amp;gt;: Initialisiert den UART und aktiviert Receiver und Transmitter.&lt;br /&gt;
;&amp;lt;tt&amp;gt;static inline int uart_putc (const uint8_t c)&amp;lt;/tt&amp;gt;: Sendet das Zeichen &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; über den UART. Der return-Wert ist immer&amp;amp;nbsp;1.&lt;br /&gt;
;&amp;lt;tt&amp;gt;static inline uint8_t uart_getc_wait()&amp;lt;/tt&amp;gt;: Wartet bis zum nächsten Empfang bzw. liefert das empfangene Zeichen.&lt;br /&gt;
;&amp;lt;tt&amp;gt;static inline int uart_getc_nowait()&amp;lt;/tt&amp;gt;: Schaut nach, ob ein Zeichen empfangen wurde und liefert dieses gegebenenfalls als &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; zurück (Wertebereich ist 0...255). Wurde nichts empfangen, wird &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; geliefert.&lt;br /&gt;
Die Defines &amp;lt;tt&amp;gt;F_CPU&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;BAUDRATE&amp;lt;/tt&amp;gt; geben die Taktrate des AVR sowie die Baudrate an. Dabei hat &amp;lt;tt&amp;gt;F_CPU&amp;lt;/tt&amp;gt; nur rein informativen Character, es ''ändert'' die CPU-Frequenz nicht! Der Define für &amp;lt;tt&amp;gt;F_CPU&amp;lt;/tt&amp;gt; kann man in die Quelle dazu schreiben, oder man gibt einen Wert per Kommandozeile/[[make|Makefile]] an mit &amp;lt;tt&amp;gt;-DF_CPU=...&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''uart.h'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
 #ifndef _UART_H_&lt;br /&gt;
 #define _UART_H_&lt;br /&gt;
 &lt;br /&gt;
 #include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 extern void uart_init();&lt;br /&gt;
 &lt;br /&gt;
 static inline int&lt;br /&gt;
 uart_putc (const uint8_t c)&lt;br /&gt;
 {&lt;br /&gt;
     {{ccomment|Warten, bis UDR bereit ist für einen neuen Wert }}&lt;br /&gt;
     while (!(UCSRA &amp;amp; (1 &amp;lt;&amp;lt; UDRE)))&lt;br /&gt;
         ;&lt;br /&gt;
 &lt;br /&gt;
     {{ccomment|UDR Schreiben startet die Übertragung }}&lt;br /&gt;
     UDR = c;&lt;br /&gt;
 &lt;br /&gt;
     return 1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 static inline uint8_t&lt;br /&gt;
 uart_getc_wait()&lt;br /&gt;
 {&lt;br /&gt;
     {{ccomment|Warten, bis etwas empfangen wird }}&lt;br /&gt;
     while (!(UCSRA &amp;amp; (1 &amp;lt;&amp;lt; RXC)))&lt;br /&gt;
         ;&lt;br /&gt;
 &lt;br /&gt;
     {{ccomment|Das empfangene Zeichen zurückliefern }}&lt;br /&gt;
     return UDR;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 static inline int&lt;br /&gt;
 uart_getc_nowait()&lt;br /&gt;
 {&lt;br /&gt;
     {{ccomment|Liefer das empfangene Zeichen, falls etwas empfangen wurde; -1 sonst }}&lt;br /&gt;
     return (UCSRA &amp;amp; (1 &amp;lt;&amp;lt; RXC)) ? (int) UDR : -1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 #endif {{comment|_UART_H_ }}&lt;br /&gt;
&lt;br /&gt;
= Variante 2: Mit Interrupts =&lt;br /&gt;
&lt;br /&gt;
Diese Interrupt-getriebene Variante benutzt FIFO-Methoden aus dem Artikel &amp;quot;[[FIFO mit avr-gcc]]&amp;quot; zur Zwischenspeicherung der zu sendenden und empfangenen Daten.&lt;br /&gt;
&lt;br /&gt;
== Benutzer-Schnittstelle und Header ==&lt;br /&gt;
&lt;br /&gt;
Im Header &amp;lt;tt&amp;gt;uart.h&amp;lt;/tt&amp;gt; werden die Funktionen veröffentlicht und stehen in anderen Modulen zur Verfügung. Das Interface ist das gleiche wie beim Polling.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;extern void uart_init()&amp;lt;/tt&amp;gt;: Initialisiert den UART und aktiviert Receiver und Transmitter sowie den Receive-Interrupt. Die Ein- und Ausgebe-FIFO werden initialisiert. Das globale Interrupt-Enable-Flag (I-Bit in SREG) wird nicht verändert.&lt;br /&gt;
;&amp;lt;tt&amp;gt;extern int uart_putc (const uint8_t c)&amp;lt;/tt&amp;gt;: Speichert das Zeichen &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; in der Ausgabe-Warteschlange. Der return-Wert ist&amp;amp;nbsp;1, falls das Zeichen in die FIFO eingetragen wurde, und&amp;amp;nbsp;0, falls die Ausgabe-FIFO voll ist. Der UART DATA-Interupt wird aktiviert, der die Zeichen aus der Ausgabe-FIFO über den UART verschickt.&lt;br /&gt;
;&amp;lt;tt&amp;gt;extern uint8_t uart_getc_wait()&amp;lt;/tt&amp;gt;: Liefert das nächste empfangene Zeichen aus der Eingabe-FIFO bzw. wartet darauf, falls die FIFO leer ist.&lt;br /&gt;
;&amp;lt;tt&amp;gt;extern int uart_getc_nowait()&amp;lt;/tt&amp;gt;: Schaut nach, ob ein Zeichen empfangen wurde und liefert dieses gegebenenfalls als &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; zurück (Wertebereich ist 0...255). Wurde nichts empfangen, wird &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; geliefert.&lt;br /&gt;
;&amp;lt;tt&amp;gt;static inline void uart_flush()&amp;lt;/tt&amp;gt;: Wartet, bis die Übertragung fertig ist.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;uart.h&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#ifndef _UART_H_&lt;br /&gt;
#define _UART_H_&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
extern void uart_init();&lt;br /&gt;
extern int uart_putc (const uint8_t);&lt;br /&gt;
extern uint8_t uart_getc_wait();&lt;br /&gt;
extern int     uart_getc_nowait();&lt;br /&gt;
&lt;br /&gt;
static inline void uart_flush()&lt;br /&gt;
{&lt;br /&gt;
	while (UCSRB &amp;amp; (1 &amp;lt;&amp;lt; UDRIE));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#endif /* _UART_H_ */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C-Datei ==&lt;br /&gt;
&lt;br /&gt;
===Dateikopf und Initialisierung ===&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;
 #include &amp;quot;uart.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;fifo.h&amp;quot; {{ccomment|erklärt im Artikel &amp;quot;[[FIFO mit avr-gcc]]&amp;quot;}}&lt;br /&gt;
 &lt;br /&gt;
 #define BAUDRATE 38400&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|FIFO-Objekte und Puffer für die Ein- und Ausgabe }}&lt;br /&gt;
 &lt;br /&gt;
 #define BUFSIZE_IN  0x40&lt;br /&gt;
 uint8_t inbuf[BUFSIZE_IN];&lt;br /&gt;
 fifo_t infifo;&lt;br /&gt;
 &lt;br /&gt;
 #define BUFSIZE_OUT 0x40&lt;br /&gt;
 uint8_t outbuf[BUFSIZE_OUT];&lt;br /&gt;
 fifo_t outfifo;&lt;br /&gt;
 &lt;br /&gt;
 void uart_init()&lt;br /&gt;
 {&lt;br /&gt;
     uint8_t sreg = SREG;&lt;br /&gt;
     uint16_t ubrr = (uint16_t) ((uint32_t) F_CPU/(16*BAUDRATE) - 1);&lt;br /&gt;
 &lt;br /&gt;
     UBRRH = (uint8_t) (ubrr&amp;gt;&amp;gt;8);&lt;br /&gt;
     UBRRL = (uint8_t) (ubrr);&lt;br /&gt;
 &lt;br /&gt;
     {{ccomment|Interrupts kurz deaktivieren }}&lt;br /&gt;
     cli();&lt;br /&gt;
 &lt;br /&gt;
     {{ccomment|UART Receiver und Transmitter anschalten, Receive-Interrupt aktivieren }}&lt;br /&gt;
     {{ccomment|Data mode 8N1, asynchron }}&lt;br /&gt;
     UCSRB = (1 &amp;lt;&amp;lt; RXEN) | (1 &amp;lt;&amp;lt; TXEN) | (1 &amp;lt;&amp;lt; RXCIE);&lt;br /&gt;
     UCSRC = (1 &amp;lt;&amp;lt; URSEL) | (1 &amp;lt;&amp;lt; UCSZ1) | (1 &amp;lt;&amp;lt; UCSZ0);&lt;br /&gt;
 &lt;br /&gt;
     {{ccomment|Flush Receive-Buffer (entfernen evtl. vorhandener ungültiger Werte) }}&lt;br /&gt;
     do&lt;br /&gt;
     {&lt;br /&gt;
         {{ccomment|UDR auslesen (Wert wird nicht verwendet) }}&lt;br /&gt;
         UDR;&lt;br /&gt;
     }&lt;br /&gt;
     while (UCSRA &amp;amp; (1 &amp;lt;&amp;lt; RXC));&lt;br /&gt;
 &lt;br /&gt;
     {{ccomment|Rücksetzen von Receive und Transmit Complete-Flags }}&lt;br /&gt;
     UCSRA = (1 &amp;lt;&amp;lt; RXC) | (1 &amp;lt;&amp;lt; TXC);&lt;br /&gt;
 &lt;br /&gt;
     {{ccomment|Global Interrupt-Flag wieder herstellen }}&lt;br /&gt;
     SREG = sreg;&lt;br /&gt;
 &lt;br /&gt;
     {{ccomment|FIFOs für Ein- und Ausgabe initialisieren }}&lt;br /&gt;
     fifo_init (&amp;amp;infifo,   inbuf, BUFSIZE_IN);&lt;br /&gt;
     fifo_init (&amp;amp;outfifo, outbuf, BUFSIZE_OUT);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Interrupt-Routinen===&lt;br /&gt;
&lt;br /&gt;
 {{ccomment|Empfangene Zeichen werden in die Eingabgs-FIFO gespeichert und warten dort }}&lt;br /&gt;
 SIGNAL (SIG_UART_RECV)&lt;br /&gt;
 {&lt;br /&gt;
     _inline_fifo_put (&amp;amp;infifo, UDR);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Ein Zeichen aus der Ausgabe-FIFO lesen und ausgeben }}&lt;br /&gt;
 {{ccomment|Ist das Zeichen fertig ausgegeben, wird ein neuer SIG_UART_DATA-IRQ getriggert }}&lt;br /&gt;
 {{ccomment|Ist die FIFO leer, deaktiviert die ISR ihren eigenen IRQ. }}&lt;br /&gt;
 SIGNAL (SIG_UART_DATA)&lt;br /&gt;
 {&lt;br /&gt;
     if (outfifo.count &amp;gt; 0)&lt;br /&gt;
        UDR = _inline_fifo_get (&amp;amp;outfifo);&lt;br /&gt;
     else&lt;br /&gt;
         UCSRB &amp;amp;= ~(1 &amp;lt;&amp;lt; UDRIE);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Ein- und Ausgabe ===&lt;br /&gt;
Die Ein- und Ausgebefunktionen machen nichts weiter, als die empfangenen/zusendenden Zeichen aus der FIFO zu lesen/in die FIFO zu schreiben.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int uart_putc (const uint8_t c)&lt;br /&gt;
{&lt;br /&gt;
    int ret = fifo_put (&amp;amp;outfifo, c);&lt;br /&gt;
	&lt;br /&gt;
    UCSRB |= (1 &amp;lt;&amp;lt; UDRIE);&lt;br /&gt;
	 &lt;br /&gt;
    return ret;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int uart_getc_nowait ()&lt;br /&gt;
{&lt;br /&gt;
    return fifo_get_nowait (&amp;amp;infifo);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
uint8_t uart_getc_wait ()&lt;br /&gt;
{&lt;br /&gt;
    return fifo_get_wait (&amp;amp;infifo);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Weitere Routinen=&lt;br /&gt;
== Einen String senden ==&lt;br /&gt;
&lt;br /&gt;
Übergeben wird die Start-Adresse des Strings. Die Zeichenkette wird solange durchlaufen und die Zeichen ausgegeben, bis eine &amp;lt;tt&amp;gt;'\0'&amp;lt;/tt&amp;gt; (Stringende-Marke) gelesen wird.&lt;br /&gt;
 #include &amp;lt;avr/interrupt.h&amp;gt;  {{ccomment|Wird nur gebraucht bei der Interrupt-Version }}&lt;br /&gt;
 #include &amp;quot;uart.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Einen 0-terminierten String übertragen. }}&lt;br /&gt;
 void uart_puts (const char *s)&lt;br /&gt;
 {&lt;br /&gt;
     do&lt;br /&gt;
     {&lt;br /&gt;
         uart_putc (*s);&lt;br /&gt;
     }&lt;br /&gt;
     while (*s++);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Ein Zeilenumbruch, abhängig davon, was die Gegenstelle haben will }}&lt;br /&gt;
 {{ccomment|Windows: &amp;quot;rn&amp;quot; }}&lt;br /&gt;
 {{ccomment|Linux  : &amp;quot;n&amp;quot; }}&lt;br /&gt;
 {{ccomment|MacOS  : &amp;quot;r&amp;quot; }}&lt;br /&gt;
 #define CR &amp;quot;\r\n&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 char text[] = &amp;quot;Hallo Welt.&amp;quot; CR;&lt;br /&gt;
 &lt;br /&gt;
 int main()&lt;br /&gt;
 {&lt;br /&gt;
     uart_init();&lt;br /&gt;
     sei();   {{ccomment|Wird nur gebraucht bei der Interrupt-Version }}&lt;br /&gt;
 &lt;br /&gt;
     uart_puts (text);&lt;br /&gt;
     uart_puts (&amp;quot;Hallo Welt!&amp;quot; CR);&lt;br /&gt;
 &lt;br /&gt;
     return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
== Einen konstanten String senden ==&lt;br /&gt;
&lt;br /&gt;
Unveränderliche Strings brauchen kein Platz im SRAM zu verschwenden, man lässt sie im Flash (wo sie sonst ebenfalls stehen für die SRAM-Initialisierung).&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;avr/interrupt.h&amp;gt;   {{ccomment|Wird nur gebraucht bei der Interrupt-Version }}&lt;br /&gt;
 #include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
 #include &amp;quot;uart.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Einen 0-terminierten String senden, der im Flash steht. }}&lt;br /&gt;
 void uart_puts_P (PGM_P s)&lt;br /&gt;
 {&lt;br /&gt;
     while (1)&lt;br /&gt;
     {&lt;br /&gt;
         unsigned char c = pgm_read_byte (s);&lt;br /&gt;
         s++;&lt;br /&gt;
         if ('\0' == c)&lt;br /&gt;
             break;&lt;br /&gt;
         uart_putc (c);&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 {{ccomment|Ein Zeilenumbruch, abhängig davon, was die Gegenstelle haben will }}&lt;br /&gt;
 {{ccomment|Windows: &amp;quot;rn&amp;quot; }}&lt;br /&gt;
 {{ccomment|Linux  : &amp;quot;n&amp;quot; }}&lt;br /&gt;
 {{ccomment|MacOS  : &amp;quot;r&amp;quot; }}&lt;br /&gt;
 #define CR &amp;quot;\r\n&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 const prog_char text_p[] = &amp;quot;Hallo Welt.&amp;quot; CR;&lt;br /&gt;
 &lt;br /&gt;
 int main()&lt;br /&gt;
 {&lt;br /&gt;
     uart_init();&lt;br /&gt;
     sei();   {{ccomment|Wird nur gebraucht bei der Interrupt-Version }}&lt;br /&gt;
 &lt;br /&gt;
     uart_puts_P (text_p);&lt;br /&gt;
     uart_puts_P (PSTR(&amp;quot;Hallo Welt!&amp;quot; CR));&lt;br /&gt;
 &lt;br /&gt;
     return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
= Siehe auch =&lt;br /&gt;
&lt;br /&gt;
*[[UART]]&lt;br /&gt;
*[[RS232]]&lt;br /&gt;
*[[Software-UART mit avr-gcc]]&lt;br /&gt;
*[[FIFO mit avr-gcc]]&lt;br /&gt;
&lt;br /&gt;
==WebLinks==&lt;br /&gt;
* [http://www.gjlay.de/helferlein/avr-uart-rechner.html AVR-Baudraten-Rechner (JavaScript)]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Quellcode C]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;/div&gt;</summary>
		<author><name>Tuffig</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=12853</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=12853"/>
				<updated>2007-10-28T09:31:16Z</updated>
		
		<summary type="html">&lt;p&gt;Tuffig: /* strlen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Programmiersprache C wurde 1971 als Grundlage 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, [[Mikrocontroller]]) 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 im Allgemeuinen 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 und evtl. Umgebungsvariablen, 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 und der Initialisierung 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. C-Programme sind in so genannte Blöcke unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Konstrukte stellt ein eigenständiges Stück Code dar, das als solches gekennzeichnet werden muss. &lt;br /&gt;
&lt;br /&gt;
Die Kennzeichnung für einen Blockanfang ist die öffnende geschweifte Klammer, während ein Blockende mit der schliessenden Klammer notiert wird. Ein Block kann mehrere Teilblöcke enthalten, die wiederum Teilblöcke enthalten dürfen, etc. Öffnende und schliessende Block-Klammern tauchen immer Paarweise auf. &lt;br /&gt;
&lt;br /&gt;
Variablen, die in einem Block deklariert werden, sind nur innerhalb dieses Blocks &amp;amp;ndash; und damit auch in allen seinen Teilblöcken &amp;amp;ndash; gültig.&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;
Stell 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 ebenso...&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;
In C ist es möglich, einer Funktion eine variable Anzahl an Argumenten zu übergeben. Solche Funktionen haben eine Anzahl benamter Argumente wie &amp;quot;normale&amp;quot; Funktionen auch, jedoch folgt nach dem letzten benamten Argument eine beliebige Anzahl weiterer Argumente.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für eine solche Funktion ist das Bekannte &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;, für das zB folgende Aufrufe möglich sind:&lt;br /&gt;
 printf (&amp;quot;Hallo&amp;quot;);&lt;br /&gt;
 printf (&amp;quot;%c&amp;quot;, c);&lt;br /&gt;
 printf (&amp;quot;%s %d&amp;quot;, einString, 15);&lt;br /&gt;
 printf (&amp;quot;%d %d %d&amp;quot;, zahl1, zahl2, zahl3);&lt;br /&gt;
&lt;br /&gt;
Einer solchen Funktion muss die Anzahl der Argumente mitgeleilt werden, die ihr übergeben werden. Sies könnte dadurch geschehen, daß man ihr die Argumentanzahl explizit übergibt. Bei &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; wird die Anzahl der Übergabeparameter im Formatstring transportiert, ebenso wie die Typen der Übergebenen Variablen, denn die Funktion muss wissen, wie die übergebenen Werte zu interpretieren sind. Bei &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; geschieht dies wiederum mittls des Format-Strings.&lt;br /&gt;
&lt;br /&gt;
Der Prototyp einer varargs-Funktion sieht aus wie folgt, wobei die drei Pünktchen wörtlich zu nehmen sind und nicht etwa als abkürzende Schreibweise für die Parameterliste! &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdarg.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 extern void fprintf (FILE * file, const char * format, ...);&lt;br /&gt;
 extern void printf  (const char * format, ...);&lt;br /&gt;
 extern void fprintf_va (FILE * file, const char * format, va_list args);&lt;br /&gt;
&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;fprintf&amp;lt;/tt&amp;gt; soll eine Ausgabe zum File (Stream) &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; erledigen und ansonsten genauso funktionieren wie das altbekannte &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;. Es ist also anzustreben, in &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; nur die File-Version aufzurufen um eine Doppel-Implementierung der Funktionalität zu vermeiden. Hierzu dient die Funktion &amp;lt;tt&amp;gt;fprintf_va&amp;lt;/tt&amp;gt;, die von &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;fprintf&amp;lt;/tt&amp;gt; einen File-Pointer, den Format-String sowie die Argumente erhält:&lt;br /&gt;
&lt;br /&gt;
 void fprintf (FILE * file, const char * format, ...)&lt;br /&gt;
 {&lt;br /&gt;
 	{{ccomment|Die Argumentliste 'args'}}&lt;br /&gt;
 	va_list args;&lt;br /&gt;
 	{{ccomment|Die variablen Argument beginnen nach 'format' }}&lt;br /&gt;
 	va_start (args, format);&lt;br /&gt;
 	{{ccomment|Die eigentliche Arbeit erledigt 'fprintf_va' }}&lt;br /&gt;
 	fprintf_va (file, format, args);&lt;br /&gt;
 	{{ccomment|fertig }}&lt;br /&gt;
 	va_end (args);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Fast genauso sieht unser &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; aus:&lt;br /&gt;
&lt;br /&gt;
 void printf (const char * format, ...)&lt;br /&gt;
 {&lt;br /&gt;
 	{{ccomment|Die Argumentliste 'args'}}&lt;br /&gt;
 	va_list args;&lt;br /&gt;
 	{{ccomment|Die variablen Argument beginnen nach 'format' }}&lt;br /&gt;
 	va_start (args, format);&lt;br /&gt;
 	{{ccomment|Die eigentliche Arbeit erledigt 'fprintf_va' }}&lt;br /&gt;
 	fprintf_va (stdout, format, args);&lt;br /&gt;
 	{{ccomment|fertig }}&lt;br /&gt;
 	va_end (args);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Was zu tun bleibt, ist die Implementioerung der eigentlichen Funktionalität in &amp;lt;tt&amp;gt;fprintf_va&amp;lt;/tt&amp;gt;. Diese durchfostet den Format-String und bei jedem %-Ausdruck wird ein weiteres Argument eingelesen und an eine passende Ausgabefunktion delegiert. Hier wird der Einfachheit halber nur &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;%s&amp;lt;/tt&amp;gt; implementiert:&lt;br /&gt;
&lt;br /&gt;
 static void fprintf_va (FILE * file, const char * fmt, va_list args)&lt;br /&gt;
 {&lt;br /&gt;
     char c;&lt;br /&gt;
 &lt;br /&gt;
     {{ccomment|Nächstes Zeichen des Formatstrings lesen und String-Ende abtesten }}&lt;br /&gt;
     while (c = *fmt++, c != '\0')&lt;br /&gt;
     {&lt;br /&gt;
         {{ccomment|Das Format-Zeichen }}&lt;br /&gt;
         if ('%' == c)&lt;br /&gt;
         {&lt;br /&gt;
             {{ccomment|Weiterlesen: das Zeichen nach dem % }}&lt;br /&gt;
             c = fmt++;&lt;br /&gt;
 &lt;br /&gt;
             {{ccomment|%% --&amp;gt; ein % ausgeben }}&lt;br /&gt;
             if ('%' == c)    fputc ('%', file);&lt;br /&gt;
             {{ccomment|%c --&amp;gt; Character ausgeben }}&lt;br /&gt;
             else if ('c' == c)    fputc (va_arg (args, int), file);&lt;br /&gt;
             {{ccomment|%s --&amp;gt; String ausgeben }}&lt;br /&gt;
             else if ('s' == c)    fputs (va_arg (args, char*), file);&lt;br /&gt;
             {{ccomment|Unbekannts %-Format }}&lt;br /&gt;
             else fputs (&amp;quot;???&amp;quot;, file);&lt;br /&gt;
 &lt;br /&gt;
             {{ccomment|Falls ein % am String-Ende steht }}&lt;br /&gt;
             if ('\0' == c)  return;&lt;br /&gt;
 &lt;br /&gt;
             continue;&lt;br /&gt;
         }&lt;br /&gt;
 &lt;br /&gt;
         {{ccomment|Für Win32: Zeilenumbruch ist carriage return + line feed }}&lt;br /&gt;
         if ('\n' == c)&lt;br /&gt;
             putc ('\r');&lt;br /&gt;
 &lt;br /&gt;
         {{ccomment|Zeichen ausgenen }}&lt;br /&gt;
         putc (c);&lt;br /&gt;
     } {{ccomment|while }}&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, einen 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 dieses 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;
* [[C-Tutorial/Interrupt-Programmierung]]&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>Tuffig</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=12852</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=12852"/>
				<updated>2007-10-28T09:29:58Z</updated>
		
		<summary type="html">&lt;p&gt;Tuffig: /* strcpy */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Programmiersprache C wurde 1971 als Grundlage 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, [[Mikrocontroller]]) 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 im Allgemeuinen 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 und evtl. Umgebungsvariablen, 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 und der Initialisierung 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. C-Programme sind in so genannte Blöcke unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Konstrukte stellt ein eigenständiges Stück Code dar, das als solches gekennzeichnet werden muss. &lt;br /&gt;
&lt;br /&gt;
Die Kennzeichnung für einen Blockanfang ist die öffnende geschweifte Klammer, während ein Blockende mit der schliessenden Klammer notiert wird. Ein Block kann mehrere Teilblöcke enthalten, die wiederum Teilblöcke enthalten dürfen, etc. Öffnende und schliessende Block-Klammern tauchen immer Paarweise auf. &lt;br /&gt;
&lt;br /&gt;
Variablen, die in einem Block deklariert werden, sind nur innerhalb dieses Blocks &amp;amp;ndash; und damit auch in allen seinen Teilblöcken &amp;amp;ndash; gültig.&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;
Stell 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 ebenso...&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;
In C ist es möglich, einer Funktion eine variable Anzahl an Argumenten zu übergeben. Solche Funktionen haben eine Anzahl benamter Argumente wie &amp;quot;normale&amp;quot; Funktionen auch, jedoch folgt nach dem letzten benamten Argument eine beliebige Anzahl weiterer Argumente.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für eine solche Funktion ist das Bekannte &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;, für das zB folgende Aufrufe möglich sind:&lt;br /&gt;
 printf (&amp;quot;Hallo&amp;quot;);&lt;br /&gt;
 printf (&amp;quot;%c&amp;quot;, c);&lt;br /&gt;
 printf (&amp;quot;%s %d&amp;quot;, einString, 15);&lt;br /&gt;
 printf (&amp;quot;%d %d %d&amp;quot;, zahl1, zahl2, zahl3);&lt;br /&gt;
&lt;br /&gt;
Einer solchen Funktion muss die Anzahl der Argumente mitgeleilt werden, die ihr übergeben werden. Sies könnte dadurch geschehen, daß man ihr die Argumentanzahl explizit übergibt. Bei &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; wird die Anzahl der Übergabeparameter im Formatstring transportiert, ebenso wie die Typen der Übergebenen Variablen, denn die Funktion muss wissen, wie die übergebenen Werte zu interpretieren sind. Bei &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; geschieht dies wiederum mittls des Format-Strings.&lt;br /&gt;
&lt;br /&gt;
Der Prototyp einer varargs-Funktion sieht aus wie folgt, wobei die drei Pünktchen wörtlich zu nehmen sind und nicht etwa als abkürzende Schreibweise für die Parameterliste! &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdarg.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 extern void fprintf (FILE * file, const char * format, ...);&lt;br /&gt;
 extern void printf  (const char * format, ...);&lt;br /&gt;
 extern void fprintf_va (FILE * file, const char * format, va_list args);&lt;br /&gt;
&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;fprintf&amp;lt;/tt&amp;gt; soll eine Ausgabe zum File (Stream) &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; erledigen und ansonsten genauso funktionieren wie das altbekannte &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;. Es ist also anzustreben, in &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; nur die File-Version aufzurufen um eine Doppel-Implementierung der Funktionalität zu vermeiden. Hierzu dient die Funktion &amp;lt;tt&amp;gt;fprintf_va&amp;lt;/tt&amp;gt;, die von &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;fprintf&amp;lt;/tt&amp;gt; einen File-Pointer, den Format-String sowie die Argumente erhält:&lt;br /&gt;
&lt;br /&gt;
 void fprintf (FILE * file, const char * format, ...)&lt;br /&gt;
 {&lt;br /&gt;
 	{{ccomment|Die Argumentliste 'args'}}&lt;br /&gt;
 	va_list args;&lt;br /&gt;
 	{{ccomment|Die variablen Argument beginnen nach 'format' }}&lt;br /&gt;
 	va_start (args, format);&lt;br /&gt;
 	{{ccomment|Die eigentliche Arbeit erledigt 'fprintf_va' }}&lt;br /&gt;
 	fprintf_va (file, format, args);&lt;br /&gt;
 	{{ccomment|fertig }}&lt;br /&gt;
 	va_end (args);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Fast genauso sieht unser &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; aus:&lt;br /&gt;
&lt;br /&gt;
 void printf (const char * format, ...)&lt;br /&gt;
 {&lt;br /&gt;
 	{{ccomment|Die Argumentliste 'args'}}&lt;br /&gt;
 	va_list args;&lt;br /&gt;
 	{{ccomment|Die variablen Argument beginnen nach 'format' }}&lt;br /&gt;
 	va_start (args, format);&lt;br /&gt;
 	{{ccomment|Die eigentliche Arbeit erledigt 'fprintf_va' }}&lt;br /&gt;
 	fprintf_va (stdout, format, args);&lt;br /&gt;
 	{{ccomment|fertig }}&lt;br /&gt;
 	va_end (args);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Was zu tun bleibt, ist die Implementioerung der eigentlichen Funktionalität in &amp;lt;tt&amp;gt;fprintf_va&amp;lt;/tt&amp;gt;. Diese durchfostet den Format-String und bei jedem %-Ausdruck wird ein weiteres Argument eingelesen und an eine passende Ausgabefunktion delegiert. Hier wird der Einfachheit halber nur &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;%s&amp;lt;/tt&amp;gt; implementiert:&lt;br /&gt;
&lt;br /&gt;
 static void fprintf_va (FILE * file, const char * fmt, va_list args)&lt;br /&gt;
 {&lt;br /&gt;
     char c;&lt;br /&gt;
 &lt;br /&gt;
     {{ccomment|Nächstes Zeichen des Formatstrings lesen und String-Ende abtesten }}&lt;br /&gt;
     while (c = *fmt++, c != '\0')&lt;br /&gt;
     {&lt;br /&gt;
         {{ccomment|Das Format-Zeichen }}&lt;br /&gt;
         if ('%' == c)&lt;br /&gt;
         {&lt;br /&gt;
             {{ccomment|Weiterlesen: das Zeichen nach dem % }}&lt;br /&gt;
             c = fmt++;&lt;br /&gt;
 &lt;br /&gt;
             {{ccomment|%% --&amp;gt; ein % ausgeben }}&lt;br /&gt;
             if ('%' == c)    fputc ('%', file);&lt;br /&gt;
             {{ccomment|%c --&amp;gt; Character ausgeben }}&lt;br /&gt;
             else if ('c' == c)    fputc (va_arg (args, int), file);&lt;br /&gt;
             {{ccomment|%s --&amp;gt; String ausgeben }}&lt;br /&gt;
             else if ('s' == c)    fputs (va_arg (args, char*), file);&lt;br /&gt;
             {{ccomment|Unbekannts %-Format }}&lt;br /&gt;
             else fputs (&amp;quot;???&amp;quot;, file);&lt;br /&gt;
 &lt;br /&gt;
             {{ccomment|Falls ein % am String-Ende steht }}&lt;br /&gt;
             if ('\0' == c)  return;&lt;br /&gt;
 &lt;br /&gt;
             continue;&lt;br /&gt;
         }&lt;br /&gt;
 &lt;br /&gt;
         {{ccomment|Für Win32: Zeilenumbruch ist carriage return + line feed }}&lt;br /&gt;
         if ('\n' == c)&lt;br /&gt;
             putc ('\r');&lt;br /&gt;
 &lt;br /&gt;
         {{ccomment|Zeichen ausgenen }}&lt;br /&gt;
         putc (c);&lt;br /&gt;
     } {{ccomment|while }}&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, einen 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;
* [[C-Tutorial/Interrupt-Programmierung]]&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>Tuffig</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=12851</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=12851"/>
				<updated>2007-10-28T09:24:15Z</updated>
		
		<summary type="html">&lt;p&gt;Tuffig: /* Rekursive Funktionen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Programmiersprache C wurde 1971 als Grundlage 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, [[Mikrocontroller]]) 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 im Allgemeuinen 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 und evtl. Umgebungsvariablen, 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 und der Initialisierung 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. C-Programme sind in so genannte Blöcke unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Konstrukte stellt ein eigenständiges Stück Code dar, das als solches gekennzeichnet werden muss. &lt;br /&gt;
&lt;br /&gt;
Die Kennzeichnung für einen Blockanfang ist die öffnende geschweifte Klammer, während ein Blockende mit der schliessenden Klammer notiert wird. Ein Block kann mehrere Teilblöcke enthalten, die wiederum Teilblöcke enthalten dürfen, etc. Öffnende und schliessende Block-Klammern tauchen immer Paarweise auf. &lt;br /&gt;
&lt;br /&gt;
Variablen, die in einem Block deklariert werden, sind nur innerhalb dieses Blocks &amp;amp;ndash; und damit auch in allen seinen Teilblöcken &amp;amp;ndash; gültig.&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;
Stell 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 ebenso...&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;
In C ist es möglich, einer Funktion eine variable Anzahl an Argumenten zu übergeben. Solche Funktionen haben eine Anzahl benamter Argumente wie &amp;quot;normale&amp;quot; Funktionen auch, jedoch folgt nach dem letzten benamten Argument eine beliebige Anzahl weiterer Argumente.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für eine solche Funktion ist das Bekannte &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;, für das zB folgende Aufrufe möglich sind:&lt;br /&gt;
 printf (&amp;quot;Hallo&amp;quot;);&lt;br /&gt;
 printf (&amp;quot;%c&amp;quot;, c);&lt;br /&gt;
 printf (&amp;quot;%s %d&amp;quot;, einString, 15);&lt;br /&gt;
 printf (&amp;quot;%d %d %d&amp;quot;, zahl1, zahl2, zahl3);&lt;br /&gt;
&lt;br /&gt;
Einer solchen Funktion muss die Anzahl der Argumente mitgeleilt werden, die ihr übergeben werden. Sies könnte dadurch geschehen, daß man ihr die Argumentanzahl explizit übergibt. Bei &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; wird die Anzahl der Übergabeparameter im Formatstring transportiert, ebenso wie die Typen der Übergebenen Variablen, denn die Funktion muss wissen, wie die übergebenen Werte zu interpretieren sind. Bei &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; geschieht dies wiederum mittls des Format-Strings.&lt;br /&gt;
&lt;br /&gt;
Der Prototyp einer varargs-Funktion sieht aus wie folgt, wobei die drei Pünktchen wörtlich zu nehmen sind und nicht etwa als abkürzende Schreibweise für die Parameterliste! &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdarg.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 extern void fprintf (FILE * file, const char * format, ...);&lt;br /&gt;
 extern void printf  (const char * format, ...);&lt;br /&gt;
 extern void fprintf_va (FILE * file, const char * format, va_list args);&lt;br /&gt;
&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;fprintf&amp;lt;/tt&amp;gt; soll eine Ausgabe zum File (Stream) &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; erledigen und ansonsten genauso funktionieren wie das altbekannte &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;. Es ist also anzustreben, in &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; nur die File-Version aufzurufen um eine Doppel-Implementierung der Funktionalität zu vermeiden. Hierzu dient die Funktion &amp;lt;tt&amp;gt;fprintf_va&amp;lt;/tt&amp;gt;, die von &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;fprintf&amp;lt;/tt&amp;gt; einen File-Pointer, den Format-String sowie die Argumente erhält:&lt;br /&gt;
&lt;br /&gt;
 void fprintf (FILE * file, const char * format, ...)&lt;br /&gt;
 {&lt;br /&gt;
 	{{ccomment|Die Argumentliste 'args'}}&lt;br /&gt;
 	va_list args;&lt;br /&gt;
 	{{ccomment|Die variablen Argument beginnen nach 'format' }}&lt;br /&gt;
 	va_start (args, format);&lt;br /&gt;
 	{{ccomment|Die eigentliche Arbeit erledigt 'fprintf_va' }}&lt;br /&gt;
 	fprintf_va (file, format, args);&lt;br /&gt;
 	{{ccomment|fertig }}&lt;br /&gt;
 	va_end (args);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Fast genauso sieht unser &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; aus:&lt;br /&gt;
&lt;br /&gt;
 void printf (const char * format, ...)&lt;br /&gt;
 {&lt;br /&gt;
 	{{ccomment|Die Argumentliste 'args'}}&lt;br /&gt;
 	va_list args;&lt;br /&gt;
 	{{ccomment|Die variablen Argument beginnen nach 'format' }}&lt;br /&gt;
 	va_start (args, format);&lt;br /&gt;
 	{{ccomment|Die eigentliche Arbeit erledigt 'fprintf_va' }}&lt;br /&gt;
 	fprintf_va (stdout, format, args);&lt;br /&gt;
 	{{ccomment|fertig }}&lt;br /&gt;
 	va_end (args);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Was zu tun bleibt, ist die Implementioerung der eigentlichen Funktionalität in &amp;lt;tt&amp;gt;fprintf_va&amp;lt;/tt&amp;gt;. Diese durchfostet den Format-String und bei jedem %-Ausdruck wird ein weiteres Argument eingelesen und an eine passende Ausgabefunktion delegiert. Hier wird der Einfachheit halber nur &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;%s&amp;lt;/tt&amp;gt; implementiert:&lt;br /&gt;
&lt;br /&gt;
 static void fprintf_va (FILE * file, const char * fmt, va_list args)&lt;br /&gt;
 {&lt;br /&gt;
     char c;&lt;br /&gt;
 &lt;br /&gt;
     {{ccomment|Nächstes Zeichen des Formatstrings lesen und String-Ende abtesten }}&lt;br /&gt;
     while (c = *fmt++, c != '\0')&lt;br /&gt;
     {&lt;br /&gt;
         {{ccomment|Das Format-Zeichen }}&lt;br /&gt;
         if ('%' == c)&lt;br /&gt;
         {&lt;br /&gt;
             {{ccomment|Weiterlesen: das Zeichen nach dem % }}&lt;br /&gt;
             c = fmt++;&lt;br /&gt;
 &lt;br /&gt;
             {{ccomment|%% --&amp;gt; ein % ausgeben }}&lt;br /&gt;
             if ('%' == c)    fputc ('%', file);&lt;br /&gt;
             {{ccomment|%c --&amp;gt; Character ausgeben }}&lt;br /&gt;
             else if ('c' == c)    fputc (va_arg (args, int), file);&lt;br /&gt;
             {{ccomment|%s --&amp;gt; String ausgeben }}&lt;br /&gt;
             else if ('s' == c)    fputs (va_arg (args, char*), file);&lt;br /&gt;
             {{ccomment|Unbekannts %-Format }}&lt;br /&gt;
             else fputs (&amp;quot;???&amp;quot;, file);&lt;br /&gt;
 &lt;br /&gt;
             {{ccomment|Falls ein % am String-Ende steht }}&lt;br /&gt;
             if ('\0' == c)  return;&lt;br /&gt;
 &lt;br /&gt;
             continue;&lt;br /&gt;
         }&lt;br /&gt;
 &lt;br /&gt;
         {{ccomment|Für Win32: Zeilenumbruch ist carriage return + line feed }}&lt;br /&gt;
         if ('\n' == c)&lt;br /&gt;
             putc ('\r');&lt;br /&gt;
 &lt;br /&gt;
         {{ccomment|Zeichen ausgenen }}&lt;br /&gt;
         putc (c);&lt;br /&gt;
     } {{ccomment|while }}&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;
* [[C-Tutorial/Interrupt-Programmierung]]&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>Tuffig</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=TWI_Praxis_Multimaster&amp;diff=12808</id>
		<title>TWI Praxis Multimaster</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=TWI_Praxis_Multimaster&amp;diff=12808"/>
				<updated>2007-10-12T18:06:58Z</updated>
		
		<summary type="html">&lt;p&gt;Tuffig: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Grundsätzlich ist ja im Artikel [[TWI Praxis]] alles dargestellt, was der Mensch braucht, um die Hardware TWI eines AVR zu verwenden. &lt;br /&gt;
&lt;br /&gt;
*Wenn &amp;quot;Multimaster&amp;quot; lediglich darin besteht, daß sich mehrere Master die I2C-Peripherie gewissermaßen teilen, reicht das auch völlig, da das TWI-Modul des Avr immer automatisch wartet, bis der Bus frei ist. &lt;br /&gt;
*Im Multimasterbetrieb mit gegenseitigem Zugriff treten allerdings Situationen auf, die die Sache dann leicht ins Stocken bringen&lt;br /&gt;
&lt;br /&gt;
=Konflikte=&lt;br /&gt;
==Bus Lost==&lt;br /&gt;
Die TWI-Hardware verfolgt ja immer den Bus, und wenn ein Master bei einem gerade besetzten Bus ein START absetzen will, wird einfach gewartet. Innerhalb eines kurzen Zeit-Fensters wird das allerdings zu spät bemerkt, da tritt dann die &amp;quot;Arbitrierung&amp;quot; in Kraft (ganz genau steht das im Datenblatt). Irgendwann merkt ein Master, daß ein anderer auch gerade Daten sendet und bricht dann seine eigene Übertragung ab. Status: Irgendeine Variante mit &amp;quot;Bus Lost&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Das einzig Sinnvolle ist es dann zu warten, bis der andere seine Übertragung beendet hat, und es dann ganz einfach wieder zu versuchen. Genauso ist es, wenn andere Störungen aufgetreten sind (Es reicht völlig, wenn ein anderer µC mit den Bascom-I2C Soft-Funktionen einfach irgendwann zu senden beginnt). &lt;br /&gt;
&lt;br /&gt;
==Deadlock==&lt;br /&gt;
Wenn so ein Multimaster gleichzeitig auch als Slave fungiert, kann aber auch ein Deadlock entstehen. Wenn wir einfach eine Sendeschleife definieren, bis wir mit unserer (Master) Sendung durchgekommen sind, und zur selben Zeit will ausgerechnet der Master, den wir gerade adressieren, mit der gleichen Strategie auf UNS zugreifen, finden beide Prozessoren kein Ende in ihrer Schleife. Jeder wartet, bis der andere endlich zuhört. &lt;br /&gt;
&lt;br /&gt;
In diesem Fall müssen wir den Sendeversuch eigentlich abbrechen und erstmal schauen, ob wir nicht selbst adressiert worden sind. Wenn ja, müssen wir erstmal das verarbeiten, was wir gekriegt haben und erst dann können wir nochmal einen Sendeversuch starten. &lt;br /&gt;
&lt;br /&gt;
=MyTWI.LIB=&lt;br /&gt;
Diese Bascom-Library versucht nun, diese Konflikte soweit abzuhandeln, daß der User nicht allzuviel damit konfrontiert ist. Zu dieser Library gehört eine Include-Datei MyTWI.BAS, die die Library, die Externals und einige Felder und Konstanten definiert.  [[TWI_Praxis_Multimaster#WebLinks_.2F_Download|Die vollständigen Originale können runtergeladen werden]]&lt;br /&gt;
==MyTWI.BAS==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$lib &amp;quot;MyTWI.LIB&amp;quot;&lt;br /&gt;
&lt;br /&gt;
$external Twi_sense&lt;br /&gt;
$external Mst_start&lt;br /&gt;
$external Mst_stop&lt;br /&gt;
$external Twi_mst_slv_isr&lt;br /&gt;
&lt;br /&gt;
Const Twi_m_sent = 1&lt;br /&gt;
Const Twi_m_recv = 2&lt;br /&gt;
Const Twi_timeout = 3&lt;br /&gt;
Const Twi_m_busy = 4&lt;br /&gt;
Const Twi_buserr = 7&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Felder für Master Transmitter/Receiver'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'-------------------------------------&lt;br /&gt;
'  twi-STRUCTURE MASTER&lt;br /&gt;
'-------------------------------------&lt;br /&gt;
Dim Twi_mst_flag As Byte                          '0     Kontroll-flags&lt;br /&gt;
Dim Twi_mst_addr As Byte                          '1     SLA + R/W&lt;br /&gt;
&lt;br /&gt;
Dim Twi_mt_curr As Byte                           '0     resv&lt;br /&gt;
Dim Twi_mt_data As Word                           '1/2   Data address&lt;br /&gt;
Dim Twi_mt_cntr As Byte                           '3     anzahl bytes&lt;br /&gt;
&lt;br /&gt;
Dim Twi_mr_curr As Byte                           '0     resv&lt;br /&gt;
Dim Twi_mr_data As Word                           '1/2   Data address&lt;br /&gt;
Dim Twi_mr_cntr As Byte                           '3     anzahl bytes&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Felder für Slave Receiver/Transmitter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'-------------------------------------&lt;br /&gt;
'  twi-STRUCTURE SLAVE RECV / TRANS&lt;br /&gt;
'-------------------------------------&lt;br /&gt;
Dim Twi_slv_flag As Byte                          '0     Kontroll-flags&lt;br /&gt;
Dim Twi_slv_addr As Byte                          '1     slave adresse&lt;br /&gt;
Dim Twi_slv_stat As Byte                          '2     twi-state (SLA)&lt;br /&gt;
&lt;br /&gt;
Dim Twi_sr_cntr As Byte                           '0     anzahl bytes&lt;br /&gt;
Dim Twi_sr_data As Word                           '1/2   Data-address&lt;br /&gt;
&lt;br /&gt;
Dim Twi_st_cntr As Byte                           '0     anzahl bytes&lt;br /&gt;
Dim Twi_st_data As Word                           '1/2   Data-address&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wofür die Felder dienen, ist im Demoprogramm am besten zu verstehen&lt;br /&gt;
&lt;br /&gt;
==M32Slave.BAS==&lt;br /&gt;
Das ist das &amp;quot;Haupt&amp;quot; Programm. Der Timer0 hat mit den TWI-Funktionen nichts zu tun. Er soll nur jede Sekunde eine TWI-Master-Sendung auslösen. &lt;br /&gt;
===Definitionen===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$regfile = &amp;quot;m32def.dat&amp;quot;       'das muß man für sich anpassen, logo&lt;br /&gt;
$crystal = 8000000            'detto&lt;br /&gt;
&lt;br /&gt;
$include &amp;quot;MyTWI.bas&amp;quot;          &lt;br /&gt;
&lt;br /&gt;
$baud = 9600                  'natürlich beliebig&lt;br /&gt;
&lt;br /&gt;
$hwstack = 64                 'Wegen der Interrupts + Reserve&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Const Tmr_c_prescale = 64&lt;br /&gt;
Const Tmr_c_preload = 131&lt;br /&gt;
Const Tmr_c_divis = 250&lt;br /&gt;
&lt;br /&gt;
'-------------------------------------------------&lt;br /&gt;
Config Timer0 = Timer , Prescale = Tmr_c_prescale           'Timer 1mS&lt;br /&gt;
On Timer0 Interrupt_ticker                                  ' Timer for Timer Queue&lt;br /&gt;
&lt;br /&gt;
Dim Timeout As Byte&lt;br /&gt;
Dim Timediv As Word&lt;br /&gt;
'-------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Declare Sub Twi_show_state(byref State As Byte)            'siehe weiter unten&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Adressen===&lt;br /&gt;
&lt;br /&gt;
Die verwendeten I2C-Adressen müß man natürlich auch auswählen&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'-------------------------------------------------&lt;br /&gt;
'  Die eigene I2C Adresse   (als Slave)&lt;br /&gt;
'-------------------------------------------------&lt;br /&gt;
Const Mn1_adr = &amp;amp;H6A&lt;br /&gt;
&lt;br /&gt;
'-------------------------------------------------&lt;br /&gt;
'  fremde I2C Adresse   (als Master)&lt;br /&gt;
'-------------------------------------------------&lt;br /&gt;
Const Mn2_adr = &amp;amp;H6E&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setup als Slave===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dim Twi_slv_buff(24) As Byte                                'Buffer für Slavefunktionen&lt;br /&gt;
&lt;br /&gt;
      Twi_slv_addr = Mn1_adr                                'lokale I2C-Adresse&lt;br /&gt;
      Twi_sr_data = Varptr(twi_slv_buff(1))                 'datenbuffer empfang&lt;br /&gt;
      Twi_st_data = Varptr(twi_slv_buff(1))                 'datenbuffer senden&lt;br /&gt;
&lt;br /&gt;
      Twar = Twi_slv_addr + 1                               'I2C Adress Mega32 + GCA&lt;br /&gt;
      Config Twi = 400000                                   'I2C Speed wahlweise&lt;br /&gt;
&lt;br /&gt;
      On Twi Twi_mst_slv_isr , Nosave                       'ISR f. TWI&lt;br /&gt;
&lt;br /&gt;
      Gosub Twi_sense                                       'Aktivieren Slave-Funktion&lt;br /&gt;
&lt;br /&gt;
      Enable Timer0                                         'Timer&lt;br /&gt;
      Enable Interrupts                                     'Generell&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Anmerkung: Wenn man nur &lt;br /&gt;
      Twar = Twi_slv_addr     &lt;br /&gt;
schreibt, wird ein GCA NICHT erkannt. &lt;br /&gt;
&lt;br /&gt;
===Hauptschleife===&lt;br /&gt;
Ob man als Slave angesprochen wurde, muß man natürlich periodisch abfragen und quittieren. Lange &amp;quot;WAIT&amp;quot; sind also nicht günstig&lt;br /&gt;
&lt;br /&gt;
====Hauptschleife Beginn====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   Do&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wer hätte das gedacht ? &lt;br /&gt;
&lt;br /&gt;
====Hauptschleife Slave-Flag abfragen====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      If Twi_slv_flag &amp;lt;&amp;gt; 0 Then&lt;br /&gt;
'-----------------------------------------------------------------&lt;br /&gt;
'             Vorsicht, der Bus ist solange blockiert&lt;br /&gt;
'-----------------------------------------------------------------&lt;br /&gt;
         Select Case Twi_slv_flag&lt;br /&gt;
         Case &amp;amp;H60 : Print Spc(30) ; &amp;quot;SLAVE recv:&amp;quot; ;        'es ist was empfangen worden&lt;br /&gt;
                  Print Hex(twi_slv_addr) ; &amp;quot; &amp;quot;;&lt;br /&gt;
                  For Temp = 1 To Twi_sr_cntr&lt;br /&gt;
                     Print Hex(twi_slv_buff(temp));         'print der Daten&lt;br /&gt;
                  Next&lt;br /&gt;
         Case &amp;amp;HA8 : Print Spc(30) ; &amp;quot;SLAVE tran:&amp;quot; ;        'es ist was abgeholt worden&lt;br /&gt;
                  Print Hex(twi_slv_addr) ; &amp;quot; &amp;quot;;&lt;br /&gt;
                  For Temp = 1 To Twi_st_cntr&lt;br /&gt;
                     Print Hex(twi_slv_buff(temp));        'print der Daten&lt;br /&gt;
                  Next&lt;br /&gt;
         Case &amp;amp;H70 : Print Spc(30) ; &amp;quot;SLAVE GCA :&amp;quot; ;        'ein General Call ist gekommen&lt;br /&gt;
                  Print Hex(twi_slv_addr) ; &amp;quot; &amp;quot;;&lt;br /&gt;
                  For Temp = 1 To Twi_sr_cntr&lt;br /&gt;
                     Print Hex(twi_slv_buff(temp));         'print der Daten&lt;br /&gt;
                  Next&lt;br /&gt;
         Case Else:&lt;br /&gt;
                  Print Chr(7) ;                            'Irgendein Fehler&lt;br /&gt;
                  Call Twi_show_state(twi_slv_flag)         'Print status-text&lt;br /&gt;
         End Select&lt;br /&gt;
         Print&lt;br /&gt;
         Twi_slv_flag = 0                                   'quittieren&lt;br /&gt;
         Twi_slv_stat = 0                                   '&lt;br /&gt;
         Gosub Twi_sense                                    'Slave wieder scharfmachen&lt;br /&gt;
                                                            'und Bus freigeben&lt;br /&gt;
      End If&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Der Kern: Slave auswerten'''      &lt;br /&gt;
*Twi_slv_flag = &lt;br /&gt;
**0 Keine Slave Aktion hat stattgefunden&lt;br /&gt;
**&amp;amp;H60 Daten wurden empfangen. Sie stehen im Buffer mit der Länge '''Twi_sr_cntr'''&lt;br /&gt;
**&amp;amp;HA8 Daten wurden gesendet. Sie stehen im Buffer mit der Länge Twi'''_st_cntr'''&lt;br /&gt;
**&amp;amp;H70 GCA-Daten wurden empfangen. &lt;br /&gt;
**else  Irgendein Fehler ist gewesen. Irgendeine Reaktion ist aber nicht notwendig.  &lt;br /&gt;
&lt;br /&gt;
'''Der Kern: Slave quittieren und wieder enablen'''      &lt;br /&gt;
 Twi_slv_flag = 0            &lt;br /&gt;
 Twi_slv_stat = 0            &lt;br /&gt;
 Gosub Twi_sense                                &lt;br /&gt;
&lt;br /&gt;
*Anmerkung: Die Demo geht natürlich bei &amp;quot;Slave Transmitter&amp;quot; ein wenig an der Realität vorbei. Normalerweiser wird ja erst in &amp;quot;Slave Receiver&amp;quot; festgelegt, welche Daten überhaupt zu senden sind. Daher ist eine nachträgliche Auswertung ja sinnlos. Bestenfalls als Bestätigung, daß sie der fremde Master auch tatsächlich geholt hat. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Hauptschleife wechseln auf Master====&lt;br /&gt;
Das ist jetzt reine Demo&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'-----------------------------------------------------------------&lt;br /&gt;
'         Jede Sekunde was senden &amp;amp; empfangen&lt;br /&gt;
'-----------------------------------------------------------------&lt;br /&gt;
      If Timeout = 1 Then&lt;br /&gt;
        Gosub Master_transmit                               'Senden in einer SUB&lt;br /&gt;
        If Twi_mst_flag = 0 Then                            'Hats geklappt ?&lt;br /&gt;
            Timeout = 0                                     'ja&lt;br /&gt;
'       else (sonst probieren wir's gleich nochmal)&lt;br /&gt;
         End If&lt;br /&gt;
      End If&lt;br /&gt;
'-----------------------------------------------------------------&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Hauptschleife Ende====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   Loop&lt;br /&gt;
End&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Sende-SUB===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'----------------------------------------&lt;br /&gt;
'   Beispiel 8 byte senden,&lt;br /&gt;
'     dann mit Rep.Start von gleicher adresse 3 Byte empfangen&lt;br /&gt;
'----------------------------------------&lt;br /&gt;
Master_transmit:&lt;br /&gt;
' sende buffer (mit testdaten) füllen&lt;br /&gt;
   For Temp = 1 To 24&lt;br /&gt;
      Twi_mst_buff(temp) = Slv_byte&lt;br /&gt;
   Next&lt;br /&gt;
&lt;br /&gt;
   Twi_mst_addr = Mn2_adr                                   'I2C adresse ZIEL&lt;br /&gt;
   Twi_mt_cntr = 8                                          '  8 Byte senden&lt;br /&gt;
   Twi_mt_data = Varptr(twi_mst_buff(1))                    ' Daten&lt;br /&gt;
&lt;br /&gt;
   Twi_mr_cntr = 3                                          ' dann 3 Byte empfangen&lt;br /&gt;
   Twi_mr_data = Varptr(twi_mst_buff(1))                    ' empfangsbuffer&lt;br /&gt;
&lt;br /&gt;
   Gosub Run_wait_master                                    ' noch eine SUB&lt;br /&gt;
&lt;br /&gt;
   Return&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Anmerkung:&lt;br /&gt;
&lt;br /&gt;
'''Nur senden'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   Twi_mst_addr = Mn2_adr                                   'I2C adresse ZIEL&lt;br /&gt;
   Twi_mt_cntr = 8                                          '  8 Byte senden&lt;br /&gt;
   Twi_mt_data = Varptr(twi_mst_buff(1))                    ' Daten&lt;br /&gt;
   Twi_mr_cntr = 0                                  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Nur abholen'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   Twi_mst_addr = Mn2_adr + 1                               'I2C adresse ZIEL (+R)&lt;br /&gt;
   Twi_mr_cntr = nn                                         ' wieviele Byte&lt;br /&gt;
   Twi_mr_data = Varptr(twi_mst_buff(1))                    ' empfangsbuffer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Durchführen der Master-Funktion===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Run_wait_master:&lt;br /&gt;
      Gosub Mst_start                                       'aufruf LIBRARY&lt;br /&gt;
      Select Case Twi_mst_flag                              'ergebnis ?&lt;br /&gt;
      Case Twi_m_sent:                                      'gesendet&lt;br /&gt;
               Print &amp;quot;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;MASTER sent:&amp;quot; ;&lt;br /&gt;
               Print Hex(twi_mst_addr) ; &amp;quot; &amp;quot;;&lt;br /&gt;
               For Temp = 1 To Twi_mt_cntr&lt;br /&gt;
                     Print Hex(twi_mst_buff(temp));&lt;br /&gt;
               Next&lt;br /&gt;
               Print&lt;br /&gt;
               Twi_mst_flag = 0&lt;br /&gt;
      Case Twi_m_recv:                                      'geholt&lt;br /&gt;
                Print &amp;quot;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;MASTER read:&amp;quot; ;&lt;br /&gt;
               Print Hex(twi_mst_addr) ; &amp;quot; &amp;quot;;&lt;br /&gt;
               For Temp = 1 To Twi_mr_cntr&lt;br /&gt;
                     Print Hex(twi_mst_buff(temp));&lt;br /&gt;
               Next&lt;br /&gt;
               Print&lt;br /&gt;
               Twi_mst_flag = 0&lt;br /&gt;
      Case Else:                                            'irgendein Problem&lt;br /&gt;
                Print Chr(7) ; Hex(twi_mst_addr) ; &amp;quot; &amp;quot;;&lt;br /&gt;
                Call Twi_show_state(twi_mst_flag)&lt;br /&gt;
      End Select&lt;br /&gt;
   Return&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
*Anmerkung: Auch das ist nur DEMO. Auswerten sollte man eventuell die Probleme, denn die bedeuten, daß das Ganze fehlgeschlagen ist, entweder, weil man gerade selbst adressiert wurde, oder weil eben irgendwas auf dem Bus passiert ist, was die Library-Funktion nicht abhandeln konnte.&lt;br /&gt;
&lt;br /&gt;
==TWI_Show_State.BAS==&lt;br /&gt;
Das ist ein unabhängiger Programmteil, der einfach den TWI Status mit Text über &amp;quot;PRINT&amp;quot; ausgibt. Für den Betrieb ist das nicht notwendig, er verbraucht wegen der Texte doch einigen Platz. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'----------------------------------------&lt;br /&gt;
'&lt;br /&gt;
'----------------------------------------&lt;br /&gt;
Sub Twi_show_state(byref State As Byte)&lt;br /&gt;
   Print Hex(state);&lt;br /&gt;
   Select Case State&lt;br /&gt;
   Case &amp;amp;H08 : Print &amp;quot; Start &amp;quot;&lt;br /&gt;
   Case &amp;amp;H10 : Print &amp;quot; Start Rep &amp;quot;&lt;br /&gt;
   Case &amp;amp;HA0 : Print &amp;quot; Stop / Rep Start  &amp;quot;&lt;br /&gt;
   Case &amp;amp;HA8 : Print &amp;quot; Sla R Received Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H60 : Print &amp;quot; Sla W Received Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H70 : Print &amp;quot; Gca Received Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H80 : Print &amp;quot; SR Sla Data Received Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H90 : Print &amp;quot; SR Gca Data Received Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H88 : Print &amp;quot; SR Sla Data Received Not Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H98 : Print &amp;quot; SR Gca Data Received Not Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;HB8 : Print &amp;quot; ST Data Transmitted Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;HC0 : Print &amp;quot; ST Data Transmitted Not Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;HC8 : Print &amp;quot; ST Last Data Transm Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H18 : Print &amp;quot; MT Sla W Transmitted Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H40 : Print &amp;quot; MT Sla R Transmitted Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H20 : Print &amp;quot; MT Sla W Transmitted Not Acked&amp;quot;&lt;br /&gt;
   Case &amp;amp;H48 : Print &amp;quot; MT Sla R Transmitted Not Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H38 : Print &amp;quot; MT Lost Or Sla R / W Not Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H68 : Print &amp;quot; MT Lost / Sla W Received Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H78 : Print &amp;quot; MT Lost / Gca Received Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;HB0 : Print &amp;quot; MT Lost / Sla R Received Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H28 : Print &amp;quot; MT Data Transmitted Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H30 : Print &amp;quot; MT Data Transmitted No Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H50 : Print &amp;quot; MT Data Received Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H58 : Print &amp;quot; MT Data Received Not Acked &amp;quot;&lt;br /&gt;
   Case Twi_timeout : Print &amp;quot; M  Timeout&amp;quot;&lt;br /&gt;
   Case Twi_m_busy : Print &amp;quot; TWI Busy&amp;quot;&lt;br /&gt;
   Case Twi_buserr : Print &amp;quot; Bus Error&amp;quot;&lt;br /&gt;
   Case Else : Print &amp;quot; ??&amp;quot;&lt;br /&gt;
   End Select&lt;br /&gt;
End Sub&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Demo-Programm=&lt;br /&gt;
*m32slave.bas demo/testprogramm &lt;br /&gt;
*twi_show_state.bas  Twi-Status printen &lt;br /&gt;
*mytwi.bas  includefile für die library &lt;br /&gt;
*mytwi.lib  Bascom library, gehört natürlich ins Bascom LIB directory &lt;br /&gt;
&lt;br /&gt;
'''Funktionen der Demo'''&lt;br /&gt;
*Das Demo definiert sich als Slave und sendet oder empfängt auf diese Weise Daten. &lt;br /&gt;
*Jede Sekunde aber sendet er selbst als Master Daten an einen anderen I2C-Slave und holt dann gleich auch Daten von dort ab&lt;br /&gt;
&lt;br /&gt;
=Test=&lt;br /&gt;
Getestet hab ich das im Kreuz-und Quer-Dauerbetrieb mit 3 Master/Slaves (2 x Atmega32, 1x AT90S2313 und den drei PCFs von der RNBFRA-Karte. &lt;br /&gt;
Die Busgeschwindigkeit ist mit 400 kHz recht günstig, da dadurch der Bus jweils nicht solange besetzt ist. Definitionsgemäß ist es nicht notwendig, daß alle Teilnehmer die gleiche Speed haben. &lt;br /&gt;
&lt;br /&gt;
 Vorsicht beim 2313: Wenn der mit den normalen Bascom I2C Funktionen sendet, benimmt er sich &lt;br /&gt;
 wie ein absoluter Terrorist, da er sich um nichts kümmert.&lt;br /&gt;
&lt;br /&gt;
Wenn der mitspielen soll, dann bitte [[Bascom_Soft-I2c_Library]] verwenden.&lt;br /&gt;
&lt;br /&gt;
=Autor=&lt;br /&gt;
[[Benutzer:PicNick]]&lt;br /&gt;
&lt;br /&gt;
= Siehe auch =&lt;br /&gt;
* [[I2C]]&lt;br /&gt;
* [[TWI]] &lt;br /&gt;
* [[TWI Praxis]] &lt;br /&gt;
&lt;br /&gt;
=WebLinks / Download=&lt;br /&gt;
* [http://www.oldformation.at/electronic/download/down.htm MyTWI (ZIP)]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Quellcode Bascom]]&lt;/div&gt;</summary>
		<author><name>Tuffig</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=TWI_Praxis_Multimaster&amp;diff=12807</id>
		<title>TWI Praxis Multimaster</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=TWI_Praxis_Multimaster&amp;diff=12807"/>
				<updated>2007-10-12T18:03:31Z</updated>
		
		<summary type="html">&lt;p&gt;Tuffig: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Grundsätzlich ist ja im Artikel [[TWI Praxis]] alles dargestellt, was der Mensch braucht, um die Hardware TWI eines AVR zu verwenden. &lt;br /&gt;
&lt;br /&gt;
*Wenn &amp;quot;Multimaster&amp;quot; lediglich darin besteht, daß sich mehrere Master die I2C-Perpherie gewissermaßen teilen, reicht das auch völlig, da das TWI-Modul des Avr immer automatisch wartet, bis der Bus frei ist. &lt;br /&gt;
*Im Multimasterbetrieb mit gegenseitigem Zugriff treten allerdings Situationen auf, die die Sache dann leicht ins Stocken bringen&lt;br /&gt;
&lt;br /&gt;
=Konflikte=&lt;br /&gt;
==Bus Lost==&lt;br /&gt;
Die TWI-Hardware verfolgt ja immer den Bus, und wenn ein Master bei einem gerade besetzten Bus ein START absetzen will, wird einfach gewartet. Innerhalb eines kurzen Zeit-Fensters wird das allerdings zu spät bemerkt, da tritt dann die &amp;quot;Arbitrierung&amp;quot; in Kraft (ganz genau steht das im Datenblatt). Irgendwann merkt ein Master, daß ein anderer auch gerade Daten sendet und bricht dann seine eigene Übertragung ab. Status: Irgendeine Variante mit &amp;quot;Bus Lost&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Das einzig Sinnvolle ist es dann zu warten, bis der andere seine Übertragung beendet hat, und es dann ganz einfach wieder zu versuchen. Genauso ist es, wenn andere Störungen aufgetreten sind (Es reicht völlig, wenn ein anderer µC mit den Bascom-I2C Soft-Funktionen einfach irgendwann zu senden beginnt). &lt;br /&gt;
&lt;br /&gt;
==Deadlock==&lt;br /&gt;
Wenn so ein Multimaster gleichzeitig auch als Slave fungiert, kann aber auch ein Deadlock entstehen. Wenn wir einfach eine Sendeschleife definieren, bis wir mit unserer (Master) Sendung durchgekommen sind, und zur selben Zeit will ausgerechnet der Master, den wir gerade adressieren, mit der gleichen Strategie auf UNS zugreifen, finden beide Prozessoren kein Ende in ihrer Schleife. Jeder wartet, bis der andere endlich zuhört. &lt;br /&gt;
&lt;br /&gt;
In diesem Fall müssen wir den Sendeversuch eigentlich abbrechen und erstmal schauen, ob wir nicht selbst adressiert worden sind. Wenn ja, müssen wir erstmal das verarbeiten, was wir gekriegt haben und erst dann können wir nochmal einen Sendeversuch starten. &lt;br /&gt;
&lt;br /&gt;
=MyTWI.LIB=&lt;br /&gt;
Diese Bascom-Library versucht nun, diese Konflikte soweit abzuhandeln, daß der User nicht allzuviel damit konfrontiert ist. Zu dieser Library gehört eine Include-Datei MyTWI.BAS, die die Library, die Externals und einige Felder und Konstanten definiert.  [[TWI_Praxis_Multimaster#WebLinks_.2F_Download|Die vollständigen Originale können runtergeladen werden]]&lt;br /&gt;
==MyTWI.BAS==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$lib &amp;quot;MyTWI.LIB&amp;quot;&lt;br /&gt;
&lt;br /&gt;
$external Twi_sense&lt;br /&gt;
$external Mst_start&lt;br /&gt;
$external Mst_stop&lt;br /&gt;
$external Twi_mst_slv_isr&lt;br /&gt;
&lt;br /&gt;
Const Twi_m_sent = 1&lt;br /&gt;
Const Twi_m_recv = 2&lt;br /&gt;
Const Twi_timeout = 3&lt;br /&gt;
Const Twi_m_busy = 4&lt;br /&gt;
Const Twi_buserr = 7&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Felder für Master Transmitter/Receiver'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'-------------------------------------&lt;br /&gt;
'  twi-STRUCTURE MASTER&lt;br /&gt;
'-------------------------------------&lt;br /&gt;
Dim Twi_mst_flag As Byte                          '0     Kontroll-flags&lt;br /&gt;
Dim Twi_mst_addr As Byte                          '1     SLA + R/W&lt;br /&gt;
&lt;br /&gt;
Dim Twi_mt_curr As Byte                           '0     resv&lt;br /&gt;
Dim Twi_mt_data As Word                           '1/2   Data address&lt;br /&gt;
Dim Twi_mt_cntr As Byte                           '3     anzahl bytes&lt;br /&gt;
&lt;br /&gt;
Dim Twi_mr_curr As Byte                           '0     resv&lt;br /&gt;
Dim Twi_mr_data As Word                           '1/2   Data address&lt;br /&gt;
Dim Twi_mr_cntr As Byte                           '3     anzahl bytes&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Felder für Slave Receiver/Transmitter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'-------------------------------------&lt;br /&gt;
'  twi-STRUCTURE SLAVE RECV / TRANS&lt;br /&gt;
'-------------------------------------&lt;br /&gt;
Dim Twi_slv_flag As Byte                          '0     Kontroll-flags&lt;br /&gt;
Dim Twi_slv_addr As Byte                          '1     slave adresse&lt;br /&gt;
Dim Twi_slv_stat As Byte                          '2     twi-state (SLA)&lt;br /&gt;
&lt;br /&gt;
Dim Twi_sr_cntr As Byte                           '0     anzahl bytes&lt;br /&gt;
Dim Twi_sr_data As Word                           '1/2   Data-address&lt;br /&gt;
&lt;br /&gt;
Dim Twi_st_cntr As Byte                           '0     anzahl bytes&lt;br /&gt;
Dim Twi_st_data As Word                           '1/2   Data-address&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wofür die Felder dienen, ist im Demoprogramm am besten zu verstehen&lt;br /&gt;
&lt;br /&gt;
==M32Slave.BAS==&lt;br /&gt;
Das ist das &amp;quot;Haupt&amp;quot; Programm. Der Timer0 hat mit den TWI-Funktionen nichts zu tun. Er soll nur jede Sekunde eine TWI-Master-Sendung auslösen. &lt;br /&gt;
===Definitionen===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$regfile = &amp;quot;m32def.dat&amp;quot;       'das muß man für sich anpassen, logo&lt;br /&gt;
$crystal = 8000000            'detto&lt;br /&gt;
&lt;br /&gt;
$include &amp;quot;MyTWI.bas&amp;quot;          &lt;br /&gt;
&lt;br /&gt;
$baud = 9600                  'natürlich beliebig&lt;br /&gt;
&lt;br /&gt;
$hwstack = 64                 'Wegen der Interrupts + Reserve&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Const Tmr_c_prescale = 64&lt;br /&gt;
Const Tmr_c_preload = 131&lt;br /&gt;
Const Tmr_c_divis = 250&lt;br /&gt;
&lt;br /&gt;
'-------------------------------------------------&lt;br /&gt;
Config Timer0 = Timer , Prescale = Tmr_c_prescale           'Timer 1mS&lt;br /&gt;
On Timer0 Interrupt_ticker                                  ' Timer for Timer Queue&lt;br /&gt;
&lt;br /&gt;
Dim Timeout As Byte&lt;br /&gt;
Dim Timediv As Word&lt;br /&gt;
'-------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Declare Sub Twi_show_state(byref State As Byte)            'siehe weiter unten&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Adressen===&lt;br /&gt;
&lt;br /&gt;
Die verwendeten I2C-Adressen müß man natürlich auch auswählen&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'-------------------------------------------------&lt;br /&gt;
'  Die eigene I2C Adresse   (als Slave)&lt;br /&gt;
'-------------------------------------------------&lt;br /&gt;
Const Mn1_adr = &amp;amp;H6A&lt;br /&gt;
&lt;br /&gt;
'-------------------------------------------------&lt;br /&gt;
'  fremde I2C Adresse   (als Master)&lt;br /&gt;
'-------------------------------------------------&lt;br /&gt;
Const Mn2_adr = &amp;amp;H6E&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setup als Slave===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dim Twi_slv_buff(24) As Byte                                'Buffer für Slavefunktionen&lt;br /&gt;
&lt;br /&gt;
      Twi_slv_addr = Mn1_adr                                'lokale I2C-Adresse&lt;br /&gt;
      Twi_sr_data = Varptr(twi_slv_buff(1))                 'datenbuffer empfang&lt;br /&gt;
      Twi_st_data = Varptr(twi_slv_buff(1))                 'datenbuffer senden&lt;br /&gt;
&lt;br /&gt;
      Twar = Twi_slv_addr + 1                               'I2C Adress Mega32 + GCA&lt;br /&gt;
      Config Twi = 400000                                   'I2C Speed wahlweise&lt;br /&gt;
&lt;br /&gt;
      On Twi Twi_mst_slv_isr , Nosave                       'ISR f. TWI&lt;br /&gt;
&lt;br /&gt;
      Gosub Twi_sense                                       'Aktivieren Slave-Funktion&lt;br /&gt;
&lt;br /&gt;
      Enable Timer0                                         'Timer&lt;br /&gt;
      Enable Interrupts                                     'Generell&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Anmerkung: Wenn man nur &lt;br /&gt;
      Twar = Twi_slv_addr     &lt;br /&gt;
schreibt, wird ein GCA NICHT erkannt. &lt;br /&gt;
&lt;br /&gt;
===Hauptschleife===&lt;br /&gt;
Ob man als Slave angesprochen wurde, muß man natürlich periodisch abfragen und quittieren. Lange &amp;quot;WAIT&amp;quot; sind also nicht günstig&lt;br /&gt;
&lt;br /&gt;
====Hauptschleife Beginn====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   Do&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wer hätte das gedacht ? &lt;br /&gt;
&lt;br /&gt;
====Hauptschleife Slave-Flag abfragen====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      If Twi_slv_flag &amp;lt;&amp;gt; 0 Then&lt;br /&gt;
'-----------------------------------------------------------------&lt;br /&gt;
'             Vorsicht, der Bus ist solange blockiert&lt;br /&gt;
'-----------------------------------------------------------------&lt;br /&gt;
         Select Case Twi_slv_flag&lt;br /&gt;
         Case &amp;amp;H60 : Print Spc(30) ; &amp;quot;SLAVE recv:&amp;quot; ;        'es ist was empfangen worden&lt;br /&gt;
                  Print Hex(twi_slv_addr) ; &amp;quot; &amp;quot;;&lt;br /&gt;
                  For Temp = 1 To Twi_sr_cntr&lt;br /&gt;
                     Print Hex(twi_slv_buff(temp));         'print der Daten&lt;br /&gt;
                  Next&lt;br /&gt;
         Case &amp;amp;HA8 : Print Spc(30) ; &amp;quot;SLAVE tran:&amp;quot; ;        'es ist was abgeholt worden&lt;br /&gt;
                  Print Hex(twi_slv_addr) ; &amp;quot; &amp;quot;;&lt;br /&gt;
                  For Temp = 1 To Twi_st_cntr&lt;br /&gt;
                     Print Hex(twi_slv_buff(temp));        'print der Daten&lt;br /&gt;
                  Next&lt;br /&gt;
         Case &amp;amp;H70 : Print Spc(30) ; &amp;quot;SLAVE GCA :&amp;quot; ;        'ein General Call ist gekommen&lt;br /&gt;
                  Print Hex(twi_slv_addr) ; &amp;quot; &amp;quot;;&lt;br /&gt;
                  For Temp = 1 To Twi_sr_cntr&lt;br /&gt;
                     Print Hex(twi_slv_buff(temp));         'print der Daten&lt;br /&gt;
                  Next&lt;br /&gt;
         Case Else:&lt;br /&gt;
                  Print Chr(7) ;                            'Irgendein Fehler&lt;br /&gt;
                  Call Twi_show_state(twi_slv_flag)         'Print status-text&lt;br /&gt;
         End Select&lt;br /&gt;
         Print&lt;br /&gt;
         Twi_slv_flag = 0                                   'quittieren&lt;br /&gt;
         Twi_slv_stat = 0                                   '&lt;br /&gt;
         Gosub Twi_sense                                    'Slave wieder scharfmachen&lt;br /&gt;
                                                            'und Bus freigeben&lt;br /&gt;
      End If&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Der Kern: Slave auswerten'''      &lt;br /&gt;
*Twi_slv_flag = &lt;br /&gt;
**0 Keine Slave Aktion hat stattgefunden&lt;br /&gt;
**&amp;amp;H60 Daten wurden empfangen. Sie stehen im Buffer mit der Länge '''Twi_sr_cntr'''&lt;br /&gt;
**&amp;amp;HA8 Daten wurden gesendet. Sie stehen im Buffer mit der Länge Twi'''_st_cntr'''&lt;br /&gt;
**&amp;amp;H70 GCA-Daten wurden empfangen. &lt;br /&gt;
**else  Irgendein Fehler ist gewesen. Irgendeine Reaktion ist aber nicht notwendig.  &lt;br /&gt;
&lt;br /&gt;
'''Der Kern: Slave quittieren und wieder enablen'''      &lt;br /&gt;
 Twi_slv_flag = 0            &lt;br /&gt;
 Twi_slv_stat = 0            &lt;br /&gt;
 Gosub Twi_sense                                &lt;br /&gt;
&lt;br /&gt;
*Anmerkung: Die Demo geht natürlich bei &amp;quot;Slave Transmitter&amp;quot; ein wenig an der Realität vorbei. Normalerweiser wird ja erst in &amp;quot;Slave Receiver&amp;quot; festgelegt, welche Daten überhaupt zu senden sind. Daher ist eine nachträgliche Auswertung ja sinnlos. Bestenfalls als Bestätigung, daß sie der fremde Master auch tatsächlich geholt hat. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Hauptschleife wechseln auf Master====&lt;br /&gt;
Das ist jetzt reine Demo&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'-----------------------------------------------------------------&lt;br /&gt;
'         Jede Sekunde was senden &amp;amp; empfangen&lt;br /&gt;
'-----------------------------------------------------------------&lt;br /&gt;
      If Timeout = 1 Then&lt;br /&gt;
        Gosub Master_transmit                               'Senden in einer SUB&lt;br /&gt;
        If Twi_mst_flag = 0 Then                            'Hats geklappt ?&lt;br /&gt;
            Timeout = 0                                     'ja&lt;br /&gt;
'       else (sonst probieren wir's gleich nochmal)&lt;br /&gt;
         End If&lt;br /&gt;
      End If&lt;br /&gt;
'-----------------------------------------------------------------&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Hauptschleife Ende====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   Loop&lt;br /&gt;
End&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Sende-SUB===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'----------------------------------------&lt;br /&gt;
'   Beispiel 8 byte senden,&lt;br /&gt;
'     dann mit Rep.Start von gleicher adresse 3 Byte empfangen&lt;br /&gt;
'----------------------------------------&lt;br /&gt;
Master_transmit:&lt;br /&gt;
' sende buffer (mit testdaten) füllen&lt;br /&gt;
   For Temp = 1 To 24&lt;br /&gt;
      Twi_mst_buff(temp) = Slv_byte&lt;br /&gt;
   Next&lt;br /&gt;
&lt;br /&gt;
   Twi_mst_addr = Mn2_adr                                   'I2C adresse ZIEL&lt;br /&gt;
   Twi_mt_cntr = 8                                          '  8 Byte senden&lt;br /&gt;
   Twi_mt_data = Varptr(twi_mst_buff(1))                    ' Daten&lt;br /&gt;
&lt;br /&gt;
   Twi_mr_cntr = 3                                          ' dann 3 Byte empfangen&lt;br /&gt;
   Twi_mr_data = Varptr(twi_mst_buff(1))                    ' empfangsbuffer&lt;br /&gt;
&lt;br /&gt;
   Gosub Run_wait_master                                    ' noch eine SUB&lt;br /&gt;
&lt;br /&gt;
   Return&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Anmerkung:&lt;br /&gt;
&lt;br /&gt;
'''Nur senden'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   Twi_mst_addr = Mn2_adr                                   'I2C adresse ZIEL&lt;br /&gt;
   Twi_mt_cntr = 8                                          '  8 Byte senden&lt;br /&gt;
   Twi_mt_data = Varptr(twi_mst_buff(1))                    ' Daten&lt;br /&gt;
   Twi_mr_cntr = 0                                  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Nur abholen'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   Twi_mst_addr = Mn2_adr + 1                               'I2C adresse ZIEL (+R)&lt;br /&gt;
   Twi_mr_cntr = nn                                         ' wieviele Byte&lt;br /&gt;
   Twi_mr_data = Varptr(twi_mst_buff(1))                    ' empfangsbuffer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Durchführen der Master-Funktion===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Run_wait_master:&lt;br /&gt;
      Gosub Mst_start                                       'aufruf LIBRARY&lt;br /&gt;
      Select Case Twi_mst_flag                              'ergebnis ?&lt;br /&gt;
      Case Twi_m_sent:                                      'gesendet&lt;br /&gt;
               Print &amp;quot;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;MASTER sent:&amp;quot; ;&lt;br /&gt;
               Print Hex(twi_mst_addr) ; &amp;quot; &amp;quot;;&lt;br /&gt;
               For Temp = 1 To Twi_mt_cntr&lt;br /&gt;
                     Print Hex(twi_mst_buff(temp));&lt;br /&gt;
               Next&lt;br /&gt;
               Print&lt;br /&gt;
               Twi_mst_flag = 0&lt;br /&gt;
      Case Twi_m_recv:                                      'geholt&lt;br /&gt;
                Print &amp;quot;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;MASTER read:&amp;quot; ;&lt;br /&gt;
               Print Hex(twi_mst_addr) ; &amp;quot; &amp;quot;;&lt;br /&gt;
               For Temp = 1 To Twi_mr_cntr&lt;br /&gt;
                     Print Hex(twi_mst_buff(temp));&lt;br /&gt;
               Next&lt;br /&gt;
               Print&lt;br /&gt;
               Twi_mst_flag = 0&lt;br /&gt;
      Case Else:                                            'irgendein Problem&lt;br /&gt;
                Print Chr(7) ; Hex(twi_mst_addr) ; &amp;quot; &amp;quot;;&lt;br /&gt;
                Call Twi_show_state(twi_mst_flag)&lt;br /&gt;
      End Select&lt;br /&gt;
   Return&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
*Anmerkung: Auch das ist nur DEMO. Auswerten sollte man eventuell die Probleme, denn die bedeuten, daß das Ganze fehlgeschlagen ist, entweder, weil man gerade selbst adressiert wurde, oder weil eben irgendwas auf dem Bus passiert ist, was die Library-Funktion nicht abhandeln konnte.&lt;br /&gt;
&lt;br /&gt;
==TWI_Show_State.BAS==&lt;br /&gt;
Das ist ein unabhängiger Programmteil, der einfach den TWI Status mit Text über &amp;quot;PRINT&amp;quot; ausgibt. Für den Betrieb ist das nicht notwendig, er verbraucht wegen der Texte doch einigen Platz. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'----------------------------------------&lt;br /&gt;
'&lt;br /&gt;
'----------------------------------------&lt;br /&gt;
Sub Twi_show_state(byref State As Byte)&lt;br /&gt;
   Print Hex(state);&lt;br /&gt;
   Select Case State&lt;br /&gt;
   Case &amp;amp;H08 : Print &amp;quot; Start &amp;quot;&lt;br /&gt;
   Case &amp;amp;H10 : Print &amp;quot; Start Rep &amp;quot;&lt;br /&gt;
   Case &amp;amp;HA0 : Print &amp;quot; Stop / Rep Start  &amp;quot;&lt;br /&gt;
   Case &amp;amp;HA8 : Print &amp;quot; Sla R Received Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H60 : Print &amp;quot; Sla W Received Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H70 : Print &amp;quot; Gca Received Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H80 : Print &amp;quot; SR Sla Data Received Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H90 : Print &amp;quot; SR Gca Data Received Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H88 : Print &amp;quot; SR Sla Data Received Not Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H98 : Print &amp;quot; SR Gca Data Received Not Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;HB8 : Print &amp;quot; ST Data Transmitted Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;HC0 : Print &amp;quot; ST Data Transmitted Not Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;HC8 : Print &amp;quot; ST Last Data Transm Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H18 : Print &amp;quot; MT Sla W Transmitted Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H40 : Print &amp;quot; MT Sla R Transmitted Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H20 : Print &amp;quot; MT Sla W Transmitted Not Acked&amp;quot;&lt;br /&gt;
   Case &amp;amp;H48 : Print &amp;quot; MT Sla R Transmitted Not Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H38 : Print &amp;quot; MT Lost Or Sla R / W Not Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H68 : Print &amp;quot; MT Lost / Sla W Received Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H78 : Print &amp;quot; MT Lost / Gca Received Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;HB0 : Print &amp;quot; MT Lost / Sla R Received Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H28 : Print &amp;quot; MT Data Transmitted Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H30 : Print &amp;quot; MT Data Transmitted No Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H50 : Print &amp;quot; MT Data Received Acked &amp;quot;&lt;br /&gt;
   Case &amp;amp;H58 : Print &amp;quot; MT Data Received Not Acked &amp;quot;&lt;br /&gt;
   Case Twi_timeout : Print &amp;quot; M  Timeout&amp;quot;&lt;br /&gt;
   Case Twi_m_busy : Print &amp;quot; TWI Busy&amp;quot;&lt;br /&gt;
   Case Twi_buserr : Print &amp;quot; Bus Error&amp;quot;&lt;br /&gt;
   Case Else : Print &amp;quot; ??&amp;quot;&lt;br /&gt;
   End Select&lt;br /&gt;
End Sub&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Demo-Programm=&lt;br /&gt;
*m32slave.bas demo/testprogramm &lt;br /&gt;
*twi_show_state.bas  Twi-Status printen &lt;br /&gt;
*mytwi.bas  includefile für die library &lt;br /&gt;
*mytwi.lib  Bascom library, gehört natürlich ins Bascom LIB directory &lt;br /&gt;
&lt;br /&gt;
'''Funktionen der Demo'''&lt;br /&gt;
*Das Demo definiert sich als Slave und sendet oder empfängt auf diese Weise Daten. &lt;br /&gt;
*Jede Sekunde aber sendet er selbst als Master Daten an einen anderen I2C-Slave und holt dann gleich auch Daten von dort ab&lt;br /&gt;
&lt;br /&gt;
=Test=&lt;br /&gt;
Getestet hab ich das im Kreuz-und Quer-Dauerbetrieb mit 3 Master/Slaves (2 x Atmega32, 1x AT90S2313 und den drei PCFs von der RNBFRA-Karte. &lt;br /&gt;
Die Busgeschwindigkeit ist mit 400 kHz recht günstig, da dadurch der Bus jweils nicht solange besetzt ist. Definitionsgemäß ist es nicht notwendig, daß alle Teilnehmer die gleiche Speed haben. &lt;br /&gt;
&lt;br /&gt;
 Vorsicht beim 2313: Wenn der mit den normalen Bascom I2C Funktionen sendet, benimmt er sich &lt;br /&gt;
 wie ein absoluter Terrorist, da er sich um nichts kümmert.&lt;br /&gt;
&lt;br /&gt;
Wenn der mitspielen soll, dann bitte [[Bascom_Soft-I2c_Library]] verwenden.&lt;br /&gt;
&lt;br /&gt;
=Autor=&lt;br /&gt;
[[Benutzer:PicNick]]&lt;br /&gt;
&lt;br /&gt;
= Siehe auch =&lt;br /&gt;
* [[I2C]]&lt;br /&gt;
* [[TWI]] &lt;br /&gt;
* [[TWI Praxis]] &lt;br /&gt;
&lt;br /&gt;
=WebLinks / Download=&lt;br /&gt;
* [http://www.oldformation.at/electronic/download/down.htm MyTWI (ZIP)]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Quellcode Bascom]]&lt;/div&gt;</summary>
		<author><name>Tuffig</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=12791</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=12791"/>
				<updated>2007-10-08T18:33:31Z</updated>
		
		<summary type="html">&lt;p&gt;Tuffig: /* Funktionen */&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 im Allgemeuinen 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 und evtl. Umgebungsvariablen, 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 und der Initialisierung 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. C-Programme sind in so genannte Blöcke unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Konstrukte stellt ein eigenständiges Stück Code dar, das als solches gekennzeichnet werden muss. &lt;br /&gt;
&lt;br /&gt;
Die Kennzeichnung für einen Blockanfang ist die öffnende geschweifte Klammer, während ein Blockende mit der schliessenden Klammer notiert wird. Ein Block kann mehrere Teilblöcke enthalten, die wiederum Teilblöcke enthalten dürfen, etc. Öffnende und schliessende Block-Klammern tauchen immer Paarweise auf. &lt;br /&gt;
&lt;br /&gt;
Variablen, die in einem Block deklariert werden, sind nur innerhalb dieses Blocks &amp;amp;ndash; und damit auch in allen seinen Teilblöcken &amp;amp;ndash; gültig.&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;
Stell 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;
In C ist es möglich, einer Funktion eine variable Anzahl an Argumenten zu übergeben. Solche Funktionen haben eine Anzahl benamter Argumente wie &amp;quot;normale&amp;quot; Funktionen auch, jedoch folgt nach dem letzten benamten Argument eine beliebige Anzahl weiterer Argumente.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für eine solche Funktion ist das Bekannte &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;, für das zB folgende Aufrufe möglich sind:&lt;br /&gt;
 printf (&amp;quot;Hallo&amp;quot;);&lt;br /&gt;
 printf (&amp;quot;%c&amp;quot;, c);&lt;br /&gt;
 printf (&amp;quot;%s %d&amp;quot;, einString, 15);&lt;br /&gt;
 printf (&amp;quot;%d %d %d&amp;quot;, zahl1, zahl2, zahl3);&lt;br /&gt;
&lt;br /&gt;
Einer solchen Funktion muss die Anzahl der Argumente mitgeleilt werden, die ihr übergeben werden. Sies könnte dadurch geschehen, daß man ihr die Argumentanzahl explizit übergibt. Bei &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; wird die Anzahl der Übergabeparameter im Formatstring transportiert, ebenso wie die Typen der Übergebenen Variablen, denn die Funktion muss wissen, wie die übergebenen Werte zu interpretieren sind. Bei &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; geschieht dies wiederum mittls des Format-Strings.&lt;br /&gt;
&lt;br /&gt;
Der Prototyp einer varargs-Funktion sieht aus wie folgt, wobei die drei Pünktchen wörtlich zu nehmen sind und nicht etwa als abkürzende Schreibweise für die Parameterliste! &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdarg.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 extern void fprintf (FILE * file, const char * format, ...);&lt;br /&gt;
 extern void printf  (const char * format, ...);&lt;br /&gt;
 extern void fprintf_va (FILE * file, const char * format, va_list args);&lt;br /&gt;
&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;fprintf&amp;lt;/tt&amp;gt; soll eine Ausgabe zum File (Stream) &amp;lt;tt&amp;gt;file&amp;lt;/tt&amp;gt; erledigen und ansonsten genauso funktionieren wie das altbekannte &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;. Es ist also anzustreben, in &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; nur die File-Version aufzurufen um eine Doppel-Implementierung der Funktionalität zu vermeiden. Hierzu dient die Funktion &amp;lt;tt&amp;gt;fprintf_va&amp;lt;/tt&amp;gt;, die von &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;fprintf&amp;lt;/tt&amp;gt; einen File-Pointer, den Format-String sowie die Argumente erhält:&lt;br /&gt;
&lt;br /&gt;
 void fprintf (FILE * file, const char * format, ...)&lt;br /&gt;
 {&lt;br /&gt;
 	{{ccomment|Die Argumentliste 'args'}}&lt;br /&gt;
 	va_list args;&lt;br /&gt;
 	{{ccomment|Die variablen Argument beginnen nach 'format' }}&lt;br /&gt;
 	va_start (args, format);&lt;br /&gt;
 	{{ccomment|Die eigentliche Arbeit erledigt 'fprintf_va' }}&lt;br /&gt;
 	fprintf_va (file, format, args);&lt;br /&gt;
 	{{ccomment|fertig }}&lt;br /&gt;
 	va_end (args);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Fast genauso sieht unser &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; aus:&lt;br /&gt;
&lt;br /&gt;
 void printf (const char * format, ...)&lt;br /&gt;
 {&lt;br /&gt;
 	{{ccomment|Die Argumentliste 'args'}}&lt;br /&gt;
 	va_list args;&lt;br /&gt;
 	{{ccomment|Die variablen Argument beginnen nach 'format' }}&lt;br /&gt;
 	va_start (args, format);&lt;br /&gt;
 	{{ccomment|Die eigentliche Arbeit erledigt 'fprintf_va' }}&lt;br /&gt;
 	fprintf_va (stdout, format, args);&lt;br /&gt;
 	{{ccomment|fertig }}&lt;br /&gt;
 	va_end (args);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Was zu tun bleibt, ist die Implementioerung der eigentlichen Funktionalität in &amp;lt;tt&amp;gt;fprintf_va&amp;lt;/tt&amp;gt;. Diese durchfostet den Format-String und bei jedem %-Ausdruck wird ein weiteres Argument eingelesen und an eine passende Ausgabefunktion delegiert. Hier wird der Einfachheit halber nur &amp;lt;tt&amp;gt;%c&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;%s&amp;lt;/tt&amp;gt; implementiert:&lt;br /&gt;
&lt;br /&gt;
 static void fprintf_va (FILE * file, const char * fmt, va_list args)&lt;br /&gt;
 {&lt;br /&gt;
     char c;&lt;br /&gt;
 &lt;br /&gt;
     {{ccomment|Nächstes Zeichen des Formatstrings lesen und String-Ende abtesten }}&lt;br /&gt;
     while (c = *fmt++, c != '\0')&lt;br /&gt;
     {&lt;br /&gt;
         {{ccomment|Das Format-Zeichen }}&lt;br /&gt;
         if ('%' == c)&lt;br /&gt;
         {&lt;br /&gt;
             {{ccomment|Weiterlesen: das Zeichen nach dem % }}&lt;br /&gt;
             c = fmt++;&lt;br /&gt;
 &lt;br /&gt;
             {{ccomment|%% --&amp;gt; ein % ausgeben }}&lt;br /&gt;
             if ('%' == c)    fputc ('%', file);&lt;br /&gt;
             {{ccomment|%c --&amp;gt; Character ausgeben }}&lt;br /&gt;
             else if ('c' == c)    fputc (va_arg (args, int), file);&lt;br /&gt;
             {{ccomment|%s --&amp;gt; String ausgeben }}&lt;br /&gt;
             else if ('s' == c)    fputs (va_arg (args, char*), file);&lt;br /&gt;
             {{ccomment|Unbekannts %-Format }}&lt;br /&gt;
             else fputs (&amp;quot;???&amp;quot;, file);&lt;br /&gt;
 &lt;br /&gt;
             {{ccomment|Falls ein % am String-Ende steht }}&lt;br /&gt;
             if ('\0' == c)  return;&lt;br /&gt;
 &lt;br /&gt;
             continue;&lt;br /&gt;
         }&lt;br /&gt;
 &lt;br /&gt;
         {{ccomment|Für Win32: Zeilenumbruch ist carriage return + line feed }}&lt;br /&gt;
         if ('\n' == c)&lt;br /&gt;
             putc ('\r');&lt;br /&gt;
 &lt;br /&gt;
         {{ccomment|Zeichen ausgenen }}&lt;br /&gt;
         putc (c);&lt;br /&gt;
     } {{ccomment|while }}&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;
* [[C-Tutorial/Interrupt-Programmierung]]&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>Tuffig</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_I2C_EEprom&amp;diff=12755</id>
		<title>Bascom und I2C EEprom</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Bascom_und_I2C_EEprom&amp;diff=12755"/>
				<updated>2007-09-29T09:12:34Z</updated>
		
		<summary type="html">&lt;p&gt;Tuffig: /* Beispiel für EEprom 24C16 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Ansteuern vom I2C EEproms mit Bascom ==&lt;br /&gt;
&lt;br /&gt;
Der Artikel demonstriert wie man EEPROM Speicherbausteine unter Bascom über den [[I2C]]-Bus anspricht.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Struktur: ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'---- schreiben ins EEprom ----------------------------------------&lt;br /&gt;
I2cstart                                   'Start I2C&lt;br /&gt;
I2cwbyte Slave Adresse&lt;br /&gt;
I2cwbyte Speicheradresse&lt;br /&gt;
I2cwbyte Wert&lt;br /&gt;
I2cstop                                    'Stop I2C&lt;br /&gt;
Waitms 10                                  'warte 10ms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'--- lesen vom EEprom --------------------------------------------&lt;br /&gt;
I2cstart                                    'Start I2C&lt;br /&gt;
I2cwbyte Slave Adresse  &lt;br /&gt;
I2cwbyte Speicheradresse&lt;br /&gt;
&lt;br /&gt;
I2cstart                                    'Start I2C&lt;br /&gt;
I2cwbyte Slave Adresse +1 für Lesen&lt;br /&gt;
I2crbyte lese Wert&lt;br /&gt;
I2cstop                                     'Stop I2C&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C16 ===&lt;br /&gt;
Zum besseren Verständnis werden hier die I2C Befehle untereinander geschrieben.&lt;br /&gt;
In einem grösserem Programm könnte man aber auch eine Sub-Routine deklarieren, die dann den Schreib/Lesevorgang abwickelt.&lt;br /&gt;
&lt;br /&gt;
(Eine Sub-Routine braucht aber ca. um die 30Byte pro Aufruf mehr an Speicher, als ein Gosub-Aufruf. Ich persönlich bleibe deshalb doch lieber bei den Gosub's.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel :'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'============I2C EEprom schreiben/lesen ==================================&lt;br /&gt;
&lt;br /&gt;
 ' =========== Für 24C16 EEprom =====================&lt;br /&gt;
 ' 8MHz Quarz&lt;br /&gt;
 ' LCD auf Port B ,&lt;br /&gt;
 '&lt;br /&gt;
$regfile = &amp;quot;m8def.dat&amp;quot;&lt;br /&gt;
$crystal = 8000000&lt;br /&gt;
&lt;br /&gt;
'---Config für LCD -----------------&lt;br /&gt;
Config Lcd = 40 * 2&lt;br /&gt;
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , Rs = Portb.4 , E = Portb.5&lt;br /&gt;
Config Lcdbus = 4&lt;br /&gt;
Config Lcdmode = Port&lt;br /&gt;
Cursor On&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'SDA und SCL definieren&lt;br /&gt;
Config Sda = Portd.5                                         &lt;br /&gt;
Config Scl = Portd.7                                        &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dim X As Byte&lt;br /&gt;
Dim A As Byte&lt;br /&gt;
Dim B As Byte&lt;br /&gt;
Dim Lesen As Byte&lt;br /&gt;
&lt;br /&gt;
CLS&lt;br /&gt;
Do&lt;br /&gt;
'---- schreibe in EEprom ----&lt;br /&gt;
For A = 1 To 10&lt;br /&gt;
Incr X                                    '1 bis Überlauf zählen&lt;br /&gt;
&lt;br /&gt;
I2cstart                                  'Start I2C&lt;br /&gt;
I2cwbyte &amp;amp;HA0                             'Sende Slave Adresse&lt;br /&gt;
I2cwbyte A                                'Sende Speicheradresse&lt;br /&gt;
I2cwbyte X                                'Sende Wert&lt;br /&gt;
I2cstop                                   'Stop I2C&lt;br /&gt;
Waitms 10                                 'warte 10ms&lt;br /&gt;
&lt;br /&gt;
Locate 1 , 1&lt;br /&gt;
Lcd &amp;quot;ins EEprom = &amp;quot; ; X ; &amp;quot;  &amp;quot;  ' Ausgabe der geschriebenen Werte am LCD&lt;br /&gt;
Waitms 500&lt;br /&gt;
Next A&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'--- lesen vom EEprom ----&lt;br /&gt;
For B = 1 To 10&lt;br /&gt;
&lt;br /&gt;
I2cstart                                    'Start I2C&lt;br /&gt;
I2cwbyte &amp;amp;HA0                               'sende Slave Adresse  &lt;br /&gt;
I2cwbyte B                                  'sende Speicheradresse&lt;br /&gt;
&lt;br /&gt;
I2cstart                                    'Start I2C&lt;br /&gt;
I2cwbyte &amp;amp;HA1                               'sende Slave Adresse +1 für Lesen&lt;br /&gt;
I2crbyte Lesen , Nack                       'lese Adresse vom EEprom&lt;br /&gt;
I2cstop                                     'Stop I2C&lt;br /&gt;
&lt;br /&gt;
Locate 2 , 1&lt;br /&gt;
Lcd &amp;quot;Lese  EEprom= &amp;quot; ; Lesen ; &amp;quot;  &amp;quot;                         'Ausgabe der EEprom Werte&lt;br /&gt;
Waitms 500&lt;br /&gt;
Next B&lt;br /&gt;
&lt;br /&gt;
Loop&lt;br /&gt;
End&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Schleife A schreibt den Wert 1-10 in die Speicherstelle 1-10 &amp;lt;br&amp;gt;&lt;br /&gt;
Schleife B liest Speicherstelle 1-10 wieder aus und zeigt dies auch am LCD an.&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C256 ===&lt;br /&gt;
&lt;br /&gt;
EEprom  24C32,24C128, 24C256 haben im Gegensatz zu den 24C16'er einen Adressraum von zwei Byte. (Weil grösserer Speicherbereich im EEprom vorhanden ist)&lt;br /&gt;
Darum muss man den Adressbereich in High und Low Adressbereich trennen.&lt;br /&gt;
(Zuerst High-Adressbereich schreiben und dann Low-Adressbereich) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel: ''' &amp;lt;br&amp;gt;&lt;br /&gt;
Wie Beispiel oben, nur mit erweiterten Adressbereich.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'============I2C EEprom schreiben/lesen ==================================&lt;br /&gt;
&lt;br /&gt;
 ' =========== Für 24C256 EEprom =====================&lt;br /&gt;
 ' 8MHz Quarz&lt;br /&gt;
 ' LCD auf Port B ,&lt;br /&gt;
 '&lt;br /&gt;
$regfile = &amp;quot;m8def.dat&amp;quot;&lt;br /&gt;
$crystal = 8000000&lt;br /&gt;
&lt;br /&gt;
'---Config für LCD -----------------&lt;br /&gt;
Config Lcd = 40 * 2&lt;br /&gt;
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , Rs = Portb.4 , E = Portb.5&lt;br /&gt;
Config Lcdbus = 4&lt;br /&gt;
Config Lcdmode = Port&lt;br /&gt;
Cursor On&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'SDA und SCL definieren&lt;br /&gt;
Config Sda = Portd.5                                         &lt;br /&gt;
Config Scl = Portd.7                                        &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dim X As Byte&lt;br /&gt;
Dim A As Byte&lt;br /&gt;
Dim B As Byte&lt;br /&gt;
Dim Lesen As Byte&lt;br /&gt;
CLS&lt;br /&gt;
&lt;br /&gt;
Do&lt;br /&gt;
'---- schreibe in EEprom ----&lt;br /&gt;
For A = 1 To 10&lt;br /&gt;
Incr X                                    '1 bis Überlauf zählen&lt;br /&gt;
&lt;br /&gt;
I2cstart                                  'Start I2C&lt;br /&gt;
I2cwbyte &amp;amp;HA0                             'Sende Slave Adresse&lt;br /&gt;
I2cwbyte 1                                'Sende Speicheradresse High&lt;br /&gt;
I2cwbyte A                                'Sende Speicheradresse LOw&lt;br /&gt;
I2cwbyte X                                'Sende Wert&lt;br /&gt;
I2cstop                                   'Stop I2C&lt;br /&gt;
Waitms 10                                 'warte 10ms&lt;br /&gt;
&lt;br /&gt;
Locate 1 , 1&lt;br /&gt;
Lcd &amp;quot;ins EEprom = &amp;quot; ; X ; &amp;quot;  &amp;quot;  ' Ausgabe der geschriebenen Werte am LCD&lt;br /&gt;
Waitms 500&lt;br /&gt;
Next A&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'--- lesen vom EEprom ----&lt;br /&gt;
For B = 1 To 10&lt;br /&gt;
&lt;br /&gt;
I2cstart                                    'Start I2C&lt;br /&gt;
I2cwbyte &amp;amp;HA0                               'sende Slave Adresse  &lt;br /&gt;
I2cwbyte 1                                  'sende Speicheradresse High&lt;br /&gt;
I2cwbyte B                                  'sende Speicheradresse Low&lt;br /&gt;
&lt;br /&gt;
I2cstart                                    'Start I2C&lt;br /&gt;
I2cwbyte &amp;amp;HA1                               'sende Slave Adresse +1 für Lesen&lt;br /&gt;
I2crbyte Lesen , Nack                       'lese Adresse vom EEprom&lt;br /&gt;
I2cstop                                     'Stop I2C&lt;br /&gt;
&lt;br /&gt;
Locate 2 , 1&lt;br /&gt;
Lcd &amp;quot;Lese  EEprom= &amp;quot; ; Lesen ; &amp;quot;  &amp;quot;                         'Ausgabe der EEprom Werte&lt;br /&gt;
Waitms 500&lt;br /&gt;
Next B&lt;br /&gt;
&lt;br /&gt;
Loop&lt;br /&gt;
End&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== High/Low Adressbereich mit Overlay leicht ansprechen ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'============I2C EEprom lesen/schreiben ==================================&lt;br /&gt;
&lt;br /&gt;
 '===========Für 24C256 EEprom=====================&lt;br /&gt;
 ' 8MHz Quarz&lt;br /&gt;
 ' LCD auf Port B ,&lt;br /&gt;
&lt;br /&gt;
$regfile = &amp;quot;m8def.dat&amp;quot;&lt;br /&gt;
$crystal = 8000000&lt;br /&gt;
&lt;br /&gt;
'---Config für LCD -----------------&lt;br /&gt;
Config Lcd = 40 * 2&lt;br /&gt;
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , Rs = Portb.4 , E = Portb.5&lt;br /&gt;
Config Lcdbus = 4&lt;br /&gt;
Config Lcdmode = Port&lt;br /&gt;
Cursor On&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Config Sda = Portd.5                                        ' I2C-Port festlegen&lt;br /&gt;
Config Scl = Portd.7                                        ' I2C-Port festlegen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dim X As Byte&lt;br /&gt;
Dim A As Word&lt;br /&gt;
Dim B As Word&lt;br /&gt;
Dim Schreiben As Byte&lt;br /&gt;
Dim Lesen As Byte&lt;br /&gt;
&lt;br /&gt;
Dim Adresse As Word At $160                      'Die Adresse als Word-Variable&lt;br /&gt;
Dim Low_adresse As Byte At $160 Overlay          'Zeiger auf das erste Byte&lt;br /&gt;
Dim High_adresse As Byte At $161 Overlay         'Zeiger auf das zweite Byte&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'===================Hauptprogramm===============================================&lt;br /&gt;
Do&lt;br /&gt;
&lt;br /&gt;
'----schreiben----&lt;br /&gt;
For Adresse = 250 To 260                          'Adresse geht über die Byte-Grenze&lt;br /&gt;
Incr X                                            '1 bis Überlauf&lt;br /&gt;
&lt;br /&gt;
I2cstart                                          'Start&lt;br /&gt;
I2cwbyte &amp;amp;HA0                                     'Sende Slavadresse&lt;br /&gt;
I2cwbyte High_adresse                             'Sende Speicheradresse High&lt;br /&gt;
I2cwbyte Low_adresse                              'Sende Speicheradresse  LOW&lt;br /&gt;
I2cwbyte X                                        'Sende Wert&lt;br /&gt;
I2cstop                                           'stop&lt;br /&gt;
Waitms 10&lt;br /&gt;
&lt;br /&gt;
Locate 1 , 1&lt;br /&gt;
Lcd &amp;quot;-&amp;gt;Adres.=&amp;quot; ; Adresse ; &amp;quot;Wert=&amp;quot; ; X ; &amp;quot;  &amp;quot;    'Anzeige vom schreiben&lt;br /&gt;
Waitms 500&lt;br /&gt;
Next Adresse&lt;br /&gt;
&lt;br /&gt;
'---lesen----&lt;br /&gt;
For Adresse = 250 To 260&lt;br /&gt;
I2cstart                                      'Start&lt;br /&gt;
I2cwbyte &amp;amp;HA0                                 'Sende Slavadresse +1 für Schreiben&lt;br /&gt;
I2cwbyte High_adresse                         'Sende Speicheradresse High&lt;br /&gt;
I2cwbyte Low_adresse                          'Sende Speicheradresse Low&lt;br /&gt;
&lt;br /&gt;
I2cstart                                      'Start&lt;br /&gt;
I2cwbyte &amp;amp;HA1                                 'Sende Slavadresse +1 für Lesen&lt;br /&gt;
I2crbyte Lesen , Nack                         'Lese Adresse vom EEprom&lt;br /&gt;
I2cstop                                       'Stop&lt;br /&gt;
&lt;br /&gt;
Locate 2 , 1&lt;br /&gt;
Lcd &amp;quot;&amp;lt;-Adres.=&amp;quot; ; Adresse ; &amp;quot;Wert=&amp;quot; ; Lesen ; &amp;quot;  &amp;quot;    'Anzeige vom lesen&lt;br /&gt;
Waitms 500&lt;br /&gt;
Next Adresse&lt;br /&gt;
&lt;br /&gt;
Loop&lt;br /&gt;
End&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Die Sache mit dem Overlay : ===&lt;br /&gt;
&lt;br /&gt;
 Dim Adresse As Word At $160      &lt;br /&gt;
&lt;br /&gt;
Hier definiere ich die Variable für die Adresse vom I2C-EEprom als Word-Variable. Die Variable soll ab Adresse $160 im Ram vom AVR abgelegt werden. Die Word-Variable hat einen Bereich von zwei Byte und braucht daher den Bereich von $160 - $161&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mit:                &lt;br /&gt;
 Dim Low_adresse As Byte At $160 Overlay          &lt;br /&gt;
 Dim High_adresse As Byte At $161 Overlay &lt;br /&gt;
weise ich der neuen (Pseudo) Variablen &amp;quot;Low_adresse&amp;quot; einen Zeiger auf die Speicherstelle $160 und &amp;quot;High_adresse&amp;quot;  einen Zeiger auf $161 zu.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Low_adresse&amp;quot; und &amp;quot;High_Adresse&amp;quot; sind also keine Variablen, sondern nur jeweils ein &amp;quot;Zeiger&amp;quot; auf diesen Speicherberreich der Variable: &amp;quot;Adresse&amp;quot; !&lt;br /&gt;
&lt;br /&gt;
Mit diesen zwei Zeigern habe ich automatisch jetzt meine Low und High Adressen für das I2C-EEprom.&lt;br /&gt;
&lt;br /&gt;
Ich kann diese zwei Zeiger jetzt ganz normal, wie Variablen, im Programm verwenden. :-)&lt;br /&gt;
&lt;br /&gt;
==Autor==&lt;br /&gt;
*  [[Benutzer:Roberto|Roberto]]&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
* [[Avr]]&lt;br /&gt;
* [[Bascom]]&lt;br /&gt;
* [[EEPROM]]&lt;br /&gt;
* [[I2C]]&lt;br /&gt;
&lt;br /&gt;
==Weblinks==&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=12086&amp;amp;highlight=eeprom Roboternetz-Thread]&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=15433&amp;amp;highlight=eeprom Roboternetz-Thread]&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=10945&amp;amp;highlight=eeprom Roboternetz-Thread]&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/viewtopic.php?t=15661 Roboternetz-Thread]&lt;br /&gt;
* http://www.eseo.de/i2c.htm&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Robotikeinstieg]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Quellcode Bascom]]&lt;/div&gt;</summary>
		<author><name>Tuffig</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_I2C_EEprom&amp;diff=12754</id>
		<title>Bascom und I2C EEprom</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Bascom_und_I2C_EEprom&amp;diff=12754"/>
				<updated>2007-09-29T09:12:02Z</updated>
		
		<summary type="html">&lt;p&gt;Tuffig: /* Beispiel für EEprom 24C256 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Ansteuern vom I2C EEproms mit Bascom ==&lt;br /&gt;
&lt;br /&gt;
Der Artikel demonstriert wie man EEPROM Speicherbausteine unter Bascom über den [[I2C]]-Bus anspricht.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Struktur: ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'---- schreiben ins EEprom ----------------------------------------&lt;br /&gt;
I2cstart                                   'Start I2C&lt;br /&gt;
I2cwbyte Slave Adresse&lt;br /&gt;
I2cwbyte Speicheradresse&lt;br /&gt;
I2cwbyte Wert&lt;br /&gt;
I2cstop                                    'Stop I2C&lt;br /&gt;
Waitms 10                                  'warte 10ms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'--- lesen vom EEprom --------------------------------------------&lt;br /&gt;
I2cstart                                    'Start I2C&lt;br /&gt;
I2cwbyte Slave Adresse  &lt;br /&gt;
I2cwbyte Speicheradresse&lt;br /&gt;
&lt;br /&gt;
I2cstart                                    'Start I2C&lt;br /&gt;
I2cwbyte Slave Adresse +1 für Lesen&lt;br /&gt;
I2crbyte lese Wert&lt;br /&gt;
I2cstop                                     'Stop I2C&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C16 ===&lt;br /&gt;
Zum besseren Verständnis werden hier die I2C Befehle untereinander geschrieben.&lt;br /&gt;
In einem grösserem Programm könnte man aber auch eine Sub-Routine deklarieren, die dann den Schreib/Lesevorgang abwickelt.&lt;br /&gt;
&lt;br /&gt;
(Eine Sub-Routine braucht aber ca. um die 30Byte pro Aufruf mehr an Speicher, als ein Gosub-Aufruf. Ich persönlich bleibe deshalb doch lieber bei den Gosub's.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel :'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'============I2C EEprom schreiben/lesen ==================================&lt;br /&gt;
&lt;br /&gt;
 ' =========== Für 24C16 EEprom =====================&lt;br /&gt;
 ' 8MHz Quarz&lt;br /&gt;
 ' LCD auf Port B ,&lt;br /&gt;
 '&lt;br /&gt;
$regfile = &amp;quot;m8def.dat&amp;quot;&lt;br /&gt;
$crystal = 8000000&lt;br /&gt;
&lt;br /&gt;
'---Config für LCD -----------------&lt;br /&gt;
Config Lcd = 40 * 2&lt;br /&gt;
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , Rs = Portb.4 , E = Portb.5&lt;br /&gt;
Config Lcdbus = 4&lt;br /&gt;
Config Lcdmode = Port&lt;br /&gt;
Cursor On&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'SDA und SCL definieren&lt;br /&gt;
Config Sda = Portd.5                                         &lt;br /&gt;
Config Scl = Portd.7                                        &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dim X As Byte&lt;br /&gt;
Dim A As Byte&lt;br /&gt;
Dim B As Byte&lt;br /&gt;
Dim Lesen As Byte&lt;br /&gt;
&lt;br /&gt;
CLS&lt;br /&gt;
Do&lt;br /&gt;
'---- schreibe in EEprom ----&lt;br /&gt;
For A = 1 To 10&lt;br /&gt;
Incr X                                    '1 bis Überlauf zählen&lt;br /&gt;
&lt;br /&gt;
I2cstart                                  'Start I2C&lt;br /&gt;
I2cwbyte &amp;amp;HA0                             'Sende Slave Adresse&lt;br /&gt;
I2cwbyte A                                'Sende Speicheradresse&lt;br /&gt;
I2cwbyte X                                'Sende Wert&lt;br /&gt;
I2cstop                                   'Stop I2C&lt;br /&gt;
Waitms 10                                 'warte 10ms&lt;br /&gt;
&lt;br /&gt;
Locate 1 , 1&lt;br /&gt;
Lcd &amp;quot;ins EEprom = &amp;quot; ; X ; &amp;quot;  &amp;quot;  ' Ausgabe der geschriebenen Werte am LCD&lt;br /&gt;
Waitms 500&lt;br /&gt;
Next A&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'--- lesen vom EEprom ----&lt;br /&gt;
For B = 1 To 10&lt;br /&gt;
&lt;br /&gt;
I2cstart                                    'Start I2C&lt;br /&gt;
I2cwbyte &amp;amp;HA0                               'sende Slave Adresse  &lt;br /&gt;
I2cwbyte B                                  'sende Speicheradresse&lt;br /&gt;
&lt;br /&gt;
I2cstart                                    'Start I2C&lt;br /&gt;
I2cwbyte &amp;amp;HA1                               'sende Slave Adresse +1 für lesen&lt;br /&gt;
I2crbyte Lesen , Nack                       'lese Adresse vom EEprom&lt;br /&gt;
I2cstop                                     'Stop I2C&lt;br /&gt;
&lt;br /&gt;
Locate 2 , 1&lt;br /&gt;
Lcd &amp;quot;Lese  EEprom= &amp;quot; ; Lesen ; &amp;quot;  &amp;quot;                         'Ausgabe der EEprom Werte&lt;br /&gt;
Waitms 500&lt;br /&gt;
Next B&lt;br /&gt;
&lt;br /&gt;
Loop&lt;br /&gt;
End&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Schleife A schreibt den Wert 1-10 in die Speicherstelle 1-10 &amp;lt;br&amp;gt;&lt;br /&gt;
Schleife B liest Speicherstelle 1-10 wieder aus und zeigt dies auch am LCD an.&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C256 ===&lt;br /&gt;
&lt;br /&gt;
EEprom  24C32,24C128, 24C256 haben im Gegensatz zu den 24C16'er einen Adressraum von zwei Byte. (Weil grösserer Speicherbereich im EEprom vorhanden ist)&lt;br /&gt;
Darum muss man den Adressbereich in High und Low Adressbereich trennen.&lt;br /&gt;
(Zuerst High-Adressbereich schreiben und dann Low-Adressbereich) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel: ''' &amp;lt;br&amp;gt;&lt;br /&gt;
Wie Beispiel oben, nur mit erweiterten Adressbereich.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'============I2C EEprom schreiben/lesen ==================================&lt;br /&gt;
&lt;br /&gt;
 ' =========== Für 24C256 EEprom =====================&lt;br /&gt;
 ' 8MHz Quarz&lt;br /&gt;
 ' LCD auf Port B ,&lt;br /&gt;
 '&lt;br /&gt;
$regfile = &amp;quot;m8def.dat&amp;quot;&lt;br /&gt;
$crystal = 8000000&lt;br /&gt;
&lt;br /&gt;
'---Config für LCD -----------------&lt;br /&gt;
Config Lcd = 40 * 2&lt;br /&gt;
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , Rs = Portb.4 , E = Portb.5&lt;br /&gt;
Config Lcdbus = 4&lt;br /&gt;
Config Lcdmode = Port&lt;br /&gt;
Cursor On&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'SDA und SCL definieren&lt;br /&gt;
Config Sda = Portd.5                                         &lt;br /&gt;
Config Scl = Portd.7                                        &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dim X As Byte&lt;br /&gt;
Dim A As Byte&lt;br /&gt;
Dim B As Byte&lt;br /&gt;
Dim Lesen As Byte&lt;br /&gt;
CLS&lt;br /&gt;
&lt;br /&gt;
Do&lt;br /&gt;
'---- schreibe in EEprom ----&lt;br /&gt;
For A = 1 To 10&lt;br /&gt;
Incr X                                    '1 bis Überlauf zählen&lt;br /&gt;
&lt;br /&gt;
I2cstart                                  'Start I2C&lt;br /&gt;
I2cwbyte &amp;amp;HA0                             'Sende Slave Adresse&lt;br /&gt;
I2cwbyte 1                                'Sende Speicheradresse High&lt;br /&gt;
I2cwbyte A                                'Sende Speicheradresse LOw&lt;br /&gt;
I2cwbyte X                                'Sende Wert&lt;br /&gt;
I2cstop                                   'Stop I2C&lt;br /&gt;
Waitms 10                                 'warte 10ms&lt;br /&gt;
&lt;br /&gt;
Locate 1 , 1&lt;br /&gt;
Lcd &amp;quot;ins EEprom = &amp;quot; ; X ; &amp;quot;  &amp;quot;  ' Ausgabe der geschriebenen Werte am LCD&lt;br /&gt;
Waitms 500&lt;br /&gt;
Next A&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'--- lesen vom EEprom ----&lt;br /&gt;
For B = 1 To 10&lt;br /&gt;
&lt;br /&gt;
I2cstart                                    'Start I2C&lt;br /&gt;
I2cwbyte &amp;amp;HA0                               'sende Slave Adresse  &lt;br /&gt;
I2cwbyte 1                                  'sende Speicheradresse High&lt;br /&gt;
I2cwbyte B                                  'sende Speicheradresse Low&lt;br /&gt;
&lt;br /&gt;
I2cstart                                    'Start I2C&lt;br /&gt;
I2cwbyte &amp;amp;HA1                               'sende Slave Adresse +1 für Lesen&lt;br /&gt;
I2crbyte Lesen , Nack                       'lese Adresse vom EEprom&lt;br /&gt;
I2cstop                                     'Stop I2C&lt;br /&gt;
&lt;br /&gt;
Locate 2 , 1&lt;br /&gt;
Lcd &amp;quot;Lese  EEprom= &amp;quot; ; Lesen ; &amp;quot;  &amp;quot;                         'Ausgabe der EEprom Werte&lt;br /&gt;
Waitms 500&lt;br /&gt;
Next B&lt;br /&gt;
&lt;br /&gt;
Loop&lt;br /&gt;
End&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== High/Low Adressbereich mit Overlay leicht ansprechen ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'============I2C EEprom lesen/schreiben ==================================&lt;br /&gt;
&lt;br /&gt;
 '===========Für 24C256 EEprom=====================&lt;br /&gt;
 ' 8MHz Quarz&lt;br /&gt;
 ' LCD auf Port B ,&lt;br /&gt;
&lt;br /&gt;
$regfile = &amp;quot;m8def.dat&amp;quot;&lt;br /&gt;
$crystal = 8000000&lt;br /&gt;
&lt;br /&gt;
'---Config für LCD -----------------&lt;br /&gt;
Config Lcd = 40 * 2&lt;br /&gt;
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , Rs = Portb.4 , E = Portb.5&lt;br /&gt;
Config Lcdbus = 4&lt;br /&gt;
Config Lcdmode = Port&lt;br /&gt;
Cursor On&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Config Sda = Portd.5                                        ' I2C-Port festlegen&lt;br /&gt;
Config Scl = Portd.7                                        ' I2C-Port festlegen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dim X As Byte&lt;br /&gt;
Dim A As Word&lt;br /&gt;
Dim B As Word&lt;br /&gt;
Dim Schreiben As Byte&lt;br /&gt;
Dim Lesen As Byte&lt;br /&gt;
&lt;br /&gt;
Dim Adresse As Word At $160                      'Die Adresse als Word-Variable&lt;br /&gt;
Dim Low_adresse As Byte At $160 Overlay          'Zeiger auf das erste Byte&lt;br /&gt;
Dim High_adresse As Byte At $161 Overlay         'Zeiger auf das zweite Byte&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'===================Hauptprogramm===============================================&lt;br /&gt;
Do&lt;br /&gt;
&lt;br /&gt;
'----schreiben----&lt;br /&gt;
For Adresse = 250 To 260                          'Adresse geht über die Byte-Grenze&lt;br /&gt;
Incr X                                            '1 bis Überlauf&lt;br /&gt;
&lt;br /&gt;
I2cstart                                          'Start&lt;br /&gt;
I2cwbyte &amp;amp;HA0                                     'Sende Slavadresse&lt;br /&gt;
I2cwbyte High_adresse                             'Sende Speicheradresse High&lt;br /&gt;
I2cwbyte Low_adresse                              'Sende Speicheradresse  LOW&lt;br /&gt;
I2cwbyte X                                        'Sende Wert&lt;br /&gt;
I2cstop                                           'stop&lt;br /&gt;
Waitms 10&lt;br /&gt;
&lt;br /&gt;
Locate 1 , 1&lt;br /&gt;
Lcd &amp;quot;-&amp;gt;Adres.=&amp;quot; ; Adresse ; &amp;quot;Wert=&amp;quot; ; X ; &amp;quot;  &amp;quot;    'Anzeige vom schreiben&lt;br /&gt;
Waitms 500&lt;br /&gt;
Next Adresse&lt;br /&gt;
&lt;br /&gt;
'---lesen----&lt;br /&gt;
For Adresse = 250 To 260&lt;br /&gt;
I2cstart                                      'Start&lt;br /&gt;
I2cwbyte &amp;amp;HA0                                 'Sende Slavadresse +1 für Schreiben&lt;br /&gt;
I2cwbyte High_adresse                         'Sende Speicheradresse High&lt;br /&gt;
I2cwbyte Low_adresse                          'Sende Speicheradresse Low&lt;br /&gt;
&lt;br /&gt;
I2cstart                                      'Start&lt;br /&gt;
I2cwbyte &amp;amp;HA1                                 'Sende Slavadresse +1 für Lesen&lt;br /&gt;
I2crbyte Lesen , Nack                         'Lese Adresse vom EEprom&lt;br /&gt;
I2cstop                                       'Stop&lt;br /&gt;
&lt;br /&gt;
Locate 2 , 1&lt;br /&gt;
Lcd &amp;quot;&amp;lt;-Adres.=&amp;quot; ; Adresse ; &amp;quot;Wert=&amp;quot; ; Lesen ; &amp;quot;  &amp;quot;    'Anzeige vom lesen&lt;br /&gt;
Waitms 500&lt;br /&gt;
Next Adresse&lt;br /&gt;
&lt;br /&gt;
Loop&lt;br /&gt;
End&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Die Sache mit dem Overlay : ===&lt;br /&gt;
&lt;br /&gt;
 Dim Adresse As Word At $160      &lt;br /&gt;
&lt;br /&gt;
Hier definiere ich die Variable für die Adresse vom I2C-EEprom als Word-Variable. Die Variable soll ab Adresse $160 im Ram vom AVR abgelegt werden. Die Word-Variable hat einen Bereich von zwei Byte und braucht daher den Bereich von $160 - $161&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mit:                &lt;br /&gt;
 Dim Low_adresse As Byte At $160 Overlay          &lt;br /&gt;
 Dim High_adresse As Byte At $161 Overlay &lt;br /&gt;
weise ich der neuen (Pseudo) Variablen &amp;quot;Low_adresse&amp;quot; einen Zeiger auf die Speicherstelle $160 und &amp;quot;High_adresse&amp;quot;  einen Zeiger auf $161 zu.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Low_adresse&amp;quot; und &amp;quot;High_Adresse&amp;quot; sind also keine Variablen, sondern nur jeweils ein &amp;quot;Zeiger&amp;quot; auf diesen Speicherberreich der Variable: &amp;quot;Adresse&amp;quot; !&lt;br /&gt;
&lt;br /&gt;
Mit diesen zwei Zeigern habe ich automatisch jetzt meine Low und High Adressen für das I2C-EEprom.&lt;br /&gt;
&lt;br /&gt;
Ich kann diese zwei Zeiger jetzt ganz normal, wie Variablen, im Programm verwenden. :-)&lt;br /&gt;
&lt;br /&gt;
==Autor==&lt;br /&gt;
*  [[Benutzer:Roberto|Roberto]]&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
* [[Avr]]&lt;br /&gt;
* [[Bascom]]&lt;br /&gt;
* [[EEPROM]]&lt;br /&gt;
* [[I2C]]&lt;br /&gt;
&lt;br /&gt;
==Weblinks==&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=12086&amp;amp;highlight=eeprom Roboternetz-Thread]&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=15433&amp;amp;highlight=eeprom Roboternetz-Thread]&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=10945&amp;amp;highlight=eeprom Roboternetz-Thread]&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/viewtopic.php?t=15661 Roboternetz-Thread]&lt;br /&gt;
* http://www.eseo.de/i2c.htm&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Robotikeinstieg]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Quellcode Bascom]]&lt;/div&gt;</summary>
		<author><name>Tuffig</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_I2C_EEprom&amp;diff=12753</id>
		<title>Bascom und I2C EEprom</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Bascom_und_I2C_EEprom&amp;diff=12753"/>
				<updated>2007-09-29T09:11:22Z</updated>
		
		<summary type="html">&lt;p&gt;Tuffig: /* Struktur: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Ansteuern vom I2C EEproms mit Bascom ==&lt;br /&gt;
&lt;br /&gt;
Der Artikel demonstriert wie man EEPROM Speicherbausteine unter Bascom über den [[I2C]]-Bus anspricht.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Struktur: ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'---- schreiben ins EEprom ----------------------------------------&lt;br /&gt;
I2cstart                                   'Start I2C&lt;br /&gt;
I2cwbyte Slave Adresse&lt;br /&gt;
I2cwbyte Speicheradresse&lt;br /&gt;
I2cwbyte Wert&lt;br /&gt;
I2cstop                                    'Stop I2C&lt;br /&gt;
Waitms 10                                  'warte 10ms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'--- lesen vom EEprom --------------------------------------------&lt;br /&gt;
I2cstart                                    'Start I2C&lt;br /&gt;
I2cwbyte Slave Adresse  &lt;br /&gt;
I2cwbyte Speicheradresse&lt;br /&gt;
&lt;br /&gt;
I2cstart                                    'Start I2C&lt;br /&gt;
I2cwbyte Slave Adresse +1 für Lesen&lt;br /&gt;
I2crbyte lese Wert&lt;br /&gt;
I2cstop                                     'Stop I2C&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C16 ===&lt;br /&gt;
Zum besseren Verständnis werden hier die I2C Befehle untereinander geschrieben.&lt;br /&gt;
In einem grösserem Programm könnte man aber auch eine Sub-Routine deklarieren, die dann den Schreib/Lesevorgang abwickelt.&lt;br /&gt;
&lt;br /&gt;
(Eine Sub-Routine braucht aber ca. um die 30Byte pro Aufruf mehr an Speicher, als ein Gosub-Aufruf. Ich persönlich bleibe deshalb doch lieber bei den Gosub's.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel :'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'============I2C EEprom schreiben/lesen ==================================&lt;br /&gt;
&lt;br /&gt;
 ' =========== Für 24C16 EEprom =====================&lt;br /&gt;
 ' 8MHz Quarz&lt;br /&gt;
 ' LCD auf Port B ,&lt;br /&gt;
 '&lt;br /&gt;
$regfile = &amp;quot;m8def.dat&amp;quot;&lt;br /&gt;
$crystal = 8000000&lt;br /&gt;
&lt;br /&gt;
'---Config für LCD -----------------&lt;br /&gt;
Config Lcd = 40 * 2&lt;br /&gt;
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , Rs = Portb.4 , E = Portb.5&lt;br /&gt;
Config Lcdbus = 4&lt;br /&gt;
Config Lcdmode = Port&lt;br /&gt;
Cursor On&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'SDA und SCL definieren&lt;br /&gt;
Config Sda = Portd.5                                         &lt;br /&gt;
Config Scl = Portd.7                                        &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dim X As Byte&lt;br /&gt;
Dim A As Byte&lt;br /&gt;
Dim B As Byte&lt;br /&gt;
Dim Lesen As Byte&lt;br /&gt;
&lt;br /&gt;
CLS&lt;br /&gt;
Do&lt;br /&gt;
'---- schreibe in EEprom ----&lt;br /&gt;
For A = 1 To 10&lt;br /&gt;
Incr X                                    '1 bis Überlauf zählen&lt;br /&gt;
&lt;br /&gt;
I2cstart                                  'Start I2C&lt;br /&gt;
I2cwbyte &amp;amp;HA0                             'Sende Slave Adresse&lt;br /&gt;
I2cwbyte A                                'Sende Speicheradresse&lt;br /&gt;
I2cwbyte X                                'Sende Wert&lt;br /&gt;
I2cstop                                   'Stop I2C&lt;br /&gt;
Waitms 10                                 'warte 10ms&lt;br /&gt;
&lt;br /&gt;
Locate 1 , 1&lt;br /&gt;
Lcd &amp;quot;ins EEprom = &amp;quot; ; X ; &amp;quot;  &amp;quot;  ' Ausgabe der geschriebenen Werte am LCD&lt;br /&gt;
Waitms 500&lt;br /&gt;
Next A&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'--- lesen vom EEprom ----&lt;br /&gt;
For B = 1 To 10&lt;br /&gt;
&lt;br /&gt;
I2cstart                                    'Start I2C&lt;br /&gt;
I2cwbyte &amp;amp;HA0                               'sende Slave Adresse  &lt;br /&gt;
I2cwbyte B                                  'sende Speicheradresse&lt;br /&gt;
&lt;br /&gt;
I2cstart                                    'Start I2C&lt;br /&gt;
I2cwbyte &amp;amp;HA1                               'sende Slave Adresse +1 für lesen&lt;br /&gt;
I2crbyte Lesen , Nack                       'lese Adresse vom EEprom&lt;br /&gt;
I2cstop                                     'Stop I2C&lt;br /&gt;
&lt;br /&gt;
Locate 2 , 1&lt;br /&gt;
Lcd &amp;quot;Lese  EEprom= &amp;quot; ; Lesen ; &amp;quot;  &amp;quot;                         'Ausgabe der EEprom Werte&lt;br /&gt;
Waitms 500&lt;br /&gt;
Next B&lt;br /&gt;
&lt;br /&gt;
Loop&lt;br /&gt;
End&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Schleife A schreibt den Wert 1-10 in die Speicherstelle 1-10 &amp;lt;br&amp;gt;&lt;br /&gt;
Schleife B liest Speicherstelle 1-10 wieder aus und zeigt dies auch am LCD an.&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C256 ===&lt;br /&gt;
&lt;br /&gt;
EEprom  24C32,24C128, 24C256 haben im Gegensatz zu den 24C16'er einen Adressraum von zwei Byte. (Weil grösserer Speicherbereich im EEprom vorhanden ist)&lt;br /&gt;
Darum muss man den Adressbereich in High und Low Adressbereich trennen.&lt;br /&gt;
(Zuerst High-Adressbereich schreiben und dann Low-Adressbereich) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel: ''' &amp;lt;br&amp;gt;&lt;br /&gt;
Wie Beispiel oben, nur mit erweiterten Adressbereich.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'============I2C EEprom schreiben/lesen ==================================&lt;br /&gt;
&lt;br /&gt;
 ' =========== Für 24C256 EEprom =====================&lt;br /&gt;
 ' 8MHz Quarz&lt;br /&gt;
 ' LCD auf Port B ,&lt;br /&gt;
 '&lt;br /&gt;
$regfile = &amp;quot;m8def.dat&amp;quot;&lt;br /&gt;
$crystal = 8000000&lt;br /&gt;
&lt;br /&gt;
'---Config für LCD -----------------&lt;br /&gt;
Config Lcd = 40 * 2&lt;br /&gt;
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , Rs = Portb.4 , E = Portb.5&lt;br /&gt;
Config Lcdbus = 4&lt;br /&gt;
Config Lcdmode = Port&lt;br /&gt;
Cursor On&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'SDA und SCL definieren&lt;br /&gt;
Config Sda = Portd.5                                         &lt;br /&gt;
Config Scl = Portd.7                                        &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dim X As Byte&lt;br /&gt;
Dim A As Byte&lt;br /&gt;
Dim B As Byte&lt;br /&gt;
Dim Lesen As Byte&lt;br /&gt;
CLS&lt;br /&gt;
&lt;br /&gt;
Do&lt;br /&gt;
'---- schreibe in EEprom ----&lt;br /&gt;
For A = 1 To 10&lt;br /&gt;
Incr X                                    '1 bis Überlauf zählen&lt;br /&gt;
&lt;br /&gt;
I2cstart                                  'Start I2C&lt;br /&gt;
I2cwbyte &amp;amp;HA0                             'Sende Slave Adresse&lt;br /&gt;
I2cwbyte 1                                'Sende Speicheradresse High&lt;br /&gt;
I2cwbyte A                                'Sende Speicheradresse LOw&lt;br /&gt;
I2cwbyte X                                'Sende Wert&lt;br /&gt;
I2cstop                                   'Stop I2C&lt;br /&gt;
Waitms 10                                 'warte 10ms&lt;br /&gt;
&lt;br /&gt;
Locate 1 , 1&lt;br /&gt;
Lcd &amp;quot;ins EEprom = &amp;quot; ; X ; &amp;quot;  &amp;quot;  ' Ausgabe der geschriebenen Werte am LCD&lt;br /&gt;
Waitms 500&lt;br /&gt;
Next A&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'--- lesen vom EEprom ----&lt;br /&gt;
For B = 1 To 10&lt;br /&gt;
&lt;br /&gt;
I2cstart                                    'Start I2C&lt;br /&gt;
I2cwbyte &amp;amp;HA0                               'sende Slave Adresse  &lt;br /&gt;
I2cwbyte 1                                  'sende Speicheradresse High&lt;br /&gt;
I2cwbyte B                                  'sende Speicheradresse Low&lt;br /&gt;
&lt;br /&gt;
I2cstart                                    'Start I2C&lt;br /&gt;
I2cwbyte &amp;amp;HA1                               'sende Slave Adresse +1 für schreiben&lt;br /&gt;
I2crbyte Lesen , Nack                       'lese Adresse vom EEprom&lt;br /&gt;
I2cstop                                     'Stop I2C&lt;br /&gt;
&lt;br /&gt;
Locate 2 , 1&lt;br /&gt;
Lcd &amp;quot;Lese  EEprom= &amp;quot; ; Lesen ; &amp;quot;  &amp;quot;                         'Ausgabe der EEprom Werte&lt;br /&gt;
Waitms 500&lt;br /&gt;
Next B&lt;br /&gt;
&lt;br /&gt;
Loop&lt;br /&gt;
End&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== High/Low Adressbereich mit Overlay leicht ansprechen ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'============I2C EEprom lesen/schreiben ==================================&lt;br /&gt;
&lt;br /&gt;
 '===========Für 24C256 EEprom=====================&lt;br /&gt;
 ' 8MHz Quarz&lt;br /&gt;
 ' LCD auf Port B ,&lt;br /&gt;
&lt;br /&gt;
$regfile = &amp;quot;m8def.dat&amp;quot;&lt;br /&gt;
$crystal = 8000000&lt;br /&gt;
&lt;br /&gt;
'---Config für LCD -----------------&lt;br /&gt;
Config Lcd = 40 * 2&lt;br /&gt;
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , Rs = Portb.4 , E = Portb.5&lt;br /&gt;
Config Lcdbus = 4&lt;br /&gt;
Config Lcdmode = Port&lt;br /&gt;
Cursor On&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Config Sda = Portd.5                                        ' I2C-Port festlegen&lt;br /&gt;
Config Scl = Portd.7                                        ' I2C-Port festlegen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dim X As Byte&lt;br /&gt;
Dim A As Word&lt;br /&gt;
Dim B As Word&lt;br /&gt;
Dim Schreiben As Byte&lt;br /&gt;
Dim Lesen As Byte&lt;br /&gt;
&lt;br /&gt;
Dim Adresse As Word At $160                      'Die Adresse als Word-Variable&lt;br /&gt;
Dim Low_adresse As Byte At $160 Overlay          'Zeiger auf das erste Byte&lt;br /&gt;
Dim High_adresse As Byte At $161 Overlay         'Zeiger auf das zweite Byte&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'===================Hauptprogramm===============================================&lt;br /&gt;
Do&lt;br /&gt;
&lt;br /&gt;
'----schreiben----&lt;br /&gt;
For Adresse = 250 To 260                          'Adresse geht über die Byte-Grenze&lt;br /&gt;
Incr X                                            '1 bis Überlauf&lt;br /&gt;
&lt;br /&gt;
I2cstart                                          'Start&lt;br /&gt;
I2cwbyte &amp;amp;HA0                                     'Sende Slavadresse&lt;br /&gt;
I2cwbyte High_adresse                             'Sende Speicheradresse High&lt;br /&gt;
I2cwbyte Low_adresse                              'Sende Speicheradresse  LOW&lt;br /&gt;
I2cwbyte X                                        'Sende Wert&lt;br /&gt;
I2cstop                                           'stop&lt;br /&gt;
Waitms 10&lt;br /&gt;
&lt;br /&gt;
Locate 1 , 1&lt;br /&gt;
Lcd &amp;quot;-&amp;gt;Adres.=&amp;quot; ; Adresse ; &amp;quot;Wert=&amp;quot; ; X ; &amp;quot;  &amp;quot;    'Anzeige vom schreiben&lt;br /&gt;
Waitms 500&lt;br /&gt;
Next Adresse&lt;br /&gt;
&lt;br /&gt;
'---lesen----&lt;br /&gt;
For Adresse = 250 To 260&lt;br /&gt;
I2cstart                                      'Start&lt;br /&gt;
I2cwbyte &amp;amp;HA0                                 'Sende Slavadresse +1 für Schreiben&lt;br /&gt;
I2cwbyte High_adresse                         'Sende Speicheradresse High&lt;br /&gt;
I2cwbyte Low_adresse                          'Sende Speicheradresse Low&lt;br /&gt;
&lt;br /&gt;
I2cstart                                      'Start&lt;br /&gt;
I2cwbyte &amp;amp;HA1                                 'Sende Slavadresse +1 für Lesen&lt;br /&gt;
I2crbyte Lesen , Nack                         'Lese Adresse vom EEprom&lt;br /&gt;
I2cstop                                       'Stop&lt;br /&gt;
&lt;br /&gt;
Locate 2 , 1&lt;br /&gt;
Lcd &amp;quot;&amp;lt;-Adres.=&amp;quot; ; Adresse ; &amp;quot;Wert=&amp;quot; ; Lesen ; &amp;quot;  &amp;quot;    'Anzeige vom lesen&lt;br /&gt;
Waitms 500&lt;br /&gt;
Next Adresse&lt;br /&gt;
&lt;br /&gt;
Loop&lt;br /&gt;
End&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Die Sache mit dem Overlay : ===&lt;br /&gt;
&lt;br /&gt;
 Dim Adresse As Word At $160      &lt;br /&gt;
&lt;br /&gt;
Hier definiere ich die Variable für die Adresse vom I2C-EEprom als Word-Variable. Die Variable soll ab Adresse $160 im Ram vom AVR abgelegt werden. Die Word-Variable hat einen Bereich von zwei Byte und braucht daher den Bereich von $160 - $161&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mit:                &lt;br /&gt;
 Dim Low_adresse As Byte At $160 Overlay          &lt;br /&gt;
 Dim High_adresse As Byte At $161 Overlay &lt;br /&gt;
weise ich der neuen (Pseudo) Variablen &amp;quot;Low_adresse&amp;quot; einen Zeiger auf die Speicherstelle $160 und &amp;quot;High_adresse&amp;quot;  einen Zeiger auf $161 zu.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Low_adresse&amp;quot; und &amp;quot;High_Adresse&amp;quot; sind also keine Variablen, sondern nur jeweils ein &amp;quot;Zeiger&amp;quot; auf diesen Speicherberreich der Variable: &amp;quot;Adresse&amp;quot; !&lt;br /&gt;
&lt;br /&gt;
Mit diesen zwei Zeigern habe ich automatisch jetzt meine Low und High Adressen für das I2C-EEprom.&lt;br /&gt;
&lt;br /&gt;
Ich kann diese zwei Zeiger jetzt ganz normal, wie Variablen, im Programm verwenden. :-)&lt;br /&gt;
&lt;br /&gt;
==Autor==&lt;br /&gt;
*  [[Benutzer:Roberto|Roberto]]&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
* [[Avr]]&lt;br /&gt;
* [[Bascom]]&lt;br /&gt;
* [[EEPROM]]&lt;br /&gt;
* [[I2C]]&lt;br /&gt;
&lt;br /&gt;
==Weblinks==&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=12086&amp;amp;highlight=eeprom Roboternetz-Thread]&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=15433&amp;amp;highlight=eeprom Roboternetz-Thread]&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=10945&amp;amp;highlight=eeprom Roboternetz-Thread]&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/viewtopic.php?t=15661 Roboternetz-Thread]&lt;br /&gt;
* http://www.eseo.de/i2c.htm&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Robotikeinstieg]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Quellcode Bascom]]&lt;/div&gt;</summary>
		<author><name>Tuffig</name></author>	</entry>

	</feed>