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

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_PWM&amp;diff=12819</id>
		<title>Bascom und PWM</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Bascom_und_PWM&amp;diff=12819"/>
				<updated>2007-10-20T00:26:25Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Grundprogramm */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== PWM-Signale mit Bascom erzeugen ==&lt;br /&gt;
&lt;br /&gt;
===Grundbegriffe===&lt;br /&gt;
Bei der ''Puls-Weiten-Modulation'' ([[PWM]]) wird ein digitales Ausgangssignal erzeugt, dessen Tastverhältnis moduliert wird.&lt;br /&gt;
&lt;br /&gt;
Das Tastverhältnis gibt das Verhältnis der Länge des eingeschalteten Zustands zur Periodendauer an. Dabei bleiben die Frequenz und der Pegel des Signals immer&lt;br /&gt;
gleich! &lt;br /&gt;
Es ändert sich nur die Länge von High zu Low.&lt;br /&gt;
&lt;br /&gt;
Folgendes Bild zeigt ein Tastverhältnis einmal von 10% und einmal von 50%&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tastverhältnis.png|center]]&lt;br /&gt;
&lt;br /&gt;
Man könnte das in etwa mit einem Wasserhahn vergleichen, den man z.B. alle Minuten betätigt.&lt;br /&gt;
Wenn man ihn in jeder Minute nur kurz aufdreht und dann gleich wieder zumacht, &lt;br /&gt;
kommt in Summe nur wenig Wasser raus. &lt;br /&gt;
Wenn man ihn aber in jeder dieser Minuten länger offen lässt,  &lt;br /&gt;
kommt mehr Wasser raus.&lt;br /&gt;
&lt;br /&gt;
Der Rhythmus bleibt immer gleich, aber es ändert sich in Summe die Wassermenge,&lt;br /&gt;
die raus kommt.&lt;br /&gt;
&lt;br /&gt;
Mit dem [[PWM]]-Signal kann man nun tolle Sachen machen. &amp;lt;br /&amp;gt;&lt;br /&gt;
Zum Beispiel:&lt;br /&gt;
* eine [[LED]] (oder über einen [[Transistor]] auch eine Lampe) an den [[PWM]]-Ausgang anschliessen und mit der Länge des [[PWM]]-Signal’s die Helligkeit der [[LED]] verändern.&lt;br /&gt;
* einen Motor in der Geschwindigkeit regeln. &lt;br /&gt;
* mittels nachgeschaltetem RC-Filter, welcher das [[PWM]]-Signal glättet, kann eine Gleichspannung erzeugt werden die zwischen 0V und 5V geregelt werden kann.&lt;br /&gt;
&lt;br /&gt;
=== PWM-Arten ===&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Arten PWM-Signale in Bascom zu erzeugen:&lt;br /&gt;
&lt;br /&gt;
==== Software PWM ====&lt;br /&gt;
:'''Vorteile''': &lt;br /&gt;
::* es kann (fast) jeder Ausgabe-Pin des AVR benutzt werden.&lt;br /&gt;
::* unter zuhilfename eines (freien) [[Timer]]s k&amp;amp;ouml;nnen sogar mehrere verschiedene PWM-Signale auf verschiedene Pins erzeugt werden.&lt;br /&gt;
:'''Nachteil''': &lt;br /&gt;
::* Etwas gr&amp;amp;ouml;sserer Programmaufwand, da der PortPin per Software verändert werden muss.&lt;br /&gt;
&lt;br /&gt;
==== Hardware PWM ====&lt;br /&gt;
:'''Vorteile''':&lt;br /&gt;
::* Sehr schnell (Maximal die Quarzfrequenz / Periode)&lt;br /&gt;
::* unabhängig vom Programmablauf des AVR&lt;br /&gt;
:'''Nachteile''':&lt;br /&gt;
::* Je nach AVR k&amp;amp;ouml;nnen nur bestimmte Timer mit bestimmten Ausgangspins daf&amp;amp;uuml;r verwendet werden.&lt;br /&gt;
::* belegt den Timer, der für keine weiteren funktionen verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Beim einem [[ATMega8]] stehen drei Hardware-PWM-Ausg&amp;amp;auml;nge verteilt auf zwei Timer zur Verf&amp;amp;uuml;gung.&lt;br /&gt;
&lt;br /&gt;
Mit Timer1 können zwei PWM Signale erzeugt werden &lt;br /&gt;
(Compare A =&amp;gt; OC1A - Pin 15 und Compare B =&amp;gt; OC1B - Pin 16).&lt;br /&gt;
&lt;br /&gt;
Die Auflösung kann auf 8, 9 und 10 Bit eingestellt werden, also max. 1024 Abstufungen.&lt;br /&gt;
&lt;br /&gt;
Timer2 kann ein PWM-Signal mit einer Auflösung von 8 Bit erzeugen&lt;br /&gt;
&lt;br /&gt;
(Compare Register =&amp;gt; OC2 - Pin 17)&lt;br /&gt;
&lt;br /&gt;
=== PWM-Ablauf ===&lt;br /&gt;
&lt;br /&gt;
Das folgende Bild zeigt den Ablauf bei Timer1. Als Taktquelle dient die CPU-Frequenz, dessen Frequenz im Prescaler (Vorteiler) nochmal verkleinert werden kann.&lt;br /&gt;
Je nach eingestelltem Wert in den ''Output Compare Registern'' wird der Status des Ausgangs-Pin entsprechend oft umgeschaltet, &lt;br /&gt;
und erzeugt somit das PWM-Signal.&lt;br /&gt;
&lt;br /&gt;
[[Bild:PWM.png|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Genauere Erklärung ===&lt;br /&gt;
&lt;br /&gt;
Der Prescaler teilt die Frequenz die vom Quarz kommt!&lt;br /&gt;
Bei Teilung 1 geht die vollständige Frequenz zum Timer.&lt;br /&gt;
Bei Teilung 8 nur ein Achtel der Quarzfrequenz.&lt;br /&gt;
(Also bei 8 MHz Quarz kommen zum Timer dann nur 1 MHz )&lt;br /&gt;
Bei Teilung 1024  sind es dann z.B. 8 MHz/1024 = 7,8125kHz &lt;br /&gt;
&lt;br /&gt;
Der Timer ist hier der Zähler für die PWM.&lt;br /&gt;
Er zählt mit der Frequenz, die vom Prescaler kommt, einmal von 0 bis&lt;br /&gt;
zu der eingestellten Timerauflösung rauf, dann wieder auf  0 zurück.&lt;br /&gt;
(dann wieder von 0 auf Timerauflösung u.s.w.)&lt;br /&gt;
Einmal rauf- und runterzählen, ergibt ein Periode.&lt;br /&gt;
Die Periode ist gleich die Ausgangsfrequenz des PWM-Signals.&lt;br /&gt;
Ausgangsfrequenz = (Quarzfrequenz/Prescale ) /(Timerauflösung*2)&lt;br /&gt;
&lt;br /&gt;
z.B.: Quarz = 8 MHz ;  Prescaler = 1 ; Timer = 8 Bit&lt;br /&gt;
ergibt:  (8000000Hz/1) / (256*2)  = 15,625 kHz&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oder: Quarz = 8 MHz ;  Prescaler = 8 ; Timer = 10 Bit&lt;br /&gt;
ergibt:  (8000000Hz/8) / (1024*2)  = 244,14 Hz&lt;br /&gt;
&lt;br /&gt;
Mit dem Compare Register definiert man nun das Tastverhältnis!&lt;br /&gt;
Überall, wo nun der Timer diese Compare Linie schneidet, schaltet der Ausgang!&lt;br /&gt;
Beim raufzählen des Timers auf EIN, beim runterzählen auf AUS.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Als Beispiel ein Tastverhältnis von 20%&lt;br /&gt;
[[Bild:Compare205.png|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Als Beispiel ein Tastverhältnis von 80%&lt;br /&gt;
[[Bild:Compare51.png|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hier sieht man, wie die Signale auf einem Oszilloskop  ausschauen.&lt;br /&gt;
Oben das Signal von Pin15 (Compare A), unten das von Pin 16 (Compare B)&lt;br /&gt;
[[Bild:Osci-PWM-kleiner3.GIF|center]]&lt;br /&gt;
&lt;br /&gt;
=== Grundprogramm ===&lt;br /&gt;
&lt;br /&gt;
Hier nun ein Grundprogramm für die Ausgabe von zwei PWM Signalen mit dem Timer1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
' Hardware PWM mit Timer1&lt;br /&gt;
&lt;br /&gt;
$regfile = &amp;quot;m8def.dat&amp;quot;&lt;br /&gt;
$crystal = 4000000&lt;br /&gt;
&lt;br /&gt;
Config Portb.1 = Output&lt;br /&gt;
Config Portb.2 = Output&lt;br /&gt;
&lt;br /&gt;
Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Up , Prescale = 1&lt;br /&gt;
&lt;br /&gt;
Do&lt;br /&gt;
 Compare1a = 205&lt;br /&gt;
 Compare1b = 51&lt;br /&gt;
Loop&lt;br /&gt;
&lt;br /&gt;
End&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Erklärung:'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$regfile = &amp;quot;m8def.dat&amp;quot;&lt;br /&gt;
$crystal = 8000000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Definiert den Mega8 und den 8MHz Quarz&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Config Portb.1 = Output&lt;br /&gt;
Config Portb.2 = Output&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Definiert die zwei Ausgänge von Timer1 auf Ausgabe.&amp;lt;br/&amp;gt;&lt;br /&gt;
Portb.1 = für Compare1a (= Compare A) = Pin 15&amp;lt;br/&amp;gt;&lt;br /&gt;
Portb.2 = für Compare1b (= Compare B) = Pin 16&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Up , Prescale = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
;Config Timer1 = Pwm&lt;br /&gt;
: Timer1 auf  PWM  einstellen&lt;br /&gt;
&lt;br /&gt;
;Pwm = 8 &lt;br /&gt;
:Timer Auflösung = 8 Bit einstellen&lt;br /&gt;
&lt;br /&gt;
;Compare A Pwm = Clear Up:Definiert, wie der Compare A schalten soll. Bei „Clear Up“ schaltet der Ausgang beim erreichen  &lt;br /&gt;
:des Compare-Wertes zuerst auf  High und dann auf Low. Bei „Clear Down“, umgekehrt. &lt;br /&gt;
&lt;br /&gt;
;Compare B Pwm = Clear Up&lt;br /&gt;
:Das gleiche noch mal mit Compare B                                          &lt;br /&gt;
&lt;br /&gt;
;Prescale = 1&lt;br /&gt;
:Hier wird der Prescaler auf 1 eingestellt.&lt;br /&gt;
:(Wert 1 heißt, direkte Frequenz vom Quarz zum Timer.)&lt;br /&gt;
:Weitere Teilungen, wie z.B.: 8, 64, 256 und 1024 sind möglich.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Compare1a = 205&lt;br /&gt;
Compare1b = 51&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
Hier kann man nun die Werte für das Tastverhältnis, in dem Register Compare1a&lt;br /&gt;
und Compare1b übergeben. Oder man kann, statt Compare1a und 1b, auch die Bezeichnungen &lt;br /&gt;
Pwm1a und Pwm1b verwenden, Bascom nimmt beides.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mit diesem kurzen Programm, hat man nun zwei [[PWM]] Signale erzeugt, bei dem eines ein Tastverhältnis&lt;br /&gt;
von 20% (Compare1a) und das andere 80 % hat. :-)&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;
* [[Pwm]]&lt;br /&gt;
* [[Timer]]&lt;br /&gt;
* [[Bascom und Timer]]&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>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_PWM&amp;diff=12818</id>
		<title>Bascom und PWM</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Bascom_und_PWM&amp;diff=12818"/>
				<updated>2007-10-20T00:23:49Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Grundprogramm */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== PWM-Signale mit Bascom erzeugen ==&lt;br /&gt;
&lt;br /&gt;
===Grundbegriffe===&lt;br /&gt;
Bei der ''Puls-Weiten-Modulation'' ([[PWM]]) wird ein digitales Ausgangssignal erzeugt, dessen Tastverhältnis moduliert wird.&lt;br /&gt;
&lt;br /&gt;
Das Tastverhältnis gibt das Verhältnis der Länge des eingeschalteten Zustands zur Periodendauer an. Dabei bleiben die Frequenz und der Pegel des Signals immer&lt;br /&gt;
gleich! &lt;br /&gt;
Es ändert sich nur die Länge von High zu Low.&lt;br /&gt;
&lt;br /&gt;
Folgendes Bild zeigt ein Tastverhältnis einmal von 10% und einmal von 50%&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tastverhältnis.png|center]]&lt;br /&gt;
&lt;br /&gt;
Man könnte das in etwa mit einem Wasserhahn vergleichen, den man z.B. alle Minuten betätigt.&lt;br /&gt;
Wenn man ihn in jeder Minute nur kurz aufdreht und dann gleich wieder zumacht, &lt;br /&gt;
kommt in Summe nur wenig Wasser raus. &lt;br /&gt;
Wenn man ihn aber in jeder dieser Minuten länger offen lässt,  &lt;br /&gt;
kommt mehr Wasser raus.&lt;br /&gt;
&lt;br /&gt;
Der Rhythmus bleibt immer gleich, aber es ändert sich in Summe die Wassermenge,&lt;br /&gt;
die raus kommt.&lt;br /&gt;
&lt;br /&gt;
Mit dem [[PWM]]-Signal kann man nun tolle Sachen machen. &amp;lt;br /&amp;gt;&lt;br /&gt;
Zum Beispiel:&lt;br /&gt;
* eine [[LED]] (oder über einen [[Transistor]] auch eine Lampe) an den [[PWM]]-Ausgang anschliessen und mit der Länge des [[PWM]]-Signal’s die Helligkeit der [[LED]] verändern.&lt;br /&gt;
* einen Motor in der Geschwindigkeit regeln. &lt;br /&gt;
* mittels nachgeschaltetem RC-Filter, welcher das [[PWM]]-Signal glättet, kann eine Gleichspannung erzeugt werden die zwischen 0V und 5V geregelt werden kann.&lt;br /&gt;
&lt;br /&gt;
=== PWM-Arten ===&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Arten PWM-Signale in Bascom zu erzeugen:&lt;br /&gt;
&lt;br /&gt;
==== Software PWM ====&lt;br /&gt;
:'''Vorteile''': &lt;br /&gt;
::* es kann (fast) jeder Ausgabe-Pin des AVR benutzt werden.&lt;br /&gt;
::* unter zuhilfename eines (freien) [[Timer]]s k&amp;amp;ouml;nnen sogar mehrere verschiedene PWM-Signale auf verschiedene Pins erzeugt werden.&lt;br /&gt;
:'''Nachteil''': &lt;br /&gt;
::* Etwas gr&amp;amp;ouml;sserer Programmaufwand, da der PortPin per Software verändert werden muss.&lt;br /&gt;
&lt;br /&gt;
==== Hardware PWM ====&lt;br /&gt;
:'''Vorteile''':&lt;br /&gt;
::* Sehr schnell (Maximal die Quarzfrequenz / Periode)&lt;br /&gt;
::* unabhängig vom Programmablauf des AVR&lt;br /&gt;
:'''Nachteile''':&lt;br /&gt;
::* Je nach AVR k&amp;amp;ouml;nnen nur bestimmte Timer mit bestimmten Ausgangspins daf&amp;amp;uuml;r verwendet werden.&lt;br /&gt;
::* belegt den Timer, der für keine weiteren funktionen verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Beim einem [[ATMega8]] stehen drei Hardware-PWM-Ausg&amp;amp;auml;nge verteilt auf zwei Timer zur Verf&amp;amp;uuml;gung.&lt;br /&gt;
&lt;br /&gt;
Mit Timer1 können zwei PWM Signale erzeugt werden &lt;br /&gt;
(Compare A =&amp;gt; OC1A - Pin 15 und Compare B =&amp;gt; OC1B - Pin 16).&lt;br /&gt;
&lt;br /&gt;
Die Auflösung kann auf 8, 9 und 10 Bit eingestellt werden, also max. 1024 Abstufungen.&lt;br /&gt;
&lt;br /&gt;
Timer2 kann ein PWM-Signal mit einer Auflösung von 8 Bit erzeugen&lt;br /&gt;
&lt;br /&gt;
(Compare Register =&amp;gt; OC2 - Pin 17)&lt;br /&gt;
&lt;br /&gt;
=== PWM-Ablauf ===&lt;br /&gt;
&lt;br /&gt;
Das folgende Bild zeigt den Ablauf bei Timer1. Als Taktquelle dient die CPU-Frequenz, dessen Frequenz im Prescaler (Vorteiler) nochmal verkleinert werden kann.&lt;br /&gt;
Je nach eingestelltem Wert in den ''Output Compare Registern'' wird der Status des Ausgangs-Pin entsprechend oft umgeschaltet, &lt;br /&gt;
und erzeugt somit das PWM-Signal.&lt;br /&gt;
&lt;br /&gt;
[[Bild:PWM.png|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Genauere Erklärung ===&lt;br /&gt;
&lt;br /&gt;
Der Prescaler teilt die Frequenz die vom Quarz kommt!&lt;br /&gt;
Bei Teilung 1 geht die vollständige Frequenz zum Timer.&lt;br /&gt;
Bei Teilung 8 nur ein Achtel der Quarzfrequenz.&lt;br /&gt;
(Also bei 8 MHz Quarz kommen zum Timer dann nur 1 MHz )&lt;br /&gt;
Bei Teilung 1024  sind es dann z.B. 8 MHz/1024 = 7,8125kHz &lt;br /&gt;
&lt;br /&gt;
Der Timer ist hier der Zähler für die PWM.&lt;br /&gt;
Er zählt mit der Frequenz, die vom Prescaler kommt, einmal von 0 bis&lt;br /&gt;
zu der eingestellten Timerauflösung rauf, dann wieder auf  0 zurück.&lt;br /&gt;
(dann wieder von 0 auf Timerauflösung u.s.w.)&lt;br /&gt;
Einmal rauf- und runterzählen, ergibt ein Periode.&lt;br /&gt;
Die Periode ist gleich die Ausgangsfrequenz des PWM-Signals.&lt;br /&gt;
Ausgangsfrequenz = (Quarzfrequenz/Prescale ) /(Timerauflösung*2)&lt;br /&gt;
&lt;br /&gt;
z.B.: Quarz = 8 MHz ;  Prescaler = 1 ; Timer = 8 Bit&lt;br /&gt;
ergibt:  (8000000Hz/1) / (256*2)  = 15,625 kHz&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oder: Quarz = 8 MHz ;  Prescaler = 8 ; Timer = 10 Bit&lt;br /&gt;
ergibt:  (8000000Hz/8) / (1024*2)  = 244,14 Hz&lt;br /&gt;
&lt;br /&gt;
Mit dem Compare Register definiert man nun das Tastverhältnis!&lt;br /&gt;
Überall, wo nun der Timer diese Compare Linie schneidet, schaltet der Ausgang!&lt;br /&gt;
Beim raufzählen des Timers auf EIN, beim runterzählen auf AUS.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Als Beispiel ein Tastverhältnis von 20%&lt;br /&gt;
[[Bild:Compare205.png|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Als Beispiel ein Tastverhältnis von 80%&lt;br /&gt;
[[Bild:Compare51.png|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hier sieht man, wie die Signale auf einem Oszilloskop  ausschauen.&lt;br /&gt;
Oben das Signal von Pin15 (Compare A), unten das von Pin 16 (Compare B)&lt;br /&gt;
[[Bild:Osci-PWM-kleiner3.GIF|center]]&lt;br /&gt;
&lt;br /&gt;
=== Grundprogramm ===&lt;br /&gt;
&lt;br /&gt;
Hier nun ein Grundprogramm für die Ausgabe von zwei PWM Signalen mit dem Timer1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
' Hardware PWM mit Timer1&lt;br /&gt;
&lt;br /&gt;
$regfile = &amp;quot;m8def.dat&amp;quot;&lt;br /&gt;
$crystal = 4000000&lt;br /&gt;
&lt;br /&gt;
Config Portb.1 = Output&lt;br /&gt;
Config Portb.2 = Output&lt;br /&gt;
&lt;br /&gt;
Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Up , Prescale = 1&lt;br /&gt;
&lt;br /&gt;
Do&lt;br /&gt;
 Compare1a = 205&lt;br /&gt;
 Compare1b = 51&lt;br /&gt;
Loop&lt;br /&gt;
&lt;br /&gt;
End&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Erklärung:'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$regfile = &amp;quot;m8def.dat&amp;quot;&lt;br /&gt;
$crystal = 8000000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Definiert den Mega8 und den 8MHz Quarz&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Config Pinb.1 = Output&lt;br /&gt;
Config Pinb.2 = Output&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Definiert die zwei Ausgänge von Timer1 auf Ausgabe.&amp;lt;br/&amp;gt;&lt;br /&gt;
Pinb.1 = für Compare1a (= Compare A) = Pin 15&amp;lt;br/&amp;gt;&lt;br /&gt;
Pinb.2 = für Compare1b (= Compare B) = Pin 16&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Up , Prescale = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
;Config Timer1 = Pwm&lt;br /&gt;
: Timer1 auf  PWM  einstellen&lt;br /&gt;
&lt;br /&gt;
;Pwm = 8 &lt;br /&gt;
:Timer Auflösung = 8 Bit einstellen&lt;br /&gt;
&lt;br /&gt;
;Compare A Pwm = Clear Up:Definiert, wie der Compare A schalten soll. Bei „Clear Up“ schaltet der Ausgang beim erreichen  &lt;br /&gt;
:des Compare-Wertes zuerst auf  High und dann auf Low. Bei „Clear Down“, umgekehrt. &lt;br /&gt;
&lt;br /&gt;
;Compare B Pwm = Clear Up&lt;br /&gt;
:Das gleiche noch mal mit Compare B                                          &lt;br /&gt;
&lt;br /&gt;
;Prescale = 1&lt;br /&gt;
:Hier wird der Prescaler auf 1 eingestellt.&lt;br /&gt;
:(Wert 1 heißt, direkte Frequenz vom Quarz zum Timer.)&lt;br /&gt;
:Weitere Teilungen, wie z.B.: 8, 64, 256 und 1024 sind möglich.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Compare1a = 205&lt;br /&gt;
Compare1b = 51&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
Hier kann man nun die Werte für das Tastverhältnis, in dem Register Compare1a&lt;br /&gt;
und Compare1b übergeben. Oder man kann, statt Compare1a und 1b, auch die Bezeichnungen &lt;br /&gt;
Pwm1a und Pwm1b verwenden, Bascom nimmt beides.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mit diesem kurzen Programm, hat man nun zwei [[PWM]] Signale erzeugt, bei dem eines ein Tastverhältnis&lt;br /&gt;
von 20% (Compare1a) und das andere 80 % hat. :-)&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;
* [[Pwm]]&lt;br /&gt;
* [[Timer]]&lt;br /&gt;
* [[Bascom und Timer]]&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>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_I2C_EEprom&amp;diff=9442</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=9442"/>
				<updated>2006-10-29T17:53:30Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* 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 schreiben&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;
&lt;br /&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öhnlich 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 Adressberreich in High und Low Adressbereich trennen.&lt;br /&gt;
(Zuerst High-Adressberreich 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 Berreich von zwei Byte und braucht daher den Berreich 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>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Diskussion:Codevergleich_AVR-Compiler&amp;diff=8540</id>
		<title>Diskussion:Codevergleich AVR-Compiler</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Diskussion:Codevergleich_AVR-Compiler&amp;diff=8540"/>
				<updated>2006-08-21T19:14:26Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hallo Sprinter (schreibe mal hier)&lt;br /&gt;
&lt;br /&gt;
In Formeln bin ich sehr schlecht, aber was hälst DU davon, wenn man dazu fixe Werte für die Variablen verwendet, einen Einheitlichen Prozessor (z.B. den Mega8) und einen Gleichbeleibenden Quarz.&lt;br /&gt;
Dann könnte man die Codes auch untereinander in der Ausführungszeit und dem Speicherverbrauch vergleichen..?&lt;br /&gt;
Mann müsste dann aber auch den kompletten Code aufzeigen...&lt;br /&gt;
(für C alle Libs..)--[[Benutzer:Roberto|Roberto]] 22:31, 6. Apr 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Die C-Codes habe ich für einen ATmega8 übersetzt. Die Einstellungen für den CPU-Takt haben keinen Einfluss auf die Codeerzeugung (oder etwa bei Bascom??). Den Flash-Verbrauch kann man abzählen oder anzeigen lassen, Zeit- und RAM-Verbrauch sind statisch bestimmbar &amp;amp;ndash; letzeres ist allerdings etwas Arbeit.&lt;br /&gt;
&lt;br /&gt;
Die Beispiele habe ich als einfache Funktionen gewählt. Einerseits, weil man da schon viel der Eigenheiten eines Compilers erkennen kann. Der erzeugte Code ist wie ein Fingerabdruck und exemplarisch für größere Beispiele. Zudem finde ich, das große Beispiele nicht viel mehr aussagen, und durch meterlange Listings steigt niemand durch und langweilen eher. &lt;br /&gt;
&lt;br /&gt;
Zudem habe ich Beispiele gewählt, die keine Bibliotheken brauchen. Mehr als der Code, der da steht, wird nicht ausgeführt und ist irrelevant, also auch, wie es &amp;quot;ausserhalb&amp;quot; der Funktionen aussieht. Der einzige externe Bezug ist die Funktion &amp;lt;tt&amp;gt;foo()&amp;lt;/tt&amp;gt; bei den Interrupt-Routinen. Welcher Code sich dahinter verbirgt ist egal. Es ist einfach ''irgendeine'' parameterlose Funktion ohne Rückgabewert, die ''irgendwas'' macht und dann zurückkehrt. Genauso ist die Code, aus denen die Beispiele aufgerufen werden, für die Übersetzung unerheblich. Es sind ja keine statischen oder inline-Funktionen.&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:SprinterSB|SprinterSB]] 23:20, 6. Apr 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== sum_n_loop==&lt;br /&gt;
&lt;br /&gt;
Ich hab mal einen Code in Bascom reingestellt.&lt;br /&gt;
Ich glaube nicht dass Dir das Endergebnis so zusagt.&lt;br /&gt;
Ist das Ergebnis 45 bei 10 Durchläufen korrekt??&lt;br /&gt;
Falls doch, gib mir per PM bescheid, dann mach ich ggf. mehr.&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Darwin.nuernberg|Darwin.nuernberg]] 21:43, 23. Apr 2006 (CEST)--[[Benutzer:Darwin.nuernberg|Darwin.nuernberg]] 21:43, 23. Apr 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Am hex-File sieht man leider nicht viel, weil da vermutlich das genze Programm drinne ist und noch StartUp-Code und so.&lt;br /&gt;
&lt;br /&gt;
Ich hab mir mal in BASCOM geschaut, aber auf Anhieb hab ich nix gesehen, wie man an den Assembler-Code kommt.&lt;br /&gt;
&lt;br /&gt;
Hier mal ein Disassemble deines iHex:&lt;br /&gt;
&amp;lt;pre&amp;gt;Disassembly of section .sec1:&lt;br /&gt;
&lt;br /&gt;
00000000 &amp;lt;.sec1&amp;gt;:&lt;br /&gt;
   0:	12 c0       	rjmp	.+36     	; 0x26&lt;br /&gt;
   2:	18 95       	reti&lt;br /&gt;
   4:	18 95       	reti&lt;br /&gt;
   6:	18 95       	reti&lt;br /&gt;
   8:	18 95       	reti&lt;br /&gt;
   a:	18 95       	reti&lt;br /&gt;
   c:	18 95       	reti&lt;br /&gt;
   e:	18 95       	reti&lt;br /&gt;
  10:	18 95       	reti&lt;br /&gt;
  12:	18 95       	reti&lt;br /&gt;
  14:	18 95       	reti&lt;br /&gt;
  16:	18 95       	reti&lt;br /&gt;
  18:	18 95       	reti&lt;br /&gt;
  1a:	18 95       	reti&lt;br /&gt;
  1c:	18 95       	reti&lt;br /&gt;
  1e:	18 95       	reti&lt;br /&gt;
  20:	18 95       	reti&lt;br /&gt;
  22:	18 95       	reti&lt;br /&gt;
  24:	18 95       	reti&lt;br /&gt;
  26:	8f e5       	ldi	r24, 0x5F	; 95&lt;br /&gt;
  28:	8d bf       	out	0x3d, r24	; 61&lt;br /&gt;
  2a:	c0 e4       	ldi	r28, 0x40	; 64&lt;br /&gt;
  2c:	e8 e3       	ldi	r30, 0x38	; 56&lt;br /&gt;
  2e:	4e 2e       	mov	r4, r30&lt;br /&gt;
  30:	84 e0       	ldi	r24, 0x04	; 4&lt;br /&gt;
  32:	8e bf       	out	0x3e, r24	; 62&lt;br /&gt;
  34:	d4 e0       	ldi	r29, 0x04	; 4&lt;br /&gt;
  36:	f4 e0       	ldi	r31, 0x04	; 4&lt;br /&gt;
  38:	5f 2e       	mov	r5, r31&lt;br /&gt;
  3a:	ee ef       	ldi	r30, 0xFE	; 254&lt;br /&gt;
  3c:	f3 e0       	ldi	r31, 0x03	; 3&lt;br /&gt;
  3e:	a0 e6       	ldi	r26, 0x60	; 96&lt;br /&gt;
  40:	b0 e0       	ldi	r27, 0x00	; 0&lt;br /&gt;
  42:	88 27       	eor	r24, r24&lt;br /&gt;
  44:	8d 93       	st	X+, r24&lt;br /&gt;
  46:	31 97       	sbiw	r30, 0x01	; 1&lt;br /&gt;
  48:	e9 f7       	brne	.-6      	; 0x44&lt;br /&gt;
  4a:	66 24       	eor	r6, r6&lt;br /&gt;
  4c:	e0 e6       	ldi	r30, 0x60	; 96&lt;br /&gt;
  4e:	f0 e0       	ldi	r31, 0x00	; 0&lt;br /&gt;
  50:	fa 93       	st	-Y, r31&lt;br /&gt;
  52:	ea 93       	st	-Y, r30&lt;br /&gt;
  54:	5a 92       	st	-Y, r5&lt;br /&gt;
  56:	4a 92       	st	-Y, r4&lt;br /&gt;
  58:	8a e0       	ldi	r24, 0x0A	; 10&lt;br /&gt;
  5a:	90 e0       	ldi	r25, 0x00	; 0&lt;br /&gt;
  5c:	a4 2d       	mov	r26, r4&lt;br /&gt;
  5e:	b5 2d       	mov	r27, r5&lt;br /&gt;
  60:	8d 93       	st	X+, r24&lt;br /&gt;
  62:	9c 93       	st	X, r25&lt;br /&gt;
  64:	82 e0       	ldi	r24, 0x02	; 2&lt;br /&gt;
  66:	35 d0       	rcall	.+106    	; 0xd2&lt;br /&gt;
  68:	05 d0       	rcall	.+10     	; 0x74&lt;br /&gt;
  6a:	24 96       	adiw	r28, 0x04	; 4&lt;br /&gt;
  6c:	82 e0       	ldi	r24, 0x02	; 2&lt;br /&gt;
  6e:	2d d0       	rcall	.+90     	; 0xca&lt;br /&gt;
  70:	f8 94       	cli&lt;br /&gt;
  72:	ff cf       	rjmp	.-2      	; 0x72&lt;br /&gt;
  74:	a8 81       	ld	r26, Y&lt;br /&gt;
  76:	b9 81       	ldd	r27, Y+1	; 0x01&lt;br /&gt;
  78:	8d 91       	ld	r24, X+&lt;br /&gt;
  7a:	9c 91       	ld	r25, X&lt;br /&gt;
  7c:	a2 e6       	ldi	r26, 0x62	; 98&lt;br /&gt;
  7e:	b0 e0       	ldi	r27, 0x00	; 0&lt;br /&gt;
  80:	8d 93       	st	X+, r24&lt;br /&gt;
  82:	9c 93       	st	X, r25&lt;br /&gt;
  84:	aa 81       	ldd	r26, Y+2	; 0x02&lt;br /&gt;
  86:	bb 81       	ldd	r27, Y+3	; 0x03&lt;br /&gt;
  88:	37 d0       	rcall	.+110    	; 0xf8&lt;br /&gt;
  8a:	a2 e6       	ldi	r26, 0x62	; 98&lt;br /&gt;
  8c:	b0 e0       	ldi	r27, 0x00	; 0&lt;br /&gt;
  8e:	0d 91       	ld	r16, X+&lt;br /&gt;
  90:	1c 91       	ld	r17, X&lt;br /&gt;
  92:	00 30       	cpi	r16, 0x00	; 0&lt;br /&gt;
  94:	50 e0       	ldi	r21, 0x00	; 0&lt;br /&gt;
  96:	15 07       	cpc	r17, r21&lt;br /&gt;
  98:	14 f0       	brlt	.+4      	; 0x9e&lt;br /&gt;
  9a:	09 f0       	breq	.+2      	; 0x9e&lt;br /&gt;
  9c:	01 c0       	rjmp	.+2      	; 0xa0&lt;br /&gt;
  9e:	12 c0       	rjmp	.+36     	; 0xc4&lt;br /&gt;
  a0:	a2 e6       	ldi	r26, 0x62	; 98&lt;br /&gt;
  a2:	b0 e0       	ldi	r27, 0x00	; 0&lt;br /&gt;
  a4:	1a d0       	rcall	.+52     	; 0xda&lt;br /&gt;
  a6:	aa 81       	ldd	r26, Y+2	; 0x02&lt;br /&gt;
  a8:	bb 81       	ldd	r27, Y+3	; 0x03&lt;br /&gt;
  aa:	0d 91       	ld	r16, X+&lt;br /&gt;
  ac:	1c 91       	ld	r17, X&lt;br /&gt;
  ae:	a2 e6       	ldi	r26, 0x62	; 98&lt;br /&gt;
  b0:	b0 e0       	ldi	r27, 0x00	; 0&lt;br /&gt;
  b2:	4d 91       	ld	r20, X+&lt;br /&gt;
  b4:	5c 91       	ld	r21, X&lt;br /&gt;
  b6:	04 0f       	add	r16, r20&lt;br /&gt;
  b8:	15 1f       	adc	r17, r21&lt;br /&gt;
  ba:	aa 81       	ldd	r26, Y+2	; 0x02&lt;br /&gt;
  bc:	bb 81       	ldd	r27, Y+3	; 0x03&lt;br /&gt;
  be:	0d 93       	st	X+, r16&lt;br /&gt;
  c0:	1c 93       	st	X, r17&lt;br /&gt;
  c2:	e3 cf       	rjmp	.-58     	; 0x8a&lt;br /&gt;
  c4:	08 95       	ret&lt;br /&gt;
  c6:	f8 94       	cli&lt;br /&gt;
  c8:	ff cf       	rjmp	.-2      	; 0xc8&lt;br /&gt;
  ca:	48 1a       	sub	r4, r24&lt;br /&gt;
  cc:	88 27       	eor	r24, r24&lt;br /&gt;
  ce:	58 0a       	sbc	r5, r24&lt;br /&gt;
  d0:	08 95       	ret&lt;br /&gt;
  d2:	48 0e       	add	r4, r24&lt;br /&gt;
  d4:	88 27       	eor	r24, r24&lt;br /&gt;
  d6:	58 1e       	adc	r5, r24&lt;br /&gt;
  d8:	08 95       	ret&lt;br /&gt;
  da:	ed 91       	ld	r30, X+&lt;br /&gt;
  dc:	fc 91       	ld	r31, X&lt;br /&gt;
  de:	31 97       	sbiw	r30, 0x01	; 1&lt;br /&gt;
  e0:	fc 93       	st	X, r31&lt;br /&gt;
  e2:	ee 93       	st	-X, r30&lt;br /&gt;
  e4:	08 95       	ret&lt;br /&gt;
  e6:	31 97       	sbiw	r30, 0x01	; 1&lt;br /&gt;
  e8:	f1 f7       	brne	.-4      	; 0xe6&lt;br /&gt;
  ea:	08 95       	ret&lt;br /&gt;
  ec:	68 94       	set&lt;br /&gt;
  ee:	62 f8       	bld	r6, 2&lt;br /&gt;
  f0:	08 95       	ret&lt;br /&gt;
  f2:	e8 94       	clt&lt;br /&gt;
  f4:	62 f8       	bld	r6, 2&lt;br /&gt;
  f6:	08 95       	ret&lt;br /&gt;
  f8:	82 e0       	ldi	r24, 0x02	; 2&lt;br /&gt;
  fa:	01 c0       	rjmp	.+2      	; 0xfe&lt;br /&gt;
  fc:	84 e0       	ldi	r24, 0x04	; 4&lt;br /&gt;
  fe:	99 27       	eor	r25, r25&lt;br /&gt;
 100:	9d 93       	st	X+, r25&lt;br /&gt;
 102:	8a 95       	dec	r24&lt;br /&gt;
 104:	e9 f7       	brne	.-6      	; 0x100&lt;br /&gt;
 106:	08 95       	ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
ihex ist leider ein absolutes low-Level-Format, ohne jegliche Symbolinformation...&lt;br /&gt;
&lt;br /&gt;
Es ist ein ganzes ausführbares Prog, enthält also ausser der Funktion noch zusätzlichen Code und mehr als nur die Funktion:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x0000 -- 0x0024: VecTab &lt;br /&gt;
0x0026 -- 0x????: Startup-Code&lt;br /&gt;
0x???? -- 0x????: Hauptprogramm&lt;br /&gt;
0x0058(?) -- 0x006a :X = Sum_n_loop(10) &lt;br /&gt;
0x006c - 0x0072: End&lt;br /&gt;
0x0074--0x00c4: Sum_n_loop&lt;br /&gt;
0x00ca: Helper&lt;br /&gt;
0x00da: Helper&lt;br /&gt;
0x00d2: Helper&lt;br /&gt;
0x00f8: Helper&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Die Helper sind kleine Funktionen, die auf dem Stack und BASCOM-internen GPRs operieren. Zumindest was ich auf die schnelle sehe. Ich kenne BASCOM wie gesagt nicht.&lt;br /&gt;
&lt;br /&gt;
1+2+3+4+5+6+7+8+9+10 = 55&lt;br /&gt;
&lt;br /&gt;
Deine 45 kommt daher, daß das Decr zu früh gemacht wird. Es berechnet also nut die Summe 1...N-1.&lt;br /&gt;
&lt;br /&gt;
Jemand mit besserer Kenntnis von BASCOM könnte den Spaghetti-Code besser auseinanderklabüstern als ich. &lt;br /&gt;
&lt;br /&gt;
Die Helper gehören eigentlich nicht zum Code der Funktion, auch wenn sie teilweise von dort aufgerufen werden. Bei mehreren Funktionen werden die anderen Funks die SChnippsel auch benutzen, so daß der Code nicht der Summation zuzuschlagen ist (find ich jedenfalls).&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:SprinterSB|SprinterSB]] 23:07, 23. Apr 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Problem bei BASCOM ist, dass es nicht compiliert, wenn der Code nicht ausführbar ist.&lt;br /&gt;
Ein Objectfile oder sowas wird nicht generiert, ist ja kein C oder Pascal oder sowas.&lt;br /&gt;
Also ein Vergleich ist wenn überhaupt am endgültigen Resultat, sprich HEX-File möglich.&lt;br /&gt;
Aber das hattest Du vermutlich nicht vor. Das mit der Korrektur des Schleifendurchlauf es&lt;br /&gt;
wäre kein akt, aber wenn Du das Endresultat nicht zum Vergleich heranziehen willst, macht es keinen Sinn da noch weitere Energie hinein zu stecken. EIgentlich wäre anstelle &amp;quot;While I &amp;gt; 0&amp;quot; nuer ein &amp;quot;While I &amp;gt;= 0&amp;quot; nötig um die Funktion korrekt zum Ende zu bringen.&lt;br /&gt;
&lt;br /&gt;
PS: wo ist das denn ein Spagetti-Code? Ist doch schön strukturiert. Nur weil Du die Befehle nicht kennst muss es doch kein Spagetticode sein. Und so schlimm ist es wohl auch nicht. Umgekehrt könnte ich zu C Spagetti sagen, weil mir das nicht zusagt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Darwin.nuernberg|Darwin.nuernberg]] 00:28, 24. Apr 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
Mich interessiert der Vergleich eigentlich nicht, aber wenn er denn was nützen soll dann sollte der Code auch vergleichbar sein. Mit Codeauszügen ist das schwierig weil es mühseelig ist den speziellen Code der für die Subroutine zuständig ist herauszupicken, zudem greift Bascom auch in Assember sehr schnell auf Subroutinen im Code zurück, so das dies ohnehin schwierig ist. Es wäre viel einfacher und auch aussagekräftiger wenn das komplette Programm auf beidne Seiten als Assembler aufgelistet würde, so wie es Darwin jetzt oben in Bascom gemacht hat. &lt;br /&gt;
Ansonsten würden Benchmarks für bestimmte Aufgaben (Rechenzeit/Codegröße) für viele sicher interessanter sein. &lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Frank|Frank]] 01:12, 24. Apr 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Das &amp;quot;Spaghetti-Code&amp;quot; bezog sich auf das Disassemble der hex-Datei, nicht auf die BASIC-Quelle.&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;While I &amp;gt;= 0&amp;quot; ist immer noch nicht korrekt. Der erste Wert, der addiert wird, ist dann immer noch N-1 und nicht N. Ausserden würde mit &amp;gt;=0 am Ende eine -1 addiert werden, weil das Decr vor der Summe steht.&lt;br /&gt;
&lt;br /&gt;
Ein Codevergleich ist ja so was wie ein Benchmark. Und einfache Routinen, die in den Sprachen gleich aussehen (die Summenberechnung sieht in C ja genauso aus wie in BASIC), sind ja im Artikel als Vorschlag drinne. Irgendw muss man ja anfangen. Laufzeitbestimmungen könnte man natürlich auch machen... &lt;br /&gt;
&lt;br /&gt;
Den Assembler-Code von Darwin sehe ich momentan nicht. Das einzige was ich hab, ist ein HEX-Dump (Maschinen-Code) und ein Assembler-Code aus dem hex. Der Code der Routine kann man schon in etwa zuordnen. Und die kleinen Funktiönchen, die Bascom aufruft, sind wahrscheinlich feste Bausteine, die auch von anderen Funktionen (falls vorhanden) mitverwendet würden.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Das sehe ich nicht so. Ein &amp;quot;Bänschmarg&amp;quot; sollte eigentlich die reíne Rechenleistung wiedergeben. Codeoptimierung ist da was ganz anderes. Zumal ein längerer Code durchaus schneller als ein kompakter Code sein KANN. Manche Befehle benötigen mehr &amp;quot;Ticks&amp;quot; als andere. In Vielen Sprachen ist zwar x=x+1 langsamer und länger als inc x, dies muss aber nicht für alle Befehle gelten und ist ja auch noch kein Compilat, es wird aber auf unterschiedliche Weisen das gleiche Ergebniss erzielt (Das Ziel ist der Weg). Waurm wurde wohl der RISC entwickelt (Reduced InStruction Code). Da muss ma auch mehrere Befehle ausführen als mit einem &amp;quot;NonRISC&amp;quot; System, trozdem sollte das &amp;quot;RISC-System&amp;quot; schneller arbeiten.&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Darwin.nuernberg|Darwin.nuernberg]] 23:43, 26. Apr 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
=Fazit?=&lt;br /&gt;
Hallo&lt;br /&gt;
&lt;br /&gt;
Gibt es jetzt darüber eigentlich schon ein Fazit ?&lt;br /&gt;
Um wieviel ist C jetzt schneller als Bascom ?&lt;br /&gt;
--[[Benutzer:Roberto|Roberto]] 07:42, 10. Aug 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Zunächst mal zur Deiner Frage. Sie wird in dieser Form oder als &amp;quot;Ist C schneller als BASIC?&amp;quot; öfter gestellt. Diese Frage kann nicht beantwortet werden. Bei &amp;quot;C&amp;quot; und &amp;quot;BASIC&amp;quot; handelt es sich um zwei Programmiersprachen. Grundsätzlich ist es für jeden Compiler vorstellbar, daß er den optimalen Assembler-Code zu einer gegeben Quelle findet (wobei man natürlich noch angeben muss, was unter &amp;quot;optimal&amp;quot; zu verstehen ist).&lt;br /&gt;
&lt;br /&gt;
Hier geht es jedoch nicht um den Vergleich zweier Programmiersprachen, welche man anhand von Attributen/Kriterien wie objektorientiert, aspektorientiert, imperativ, modular, funktional, Befolgung von Standards, Verbreitung, Plattformunabhängigkeit, Möglichkeiten zur Fehlererkennung/-vermeidung, Verifizierbarkeit, Sicherheit/Robustheit etc. vergleichen würde.&lt;br /&gt;
&lt;br /&gt;
In dem Artikel geht es um einen Vergleich von Compilern, mit welchen Quellcode nach Maschinen- bzw. Assemblercode für AVR übersetzt werden kann, und zwar nur im Hinblick auf den generierten Code.&lt;br /&gt;
&lt;br /&gt;
Verglichen werden (Stand 08/2006) avr-gcc und BASCOM, wobei auf BASCOM-Seite nur eine einzige Quelle ausgearbeitet wurde, was dadurch erschwert wird, daß BASCOM keinen Assembler-Code erzeugt sondern direkt nach Maschinensprache übersetzt und keine Quellbezüge einfügt.&lt;br /&gt;
&lt;br /&gt;
Bereits anhand dieses einen Beispiels kann man auf die Arbeitsweise der beiden Compiler zurückschliessen. &lt;br /&gt;
&lt;br /&gt;
Die Codegröße von 70 Bytes (ohne die Lib-Funktion für den Dekrement) bei BASCOM im Vergleich zu 20 Bytes bei avr-gcc liegt zum großen Teil darin begründet, daß BASCOM Werte nicht in Registern hält, sondern immer wieder aus dem SRAM lesen und schreiben muss. Die dafür notwendigen Befehle ergeben sowohl einen breiteren Code als auch eine längere Laufzeit. Einem Compiler dieses Register-Rechnen beizubringen ist jedoch alles andere als einfach und m.E. kurz- oder mittelfristig in BASCOM nicht zu erwarten.&lt;br /&gt;
&lt;br /&gt;
Dies hat z.B. zur Folge, daß auch ein Dekrement (eine häufige arithmetische Operation in vielen Anwendungen) auf dem SRAM geschieht. Die lokale Variable &amp;lt;tt&amp;gt;N&amp;lt;/tt&amp;gt; lebt im Frame der Funktion  (hier als Softstack realisiert), und der Dekrement wird umgesetzt in eine Lib-Funktion und einen Aufruf mit vorheriger Adressberechnung von &amp;lt;tt&amp;gt;N&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
  LDD	XL,Y + 0&lt;br /&gt;
  LDD	XH,Y + 1&lt;br /&gt;
  CALL	L_Decrement&lt;br /&gt;
...&lt;br /&gt;
L_Decrement:&lt;br /&gt;
  LD	ZL,X+&lt;br /&gt;
  LD	ZH,X&lt;br /&gt;
  SBIW	ZL,0x0001&lt;br /&gt;
  ST	X,ZH&lt;br /&gt;
  ST	-X,ZL&lt;br /&gt;
  RET&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Das dauert ca. 20 Takte, im Gegensatz zu den 2 Takten des avr-gcc-Dekrements (&amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; lebt im Registerpaar r25:r24)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  sbiw	r24, 0x01&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Erstaunlich finde ich, daß der Vergleich gegen 0. Der abzuprüfende Wert wurde schon nach r17:r16 geladen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CPI	r16,0x00   ; LOW  &amp;lt;&amp;gt; 0 ?&lt;br /&gt;
  LDI	r21,0x00   &lt;br /&gt;
  CPC	r17,r21    ; HIGH &amp;lt;&amp;gt; 0 ? &lt;br /&gt;
  BRLT	L_0x00D6   ; branch lower  -&amp;gt;function exit&lt;br /&gt;
  BREQ	L_0x00D6   ; branch equal  -&amp;gt;function exit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Diese häufig benötigte Sequenz könnte mit wenig Aufwand geschickter gestaltet werden (evtl. mit anderem Sprungbefehl), so wie in avr-gcc geschehen (es wird r25:r24 getestet):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sbiw	r24, 0x00&lt;br /&gt;
breq	.+8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit Optimierungen ist BASCOM sehr zurückhaltend; in dem Beispiel sind sie nicht erkennbar. avr-gcc kann auf einen ganzen Pool von Optimierungen zurückgreifen, die gcc schon mitbringt.&lt;br /&gt;
&lt;br /&gt;
Für spezielle und häufig nachgefragte Routinen wie &amp;quot;Zeichen übern UART senden&amp;quot; bringt BASCOM Lib-Funktionen mit. Diese Lib-Funktionen sind in Assembler programmiert und dürften dementsprechender effizienter sein als BASCOM-compiliertes BASIC. Zwar kommt die Effizienz dieser Libs nicht vom BASCOM-Compiler, für einen Anwender, der diese Funktionen benutzt, ist dieser Unterschied jedoch rein akademischer Natur und irrelevant. Solange man nicht selber programmieren muss und viele Funktionen schreibt, bleibt man dann im Rahmen der Lib-Effizienz. &lt;br /&gt;
&lt;br /&gt;
Momentan ist BASCOM noch in einem Stadium, in dem Compiler-Optimierungen sowohl einen schnelleren auch einen dichteren Code bringen. Ausgefeilte Optimierungsstrategien wie in gcc werden nicht ergriffen. Für einfache Programme wie im AVR-Umfeld üblich dürften Codegröße und Laufzeit mindestens um den Faktor 2 schlechter sein als bei avr-gcc, teilweise auch deutlich darüber. Beschränkt man sich vorwiegend auf BASCOM-Libs, dürfte sich dieses Verhältnis etwas entspannen.&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:SprinterSB|SprinterSB]] 15:48, 21. Aug 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
Danke für die ausführliche Beschreibung :-) --[[Benutzer:Roberto|Roberto]] 21:14, 21. Aug 2006 (CEST)&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Diskussion:Codevergleich_AVR-Compiler&amp;diff=8516</id>
		<title>Diskussion:Codevergleich AVR-Compiler</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Diskussion:Codevergleich_AVR-Compiler&amp;diff=8516"/>
				<updated>2006-08-10T05:42:44Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hallo Sprinter (schreibe mal hier)&lt;br /&gt;
&lt;br /&gt;
In Formeln bin ich sehr schlecht, aber was hälst DU davon, wenn man dazu fixe Werte für die Variablen verwendet, einen Einheitlichen Prozessor (z.B. den Mega8) und einen Gleichbeleibenden Quarz.&lt;br /&gt;
Dann könnte man die Codes auch untereinander in der Ausführungszeit und dem Speicherverbrauch vergleichen..?&lt;br /&gt;
Mann müsste dann aber auch den kompletten Code aufzeigen...&lt;br /&gt;
(für C alle Libs..)--[[Benutzer:Roberto|Roberto]] 22:31, 6. Apr 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Die C-Codes habe ich für einen ATmega8 übersetzt. Die Einstellungen für den CPU-Takt haben keinen Einfluss auf die Codeerzeugung (oder etwa bei Bascom??). Den Flash-Verbrauch kann man abzählen oder anzeigen lassen, Zeit- und RAM-Verbrauch sind statisch bestimmbar &amp;amp;ndash; letzeres ist allerdings etwas Arbeit.&lt;br /&gt;
&lt;br /&gt;
Die Beispiele habe ich als einfache Funktionen gewählt. Einerseits, weil man da schon viel der Eigenheiten eines Compilers erkennen kann. Der erzeugte Code ist wie ein Fingerabdruck und exemplarisch für größere Beispiele. Zudem finde ich, das große Beispiele nicht viel mehr aussagen, und durch meterlange Listings steigt niemand durch und langweilen eher. &lt;br /&gt;
&lt;br /&gt;
Zudem habe ich Beispiele gewählt, die keine Bibliotheken brauchen. Mehr als der Code, der da steht, wird nicht ausgeführt und ist irrelevant, also auch, wie es &amp;quot;ausserhalb&amp;quot; der Funktionen aussieht. Der einzige externe Bezug ist die Funktion &amp;lt;tt&amp;gt;foo()&amp;lt;/tt&amp;gt; bei den Interrupt-Routinen. Welcher Code sich dahinter verbirgt ist egal. Es ist einfach ''irgendeine'' parameterlose Funktion ohne Rückgabewert, die ''irgendwas'' macht und dann zurückkehrt. Genauso ist die Code, aus denen die Beispiele aufgerufen werden, für die Übersetzung unerheblich. Es sind ja keine statischen oder inline-Funktionen.&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:SprinterSB|SprinterSB]] 23:20, 6. Apr 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== sum_n_loop==&lt;br /&gt;
&lt;br /&gt;
Ich hab mal einen Code in Bascom reingestellt.&lt;br /&gt;
Ich glaube nicht dass Dir das Endergebnis so zusagt.&lt;br /&gt;
Ist das Ergebnis 45 bei 10 Durchläufen korrekt??&lt;br /&gt;
Falls doch, gib mir per PM bescheid, dann mach ich ggf. mehr.&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Darwin.nuernberg|Darwin.nuernberg]] 21:43, 23. Apr 2006 (CEST)--[[Benutzer:Darwin.nuernberg|Darwin.nuernberg]] 21:43, 23. Apr 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Am hex-File sieht man leider nicht viel, weil da vermutlich das genze Programm drinne ist und noch StartUp-Code und so.&lt;br /&gt;
&lt;br /&gt;
Ich hab mir mal in BASCOM geschaut, aber auf Anhieb hab ich nix gesehen, wie man an den Assembler-Code kommt.&lt;br /&gt;
&lt;br /&gt;
Hier mal ein Disassemble deines iHex:&lt;br /&gt;
&amp;lt;pre&amp;gt;Disassembly of section .sec1:&lt;br /&gt;
&lt;br /&gt;
00000000 &amp;lt;.sec1&amp;gt;:&lt;br /&gt;
   0:	12 c0       	rjmp	.+36     	; 0x26&lt;br /&gt;
   2:	18 95       	reti&lt;br /&gt;
   4:	18 95       	reti&lt;br /&gt;
   6:	18 95       	reti&lt;br /&gt;
   8:	18 95       	reti&lt;br /&gt;
   a:	18 95       	reti&lt;br /&gt;
   c:	18 95       	reti&lt;br /&gt;
   e:	18 95       	reti&lt;br /&gt;
  10:	18 95       	reti&lt;br /&gt;
  12:	18 95       	reti&lt;br /&gt;
  14:	18 95       	reti&lt;br /&gt;
  16:	18 95       	reti&lt;br /&gt;
  18:	18 95       	reti&lt;br /&gt;
  1a:	18 95       	reti&lt;br /&gt;
  1c:	18 95       	reti&lt;br /&gt;
  1e:	18 95       	reti&lt;br /&gt;
  20:	18 95       	reti&lt;br /&gt;
  22:	18 95       	reti&lt;br /&gt;
  24:	18 95       	reti&lt;br /&gt;
  26:	8f e5       	ldi	r24, 0x5F	; 95&lt;br /&gt;
  28:	8d bf       	out	0x3d, r24	; 61&lt;br /&gt;
  2a:	c0 e4       	ldi	r28, 0x40	; 64&lt;br /&gt;
  2c:	e8 e3       	ldi	r30, 0x38	; 56&lt;br /&gt;
  2e:	4e 2e       	mov	r4, r30&lt;br /&gt;
  30:	84 e0       	ldi	r24, 0x04	; 4&lt;br /&gt;
  32:	8e bf       	out	0x3e, r24	; 62&lt;br /&gt;
  34:	d4 e0       	ldi	r29, 0x04	; 4&lt;br /&gt;
  36:	f4 e0       	ldi	r31, 0x04	; 4&lt;br /&gt;
  38:	5f 2e       	mov	r5, r31&lt;br /&gt;
  3a:	ee ef       	ldi	r30, 0xFE	; 254&lt;br /&gt;
  3c:	f3 e0       	ldi	r31, 0x03	; 3&lt;br /&gt;
  3e:	a0 e6       	ldi	r26, 0x60	; 96&lt;br /&gt;
  40:	b0 e0       	ldi	r27, 0x00	; 0&lt;br /&gt;
  42:	88 27       	eor	r24, r24&lt;br /&gt;
  44:	8d 93       	st	X+, r24&lt;br /&gt;
  46:	31 97       	sbiw	r30, 0x01	; 1&lt;br /&gt;
  48:	e9 f7       	brne	.-6      	; 0x44&lt;br /&gt;
  4a:	66 24       	eor	r6, r6&lt;br /&gt;
  4c:	e0 e6       	ldi	r30, 0x60	; 96&lt;br /&gt;
  4e:	f0 e0       	ldi	r31, 0x00	; 0&lt;br /&gt;
  50:	fa 93       	st	-Y, r31&lt;br /&gt;
  52:	ea 93       	st	-Y, r30&lt;br /&gt;
  54:	5a 92       	st	-Y, r5&lt;br /&gt;
  56:	4a 92       	st	-Y, r4&lt;br /&gt;
  58:	8a e0       	ldi	r24, 0x0A	; 10&lt;br /&gt;
  5a:	90 e0       	ldi	r25, 0x00	; 0&lt;br /&gt;
  5c:	a4 2d       	mov	r26, r4&lt;br /&gt;
  5e:	b5 2d       	mov	r27, r5&lt;br /&gt;
  60:	8d 93       	st	X+, r24&lt;br /&gt;
  62:	9c 93       	st	X, r25&lt;br /&gt;
  64:	82 e0       	ldi	r24, 0x02	; 2&lt;br /&gt;
  66:	35 d0       	rcall	.+106    	; 0xd2&lt;br /&gt;
  68:	05 d0       	rcall	.+10     	; 0x74&lt;br /&gt;
  6a:	24 96       	adiw	r28, 0x04	; 4&lt;br /&gt;
  6c:	82 e0       	ldi	r24, 0x02	; 2&lt;br /&gt;
  6e:	2d d0       	rcall	.+90     	; 0xca&lt;br /&gt;
  70:	f8 94       	cli&lt;br /&gt;
  72:	ff cf       	rjmp	.-2      	; 0x72&lt;br /&gt;
  74:	a8 81       	ld	r26, Y&lt;br /&gt;
  76:	b9 81       	ldd	r27, Y+1	; 0x01&lt;br /&gt;
  78:	8d 91       	ld	r24, X+&lt;br /&gt;
  7a:	9c 91       	ld	r25, X&lt;br /&gt;
  7c:	a2 e6       	ldi	r26, 0x62	; 98&lt;br /&gt;
  7e:	b0 e0       	ldi	r27, 0x00	; 0&lt;br /&gt;
  80:	8d 93       	st	X+, r24&lt;br /&gt;
  82:	9c 93       	st	X, r25&lt;br /&gt;
  84:	aa 81       	ldd	r26, Y+2	; 0x02&lt;br /&gt;
  86:	bb 81       	ldd	r27, Y+3	; 0x03&lt;br /&gt;
  88:	37 d0       	rcall	.+110    	; 0xf8&lt;br /&gt;
  8a:	a2 e6       	ldi	r26, 0x62	; 98&lt;br /&gt;
  8c:	b0 e0       	ldi	r27, 0x00	; 0&lt;br /&gt;
  8e:	0d 91       	ld	r16, X+&lt;br /&gt;
  90:	1c 91       	ld	r17, X&lt;br /&gt;
  92:	00 30       	cpi	r16, 0x00	; 0&lt;br /&gt;
  94:	50 e0       	ldi	r21, 0x00	; 0&lt;br /&gt;
  96:	15 07       	cpc	r17, r21&lt;br /&gt;
  98:	14 f0       	brlt	.+4      	; 0x9e&lt;br /&gt;
  9a:	09 f0       	breq	.+2      	; 0x9e&lt;br /&gt;
  9c:	01 c0       	rjmp	.+2      	; 0xa0&lt;br /&gt;
  9e:	12 c0       	rjmp	.+36     	; 0xc4&lt;br /&gt;
  a0:	a2 e6       	ldi	r26, 0x62	; 98&lt;br /&gt;
  a2:	b0 e0       	ldi	r27, 0x00	; 0&lt;br /&gt;
  a4:	1a d0       	rcall	.+52     	; 0xda&lt;br /&gt;
  a6:	aa 81       	ldd	r26, Y+2	; 0x02&lt;br /&gt;
  a8:	bb 81       	ldd	r27, Y+3	; 0x03&lt;br /&gt;
  aa:	0d 91       	ld	r16, X+&lt;br /&gt;
  ac:	1c 91       	ld	r17, X&lt;br /&gt;
  ae:	a2 e6       	ldi	r26, 0x62	; 98&lt;br /&gt;
  b0:	b0 e0       	ldi	r27, 0x00	; 0&lt;br /&gt;
  b2:	4d 91       	ld	r20, X+&lt;br /&gt;
  b4:	5c 91       	ld	r21, X&lt;br /&gt;
  b6:	04 0f       	add	r16, r20&lt;br /&gt;
  b8:	15 1f       	adc	r17, r21&lt;br /&gt;
  ba:	aa 81       	ldd	r26, Y+2	; 0x02&lt;br /&gt;
  bc:	bb 81       	ldd	r27, Y+3	; 0x03&lt;br /&gt;
  be:	0d 93       	st	X+, r16&lt;br /&gt;
  c0:	1c 93       	st	X, r17&lt;br /&gt;
  c2:	e3 cf       	rjmp	.-58     	; 0x8a&lt;br /&gt;
  c4:	08 95       	ret&lt;br /&gt;
  c6:	f8 94       	cli&lt;br /&gt;
  c8:	ff cf       	rjmp	.-2      	; 0xc8&lt;br /&gt;
  ca:	48 1a       	sub	r4, r24&lt;br /&gt;
  cc:	88 27       	eor	r24, r24&lt;br /&gt;
  ce:	58 0a       	sbc	r5, r24&lt;br /&gt;
  d0:	08 95       	ret&lt;br /&gt;
  d2:	48 0e       	add	r4, r24&lt;br /&gt;
  d4:	88 27       	eor	r24, r24&lt;br /&gt;
  d6:	58 1e       	adc	r5, r24&lt;br /&gt;
  d8:	08 95       	ret&lt;br /&gt;
  da:	ed 91       	ld	r30, X+&lt;br /&gt;
  dc:	fc 91       	ld	r31, X&lt;br /&gt;
  de:	31 97       	sbiw	r30, 0x01	; 1&lt;br /&gt;
  e0:	fc 93       	st	X, r31&lt;br /&gt;
  e2:	ee 93       	st	-X, r30&lt;br /&gt;
  e4:	08 95       	ret&lt;br /&gt;
  e6:	31 97       	sbiw	r30, 0x01	; 1&lt;br /&gt;
  e8:	f1 f7       	brne	.-4      	; 0xe6&lt;br /&gt;
  ea:	08 95       	ret&lt;br /&gt;
  ec:	68 94       	set&lt;br /&gt;
  ee:	62 f8       	bld	r6, 2&lt;br /&gt;
  f0:	08 95       	ret&lt;br /&gt;
  f2:	e8 94       	clt&lt;br /&gt;
  f4:	62 f8       	bld	r6, 2&lt;br /&gt;
  f6:	08 95       	ret&lt;br /&gt;
  f8:	82 e0       	ldi	r24, 0x02	; 2&lt;br /&gt;
  fa:	01 c0       	rjmp	.+2      	; 0xfe&lt;br /&gt;
  fc:	84 e0       	ldi	r24, 0x04	; 4&lt;br /&gt;
  fe:	99 27       	eor	r25, r25&lt;br /&gt;
 100:	9d 93       	st	X+, r25&lt;br /&gt;
 102:	8a 95       	dec	r24&lt;br /&gt;
 104:	e9 f7       	brne	.-6      	; 0x100&lt;br /&gt;
 106:	08 95       	ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
ihex ist leider ein absolutes low-Level-Format, ohne jegliche Symbolinformation...&lt;br /&gt;
&lt;br /&gt;
Es ist ein ganzes ausführbares Prog, enthält also ausser der Funktion noch zusätzlichen Code und mehr als nur die Funktion:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x0000 -- 0x0024: VecTab &lt;br /&gt;
0x0026 -- 0x????: Startup-Code&lt;br /&gt;
0x???? -- 0x????: Hauptprogramm&lt;br /&gt;
0x0058(?) -- 0x006a :X = Sum_n_loop(10) &lt;br /&gt;
0x006c - 0x0072: End&lt;br /&gt;
0x0074--0x00c4: Sum_n_loop&lt;br /&gt;
0x00ca: Helper&lt;br /&gt;
0x00da: Helper&lt;br /&gt;
0x00d2: Helper&lt;br /&gt;
0x00f8: Helper&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Die Helper sind kleine Funktionen, die auf dem Stack und BASCOM-internen GPRs operieren. Zumindest was ich auf die schnelle sehe. Ich kenne BASCOM wie gesagt nicht.&lt;br /&gt;
&lt;br /&gt;
1+2+3+4+5+6+7+8+9+10 = 55&lt;br /&gt;
&lt;br /&gt;
Deine 45 kommt daher, daß das Decr zu früh gemacht wird. Es berechnet also nut die Summe 1...N-1.&lt;br /&gt;
&lt;br /&gt;
Jemand mit besserer Kenntnis von BASCOM könnte den Spaghetti-Code besser auseinanderklabüstern als ich. &lt;br /&gt;
&lt;br /&gt;
Die Helper gehören eigentlich nicht zum Code der Funktion, auch wenn sie teilweise von dort aufgerufen werden. Bei mehreren Funktionen werden die anderen Funks die SChnippsel auch benutzen, so daß der Code nicht der Summation zuzuschlagen ist (find ich jedenfalls).&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:SprinterSB|SprinterSB]] 23:07, 23. Apr 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Problem bei BASCOM ist, dass es nicht compiliert, wenn der Code nicht ausführbar ist.&lt;br /&gt;
Ein Objectfile oder sowas wird nicht generiert, ist ja kein C oder Pascal oder sowas.&lt;br /&gt;
Also ein Vergleich ist wenn überhaupt am endgültigen Resultat, sprich HEX-File möglich.&lt;br /&gt;
Aber das hattest Du vermutlich nicht vor. Das mit der Korrektur des Schleifendurchlauf es&lt;br /&gt;
wäre kein akt, aber wenn Du das Endresultat nicht zum Vergleich heranziehen willst, macht es keinen Sinn da noch weitere Energie hinein zu stecken. EIgentlich wäre anstelle &amp;quot;While I &amp;gt; 0&amp;quot; nuer ein &amp;quot;While I &amp;gt;= 0&amp;quot; nötig um die Funktion korrekt zum Ende zu bringen.&lt;br /&gt;
&lt;br /&gt;
PS: wo ist das denn ein Spagetti-Code? Ist doch schön strukturiert. Nur weil Du die Befehle nicht kennst muss es doch kein Spagetticode sein. Und so schlimm ist es wohl auch nicht. Umgekehrt könnte ich zu C Spagetti sagen, weil mir das nicht zusagt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Darwin.nuernberg|Darwin.nuernberg]] 00:28, 24. Apr 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
Mich interessiert der Vergleich eigentlich nicht, aber wenn er denn was nützen soll dann sollte der Code auch vergleichbar sein. Mit Codeauszügen ist das schwierig weil es mühseelig ist den speziellen Code der für die Subroutine zuständig ist herauszupicken, zudem greift Bascom auch in Assember sehr schnell auf Subroutinen im Code zurück, so das dies ohnehin schwierig ist. Es wäre viel einfacher und auch aussagekräftiger wenn das komplette Programm auf beidne Seiten als Assembler aufgelistet würde, so wie es Darwin jetzt oben in Bascom gemacht hat. &lt;br /&gt;
Ansonsten würden Benchmarks für bestimmte Aufgaben (Rechenzeit/Codegröße) für viele sicher interessanter sein. &lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Frank|Frank]] 01:12, 24. Apr 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Das &amp;quot;Spaghetti-Code&amp;quot; bezog sich auf das Disassemble der hex-Datei, nicht auf die BASIC-Quelle.&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;While I &amp;gt;= 0&amp;quot; ist immer noch nicht korrekt. Der erste Wert, der addiert wird, ist dann immer noch N-1 und nicht N. Ausserden würde mit &amp;gt;=0 am Ende eine -1 addiert werden, weil das Decr vor der Summe steht.&lt;br /&gt;
&lt;br /&gt;
Ein Codevergleich ist ja so was wie ein Benchmark. Und einfache Routinen, die in den Sprachen gleich aussehen (die Summenberechnung sieht in C ja genauso aus wie in BASIC), sind ja im Artikel als Vorschlag drinne. Irgendw muss man ja anfangen. Laufzeitbestimmungen könnte man natürlich auch machen... &lt;br /&gt;
&lt;br /&gt;
Den Assembler-Code von Darwin sehe ich momentan nicht. Das einzige was ich hab, ist ein HEX-Dump (Maschinen-Code) und ein Assembler-Code aus dem hex. Der Code der Routine kann man schon in etwa zuordnen. Und die kleinen Funktiönchen, die Bascom aufruft, sind wahrscheinlich feste Bausteine, die auch von anderen Funktionen (falls vorhanden) mitverwendet würden.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Das sehe ich nicht so. Ein &amp;quot;Bänschmarg&amp;quot; sollte eigentlich die reíne Rechenleistung wiedergeben. Codeoptimierung ist da was ganz anderes. Zumal ein längerer Code durchaus schneller als ein kompakter Code sein KANN. Manche Befehle benötigen mehr &amp;quot;Ticks&amp;quot; als andere. In Vielen Sprachen ist zwar x=x+1 langsamer und länger als inc x, dies muss aber nicht für alle Befehle gelten und ist ja auch noch kein Compilat, es wird aber auf unterschiedliche Weisen das gleiche Ergebniss erzielt (Das Ziel ist der Weg). Waurm wurde wohl der RISC entwickelt (Reduced InStruction Code). Da muss ma auch mehrere Befehle ausführen als mit einem &amp;quot;NonRISC&amp;quot; System, trozdem sollte das &amp;quot;RISC-System&amp;quot; schneller arbeiten.&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Darwin.nuernberg|Darwin.nuernberg]] 23:43, 26. Apr 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
Hallo&lt;br /&gt;
&lt;br /&gt;
Gibt es jetzt darüber eigentlich schon ein Fazit ?&lt;br /&gt;
Um wieviel ist C jetzt schneller als Bascom ?&lt;br /&gt;
--[[Benutzer:Roberto|Roberto]] 07:42, 10. Aug 2006 (CEST)&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=8131</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=8131"/>
				<updated>2006-07-05T12:05:20Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Strukturen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ein kurzer Einblick in die Programmiersprache C&lt;br /&gt;
=Allgemeines=&lt;br /&gt;
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 Sprachedefinition entwickelt. C ist mittlerweile von ANSI und ISO standardisiert.&lt;br /&gt;
Heutzutage ist C (und ihr Nachfolger C++) die dominierende Programmiersprache. Sehr viele Anwendungen sind in C geschrieben. Leider ist C jedoch nicht einfach zu lernen, daher eignet es sich nur bedingt für Anfänger. Mit etwas Übung kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
C ist sehr eng an Assembler angelehnt, aber trotzdem Hardware-unabhängig. Das bedeutet, Sie können maschinennahe Programme sehr leicht (aber nicht ganz ohne Aufwand) auf ein anderes System portieren. Sie benötigen dazu 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;
&amp;lt;pre&amp;gt;&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;
   /* Anweisungen */&lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Beschreibung (die Erklärungen folgen): &lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndahs; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* &lt;br /&gt;
 * void Definition von main ist nur beim Controller üblich&lt;br /&gt;
 * spezielle Compilereinstellungen sind nötig, damit bei dieser Definition von main&lt;br /&gt;
 * kein Fehler/Warnung erzeugt wird. &lt;br /&gt;
 */&lt;br /&gt;
void main (void)&lt;br /&gt;
{&lt;br /&gt;
   ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{    /* der Block &amp;quot;main&amp;quot; beginnt */&lt;br /&gt;
   int zahl;&lt;br /&gt;
   &lt;br /&gt;
   {   /* ein Block beginnt */&lt;br /&gt;
       /* hier können Deklarationen und Anweisungen stehen */&lt;br /&gt;
   }   /* der Block endet */&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}    /* &amp;quot;main&amp;quot; endet */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Bemerkung:''' &lt;br /&gt;
Der &amp;quot;namenlose&amp;quot; Block ist eigentlich unnötig. In den folgenden Kapiteln lernen Sie jedoch bessere Beispiele kennen!&lt;br /&gt;
&lt;br /&gt;
=Datentypen=&lt;br /&gt;
==Elementare Datentypen==&lt;br /&gt;
Der Datentyp einer Variable gibt an, welche Werte eine Variable enthalten kann, welcher Art diese Daten sind und wie sie verarbeitet werden, etwa in arithmetischen Operationen wie einer Addition. So ist es zum Beispiel möglich, in eine Variable vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ganze Zahlen zwischen ca. -32000 und +32000 einzutragen. In einer char-Variable können ASCII-Zeichen gespeichert werden (alles, was Sie mit der Tastatur erzeugen können) oder ganze Zahlen von -128 bis 127.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da C plattformabhängig ist, hängt die Größe eines Datentypes zum Teil von der genutzten Hardware (z.B. 8, 16 oder 32 Bit-Controller) und dem Compiler und dessen Einstellungen ab!&lt;br /&gt;
&lt;br /&gt;
===int, char, short, long (ganze Zahlen)===&lt;br /&gt;
In Variable dieser Typen können Sie ganze Zahlen abspeichern, also z.B. 1, &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;2, 100, 12345. Jeden dieser Typen gibt es in zwei Ausprägungen: als &amp;quot;&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;quot;, also als vorzeichenbehafteten Typ, und als &amp;quot;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&amp;quot;, also ohne Vorzeichen, d.h. das Vorzeichen wird als 0 oder +1 genommen. &lt;br /&gt;
&lt;br /&gt;
Vorzeichenbehaftete Ganzzahl-Typen werden intern im &amp;lt;tt&amp;gt;n-1&amp;lt;/tt&amp;gt;-Komplement dargestellt, das Vorzeichen selbst findet sich also im höchstwertigen Bit. Werden zur Speicherung ''b'' Bits verwendet, dann reicht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;*zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==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:''' Datentyp Variablenname[Anzahl]&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 3 Variablen. Da der Index immer bei 0 beginnt, greift man also mit [0], [1] und [2] 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;
&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 i;&lt;br /&gt;
  int zahlen[10];  /* zahlen[0] bis zahlen[9] !!! */&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;10; 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;
  printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  for (i=0; i&amp;lt;10; 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;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Bemerkungen:''' &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;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
Wenn Sie einen ungültigen Index angeben (einen, der in der Deklaration nicht enthalten war) können je nach Compiler und Einstellung undefinierbare Dinge passieren, da dadurch andere Variableninhalte oder Programmcode überschrieben wird. Im schlimmsten Fall könnte sogar der Computer/Controller abstürzen. Also achten Sie darauf, daß Sie keine ungültigen Werte als Index angeben!&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;
&amp;lt;pre&amp;gt;&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;
&amp;lt;/pre&amp;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 angelegt: 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 dieses Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach &lt;br /&gt;
 struct Person Variablenname;&lt;br /&gt;
an. &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;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  struct Person hubert, klaus;&lt;br /&gt;
&lt;br /&gt;
  hubert.alter = 32;&lt;br /&gt;
  klaus.alter = hubert.alter + 1;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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 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 Person u_person;&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_double&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Groß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.&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 chat 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.&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;
/* nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform) */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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;
Teilweise erlauben C-Compiler auch die Verwendung des Dollar-Zeichens &amp;lt;tt&amp;gt;'''$'''&amp;lt;/tt&amp;gt; in Variablennaben.&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;
&amp;lt;pre&amp;gt;&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;
  /* Anweisungen */&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
;Erklärung: 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;wahr&amp;quot;, ansonsten ist sie &amp;quot;unwahr&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;
==Vergleich von Variablen==&lt;br /&gt;
Sie können Variablen miteinander vergleichen. Das geschieht mit einem der folgenden Zeichen mit den normalen mathematischen Regeln: &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;
Als Ergebnis bekommen Sie einen logischen Ausdruck in Form einer int-Zahl. &lt;br /&gt;
 intVariable = zahl1 &amp;lt;= zahl2;&lt;br /&gt;
das komplette Beispiel zeigt es deutlicher:&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;= z1  /* Ein Vergleich. Die int-Variable i wird wahr, da z1 kleiner als z2 */&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Ergebnis: %d\n&amp;quot;, i);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich 0 (&amp;quot;wahr&amp;quot;), wenn z1 kleiner oder gleich z2 ist. Ist z1 jedoch größer als z2, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich 0 (&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 dafür ein Schlüsselwort in C:&lt;br /&gt;
 const ''datentyp'' name = value;  /* 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;  /* 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;. 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 Eigenheit 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, wenn das Ergebnis bereits feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
  (x &amp;gt; 5) || datei_auf_festplatte_gefunden(&amp;quot;hallo.txt&amp;quot;) /* gut */&lt;br /&gt;
  datei_auf_festplatte_gefunden(&amp;quot;hallo.txt&amp;quot;) || (x &amp;gt; 5) /* nicht so gut */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;datei_auf_festplatte_gefunden&amp;lt;/tt&amp;gt; ist fiktiv und steht für eine Funktion,&lt;br /&gt;
die eine aufwändige Operation durchführt.&lt;br /&gt;
Beide Zeilen ergeben &amp;lt;tt&amp;gt;wahr&amp;lt;/tt&amp;gt; wenn die Variable x einen Wert größer 5 hat oder&lt;br /&gt;
es eine Datei namens &amp;lt;tt&amp;gt;hallo.txt&amp;lt;/tt&amp;gt; auf der Festplatte gibt.&lt;br /&gt;
&lt;br /&gt;
Wo ist also der Unterschied?&amp;lt;br&amp;gt;&lt;br /&gt;
In der ersten Zeile wird geprüft, ob x größer als 5 ist und wenn das der Fall ist,&lt;br /&gt;
dann wird ''nicht mehr geprüft'', ob &amp;lt;tt&amp;gt;hallo.txt&amp;lt;/tt&amp;gt; auf der Festplatte existiert.&lt;br /&gt;
In der zweiten Zeile wird ''immer geprüft'', ob &amp;lt;tt&amp;gt;hallo.txt&amp;lt;/tt&amp;gt; auf der Festplatte&lt;br /&gt;
existiert und erst, wenn sie nicht gefunden wird, wird die Variable x ausgewertet.&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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  int x = 5;    /* x ist eine Integervariable und hat den Wert 5 */&lt;br /&gt;
&lt;br /&gt;
  /* z ist ein Zeiger auf eine Integervariable und enthält somit&lt;br /&gt;
     die Speicheradresse einer Integervariablen&lt;br /&gt;
  */&lt;br /&gt;
  int *z;       &lt;br /&gt;
&lt;br /&gt;
  /* Verwendung des Adressoperators... */&lt;br /&gt;
  z = &amp;amp;x;       /* weise z die Speicheradresse von x zu */&lt;br /&gt;
&lt;br /&gt;
  /* Verwendung der Dereferenzierung */&lt;br /&gt;
  /* erhöhe den Wert, der bei Adresse z steht um eins */&lt;br /&gt;
  *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
  /* da z auf x zeigt, hat auch x jetzt den Wert 6 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff&lt;br /&gt;
auf ein Element 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;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&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&lt;br /&gt;
auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu&lt;br /&gt;
einer Änderung '''irgendeiner''' Speicherstelle:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   int *z; /* z ist ein Zeiger auf einen Integer */&lt;br /&gt;
&lt;br /&gt;
   /* An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.&lt;br /&gt;
      z enthält irgendeine(!) Adresse&lt;br /&gt;
   */&lt;br /&gt;
&lt;br /&gt;
   /* &amp;quot;Erhöhe einen Integer irgendwo im Speicher um 1&amp;quot; -&amp;gt; CRASH */&lt;br /&gt;
   *z = *z + 1;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler (z.B. gcc) erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
}}&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'' durch, sondern unterdrückt nur die Compilerwarnungen oder&lt;br /&gt;
-fehler, die bei einer &amp;quot;verdächtigen&amp;quot; Umwandlung passieren. Er kann also nicht benutzt werden, um einen Text in&lt;br /&gt;
eine Zahl oder umgekehrt zu wandeln:&lt;br /&gt;
&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;
&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Speicheradresse, an der der Text &amp;quot;5.6&amp;quot; beginnt. Der Cast-Operator&lt;br /&gt;
unterdrückt nur die Warnung, die auf den Fehler hinweisen will.&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;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Bedingte Zuweisung===&lt;br /&gt;
 lvalue = (bediungung) ? if-ausdruck : else-ausdruck;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Kein ANSI-C&lt;br /&gt;
--[[Benutzer:SprinterSB|SprinterSB]] 17:15, 29. Jun 2006 (CEST)&lt;br /&gt;
==Blöcke==&lt;br /&gt;
Selbst Blöcke haben in C einen Wert, der in einer Berechnung verwendet werden kann.&lt;br /&gt;
Der Wert eines Blockes ist der Wert der letzten Anweisung des Blocks. &lt;br /&gt;
Der Block muss un runden Klammern stehen:&lt;br /&gt;
 int sum;&lt;br /&gt;
 sum = ({&lt;br /&gt;
    int i, s = 0;&lt;br /&gt;
    for (i=1; i&amp;lt;= 100; i++)&lt;br /&gt;
       s += i;&lt;br /&gt;
    s;&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Makro &amp;lt;tt&amp;gt;PSTR&amp;lt;/tt&amp;gt; von avr-gcc, &lt;br /&gt;
das einen String ins Flash legt und die Adresse zurückliefert, was nur in einer&lt;br /&gt;
Instruktion nicht machbar wäre:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define PSTR(s)                         \&lt;br /&gt;
  ({                                    \ &lt;br /&gt;
      static char __c[] PROGMEM = (s);  \&lt;br /&gt;
      __c;                              \&lt;br /&gt;
  })&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
==Boolsche Logik==&lt;br /&gt;
Boolean-Variablen können miteinander verknüpft werden. Dies geschieht mit den boolschen Operatoren &amp;amp;&amp;amp; ( logisches &amp;quot;und&amp;quot;), || (logisches &amp;quot;oder&amp;quot;) und ! (logisches &amp;quot;nicht&amp;quot;) (es gibt noch weitere, auf die hier nicht eingegangen wird). &lt;br /&gt;
&lt;br /&gt;
 b1= b2 &amp;amp;&amp;amp; b3;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der Wert von b1 ist dann 1 (TRUE), wenn b2 und (&amp;quot;AND&amp;quot;) b3 1 (TRUE) sind. Ist eine der beiden (oder auch beide) 0 (FALSE), dann ist b1 ebenfalls 0 (FALSE).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 b1= b2 || b3;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der Wert von b1 ist dann TRUE, wenn b2 oder (&amp;quot;OR&amp;quot;) b3 TRUE ist. Ist also einer (oder beide) TRUE, dann ist auch b1 TRUE, sind beide FALSE, ist auch b1 FALSE.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 b1= !b2;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der Wert von b1 ist dann TRUE, wenn der von b2 FALSE ist. Die NOT Verknüpfung &amp;quot;dreht den logischen Wert der Variablen um&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Anweisung==&lt;br /&gt;
Syntax: IF (Bedingung) Anweisung;&lt;br /&gt;
Mit Hilfe der IF Anweisung kann man Codeteile (Blöcke) ausführen lassen, wenn die dazugehörige Bedingung erfüllt (TRUE) ist. Im Flussdiagramm sieht eine If-Anweisung folgendermassen aus:&lt;br /&gt;
&lt;br /&gt;
[[bild:ifthenelse.png]]&lt;br /&gt;
&lt;br /&gt;
Und in C schreibt man:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if (Bedingung)        /* WENN */&lt;br /&gt;
{                     /* DANN */&lt;br /&gt;
       Anweisung1;&lt;br /&gt;
       Anweisung2;&lt;br /&gt;
       ...&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{                     /* SONST */&lt;br /&gt;
       Anweisung3;&lt;br /&gt;
       Anweisung4;&lt;br /&gt;
       ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wenn die Bedingung wahr ist wird Anweisung1 ausgeführt. Anschliessend wird aus der If-Bedingung herausgesprungen. Anweisung2 wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung unwahr wird gleich zu Anweisung2 gesprungen, diese ausgeführt, und anschliessend wird die If-Bedingung beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Ein häufiger Fehler ist statt if(a == 23) etwas wie if(a = 23) zu schreiben. Hier wird allerdings nicht geprüft ob die Variable a gleich 23 ist, sondern der Variable a wird der Wert 23 zugewiesen, und das ist eine wahre Aussage. Anschliessend wird demzufolge der &amp;quot;DANN&amp;quot;-Teil ausgeführt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken. Somit ist dieser kleine Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise if(23 == a). Wenn man dort anstatt des Vergleichsoperator '==' den Zuweisungsoperator '=' verwendet spuckt der Compiler sehr wohl einen Fehler aus.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist das schreiben von if(Bedingung)''';''' Richtig müsste es heissen &amp;quot;if(Bedingung)&amp;quot; Das fehlerhafte Semikolon im ersten Fall interpretiert der Compiler bereits als Anweisung. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt. Hier also ebenfalls besser zweimal hinschauen.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;-Anweisung==&lt;br /&gt;
Syntax: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
switch(ausdruck) {&lt;br /&gt;
    case wert1:&lt;br /&gt;
        Anweisungen1...&lt;br /&gt;
    case wert2:&lt;br /&gt;
        Anweisungen2...&lt;br /&gt;
    case wert3:&lt;br /&gt;
        Anweisungen3...&lt;br /&gt;
    ...&lt;br /&gt;
    default:&lt;br /&gt;
        Anweisungen4...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der &amp;lt;tt&amp;gt;ausdruck&amp;lt;/tt&amp;gt; muss eine Ganzzahl (int) ergeben und wird dann der Reihe nach mit den Werten, die hinter&lt;br /&gt;
den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Anweisungen angegeben sind verglichen. Bei einer Übereinstimmung werden alle Befehle ab der&lt;br /&gt;
zutreffenden Case-Anweisung ausgeführt. Stimmt der &amp;lt;tt&amp;gt;ausdruck&amp;lt;/tt&amp;gt; mit keinem der Werte hinter &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;&lt;br /&gt;
überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der folgenden &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 eines&lt;br /&gt;
&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, muss aber nach allen &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitten angegeben werden,&lt;br /&gt;
wenn er verwendet wird.&lt;br /&gt;
&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;
===&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;-Schleife===&lt;br /&gt;
'''Syntax:''' while (Bedingung) { Anweisung; }&lt;br /&gt;
&lt;br /&gt;
Die WHILE-Schleife wird solange durchlaufen, wie die Bedingung erfüllt (TRUE) ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Bei mehreren Anweisungen benötigen man einen Block! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Zahl1=0;&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;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife 3 mal durchlaufen. Zu Beginn des 4. Durchlaufes ist die Bedingung FALSE (Zahl1 ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
===&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;-Schleife===&lt;br /&gt;
'''Syntax:''' do  { Anweisung; }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. Das ist dann sinnvoll, wenn der Vergleichswert für die Bedingung erst im Anweisungsblock gesetzt wird &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int i=2;&lt;br /&gt;
do &lt;br /&gt;
{&lt;br /&gt;
    i = i*i;   /* 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;
&amp;lt;/pre&amp;gt;&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.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;-Schleife===&lt;br /&gt;
'''Syntax:''' for (Zuweisung;Bedingung;Inkrement) { Anweisung; }&lt;br /&gt;
&lt;br /&gt;
Die FOR-Schleife ist eine spezielle WHILE-Variante für die Formulierung von Zählschleifen. Die angegebene Variable wird am Anfang auf einen Wert gesetzt. Danach wird sie nach jedem Durchlauf verändert (meist um 1 erhöht). Ist die Bedingung nicht mehr erfüllt, wird die Schleife beendet. Innerhalb des Anweisungsblockes können Sie auf die Variable zugreifen, d.h. Sie können sie auch verändern. Das ist jedoch nicht ratsam. Wollen Sie mehrere Anweisungen ausführen, benötigen Sie eine Block.&lt;br /&gt;
&lt;br /&gt;
Die gesammte Schleife wird solange durchgeführt, wie die Bedingung wahr ist (d.h. Sie brauchen garnicht die Zählvariable abfragen, Sie können hier auch jede andere Variable auswerten). Inkrement letztendlich wird nach jedem Schleifendurchlauf ausgeführt. Hier kann man z.B. den Zähler erhöhen.&lt;br /&gt;
&lt;br /&gt;
Die Theorie ist schwer, die Praxis nicht so sehr. In der Schleife wird die Summe ungerader Zahlen kleinergleich 10 berechnet. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int lauf;&lt;br /&gt;
int summe = 0;&lt;br /&gt;
&lt;br /&gt;
for (lauf = 1; lauf &amp;lt;= 10; lauf = lauf+2 ) &lt;br /&gt;
{&lt;br /&gt;
   summe = summe + lauf;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Das Äquivalent als &amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;-Schleife:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int lauf  = 1;                 /* Anfangswerte */&lt;br /&gt;
int summe = 0;&lt;br /&gt;
&lt;br /&gt;
while (lauf &amp;lt;= 10)             /* Bedingung */&lt;br /&gt;
{&lt;br /&gt;
   summe = summe + lauf;&lt;br /&gt;
   lauf += 2;                  /* Inkrement */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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 1 bis 10 hat, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von 1 bis kleinergleich 10 gespeichert.&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 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 = 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;
=Ein- und Ausgabe=&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;
&lt;br /&gt;
=Allgemeines zu Unterprogrammen=&lt;br /&gt;
Stellen Sie sich vor, Sie haben einen eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben (was Zeit beim Erstellen und Speicherplatz im ausführbaren Programm kostet), können Sie den Abschnitt in ein sogenanntes &amp;quot;Unterprogramm&amp;quot; schreiben. Dieses Unterprogramm können Sie dann von jeder Stelle ihre Hauptprogrammes aus aufrufen.&lt;br /&gt;
Anders als in anderen Programmiersprachen gibt es in C keine generelle Unterscheidung zwischen Funktionen und Prozeduren. Trotzdem möchte ich kurz darauf eingehen: &lt;br /&gt;
&lt;br /&gt;
==Funktionen==&lt;br /&gt;
'''Syntax:''' Rückgabe-Typ Name(Parameterliste);&lt;br /&gt;
&lt;br /&gt;
Funktionen sind Unterprogramme, die am Ende der Ausführung einen Wert zurückliefern, wie z.B. getch. Paradebeispiele für die Anwendung einer Funktion sind jedoch mathematische Formeln: &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 hoch2 (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 (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, 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;zahl1);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = hoch2 (zahl1);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;,zahl1, ergebnis);&lt;br /&gt;
  printf (&amp;quot;5 hoch 2 = %d\n&amp;quot;, hoch2(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;
'''Bemerkungen zum Programm:''' &lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur außerhalb von Blöcken. Siehe auch Prototypen. &lt;br /&gt;
Geschachtelte-Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
In der Deklaration der Funktion kommt zuerst der Rückgabe-Datentyp. Jede Funktion liefert einen Wert zurück, dieser Datentyp gibt den Typ der Variablen an. Danach folgt der Name der Funktion (case-sensitiv!). Dann kommt in Klammern die Parameter-Liste. Dabei handelt es sich um eine Liste von Parametern, die jeweils durch Typ und Name angegeben werden und mittels Komma voneinander getrennt werden.&lt;br /&gt;
Im Block der Funktion können lokale Variablen definiert werden und alle Anweisungen ausgeführt werden. &lt;br /&gt;
Am Ende der Funktion muß diese ordnungsgemäß beendet werden. Dies geschieht mittels der Anweisung &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; und dem Rückgabewert. &lt;br /&gt;
Um eine Funktion aufzurufen (aus einem anderen Unterprogramm oder main), geben Sie folgendes an&lt;br /&gt;
 variable = Funktion (Parameter);&lt;br /&gt;
 Bei Variable muß es sich jedoch nicht unbedingt um eine von Ihnen deklarierte Variable handeln. Es kann z.B. auch der Parameter für ein weiteres Unterprogramm sein (wie im Beispiel, letzte Zeile). &lt;br /&gt;
Die Einrückungen der Anweisungen innerhalb der Funktion nach rechts ist nicht notwendig, sie dient jedoch der Übersicht und ist sehr empfehlenswert.&lt;br /&gt;
&lt;br /&gt;
==Prozedur==&lt;br /&gt;
'''Syntax:''' &amp;lt;tt&amp;gt;void Name (Parameterliste)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Prozedur ist nichts anderes als eine Funktion mit dem speziellen  Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der kennzeichnet, daß die Funktion keinen Wert zurückliefert. Sie ist daher prinzipiell gleich aufgebaut wie eine Funktion, bis auf die folgenden Unterschiede: &lt;br /&gt;
&lt;br /&gt;
Als Rückgabe-Datentyp wird &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; angegeben. &lt;br /&gt;
Einer Variablen kann daher nicht der Rückgabewert einer &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion zugewiesen werden, da diese garkeinen Rückgabewert liefert.&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 param1)&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Der Wert der Variablen ist: %d\n&amp;quot;, param1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
   int zahl1 = 4;&lt;br /&gt;
   &lt;br /&gt;
   ausgeben (23);&lt;br /&gt;
   ausgeben (zahl1);&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;
'''Bemerkungen zum Programm:''' &lt;br /&gt;
Durch den Befehl &amp;quot;&amp;lt;tt&amp;gt;ausgeben(23)&amp;lt;/tt&amp;gt;&amp;quot; wird die Prozedur &amp;quot;&amp;lt;tt&amp;gt;ausgeben&amp;lt;/tt&amp;gt;&amp;quot; mit dem Parameter &amp;lt;tt&amp;gt;23&amp;lt;/tt&amp;gt; aufgerufen. &amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt; hat also den Wert &amp;lt;tt&amp;gt;23&amp;lt;/tt&amp;gt;. Die einzige Anweisung innerhalb der Prozedur ist &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;, was nun ausgeführt wird. &lt;br /&gt;
Der zweite Aufruf von &amp;lt;tt&amp;gt;ausgeben&amp;lt;/tt&amp;gt; erfolgt mit dem Parameter &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, also wird &amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt; der Wert 4 zugewiesen. Dieser wird nun wieder mittels &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; ausgeben. &lt;br /&gt;
&lt;br /&gt;
Unterprogramme ohne Parameter&lt;br /&gt;
Das ist ihnen sicherlich schon aufgefallen: Viele Unterprogramme, haben statt einer Parameterliste nur &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; stehen. Das &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; bedeutet &amp;quot;die Funktion erhält keine Parameter&amp;quot;. &amp;quot;&amp;lt;tt&amp;gt;void main (void)&amp;lt;/tt&amp;gt;&amp;quot; bedeutet also: &amp;quot;Erstelle ein Unterprogramm Namens &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keinen Rückgabewert und keine Parameter hat&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen Sie beim Aufruf trotzdem die Klammern angeben. Beispiel für eine parameterlose Funktion &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 foo();&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;
&lt;br /&gt;
Beispiele:&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;
   /* a ist immer noch 0 */&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;
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 x übergeben. Dass dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void erhoehe (int *x)&lt;br /&gt;
{&lt;br /&gt;
   /* erhöhe 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;
   /* a ist jetzt 1 */&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;
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 Operator &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&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&lt;br /&gt;
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&lt;br /&gt;
den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;
  /* a hat jetzt folgenden Inhalt: 11, 23, 35 */&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;
&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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* 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;
  /* a hat jetzt folgenden Inhalt: 11, 23, 35 */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;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;
=Standard-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;
&lt;br /&gt;
&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;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der Computer 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 scanf - da übergeben Sie ja auch die Adresse einer Variablen (&amp;quot;&amp;amp;Variable&amp;quot;). &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 = *zeiger+1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main (void)&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;
==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: &amp;quot;dir *.exe&amp;quot;, &amp;quot;copy *.* a:&amp;quot; oder &amp;quot;ls -la&amp;quot;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;&amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen! &lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
&lt;br /&gt;
* [[#Speicherklassen|auto]]&lt;br /&gt;
* break&lt;br /&gt;
* [[#Elementare Datentypen|double]]&lt;br /&gt;
* [[#Elementare Datentypen|char]]&lt;br /&gt;
* case&lt;br /&gt;
* [[#Konstanten|const]]&lt;br /&gt;
* continue&lt;br /&gt;
* default&lt;br /&gt;
* do&lt;br /&gt;
* else&lt;br /&gt;
* enum&lt;br /&gt;
* [[#Speicherklassen|extern]]&lt;br /&gt;
* [[#Elementare Datentypen|float]]&lt;br /&gt;
* for&lt;br /&gt;
* goto&lt;br /&gt;
* if&lt;br /&gt;
* [[##Elementare Datentypen|int]]&lt;br /&gt;
* [[#Elementare Datentypen|long]]&lt;br /&gt;
* return&lt;br /&gt;
* [[#Speicherklassen|register]]&lt;br /&gt;
* [[#Elementare Datentypen|short]]&lt;br /&gt;
* signed&lt;br /&gt;
* sizeof&lt;br /&gt;
* [[#Speicherklassen|static]]&lt;br /&gt;
* [[#Strukturen|struct]]&lt;br /&gt;
* switch&lt;br /&gt;
* typedef&lt;br /&gt;
* [[#Unions|union]]&lt;br /&gt;
* unsigned&lt;br /&gt;
* [[#Elementare Datentypen|void]]&lt;br /&gt;
* volatile&lt;br /&gt;
* while&lt;br /&gt;
&lt;br /&gt;
Baustelle&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
Baustelle&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung || Nebeneffekte&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; == &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; != &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || ist nicht gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;lt; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;lt;= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;gt; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;gt;= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;amp; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; = &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; += &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; -= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; *= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; /= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; ^= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; |= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++ &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; ++&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-- &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; --&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;&amp;amp; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~ &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;! &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;(&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/font&amp;gt;) &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; + &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; - &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; * &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; / &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; % &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; %= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;(&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Bedingung&amp;gt;&amp;lt;/font&amp;gt;) ? &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; : &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Struct&amp;gt;&amp;lt;/font&amp;gt;.&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Komponenten-Bezeichner&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Zeiger-auf-Struct&amp;gt;&amp;lt;/font&amp;gt;-&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Komponenten-Bezeichner&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Autoren'''&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
* Kernighan und Ritchie - Buch&lt;br /&gt;
* Christian Wirth , C Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://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>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=8130</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=8130"/>
				<updated>2006-07-05T12:02:48Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Strukturen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ein kurzer Einblick in die Programmiersprache C&lt;br /&gt;
=Allgemeines=&lt;br /&gt;
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 Sprachedefinition entwickelt. C ist mittlerweile von ANSI und ISO standardisiert.&lt;br /&gt;
Heutzutage ist C (und ihr Nachfolger C++) die dominierende Programmiersprache. Sehr viele Anwendungen sind in C geschrieben. Leider ist C jedoch nicht einfach zu lernen, daher eignet es sich nur bedingt für Anfänger. Mit etwas Übung kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
C ist sehr eng an Assembler angelehnt, aber trotzdem Hardware-unabhängig. Das bedeutet, Sie können maschinennahe Programme sehr leicht (aber nicht ganz ohne Aufwand) auf ein anderes System portieren. Sie benötigen dazu 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;
&amp;lt;pre&amp;gt;&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;
   /* Anweisungen */&lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Beschreibung (die Erklärungen folgen): &lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndahs; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* &lt;br /&gt;
 * void Definition von main ist nur beim Controller üblich&lt;br /&gt;
 * spezielle Compilereinstellungen sind nötig, damit bei dieser Definition von main&lt;br /&gt;
 * kein Fehler/Warnung erzeugt wird. &lt;br /&gt;
 */&lt;br /&gt;
void main (void)&lt;br /&gt;
{&lt;br /&gt;
   ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{    /* der Block &amp;quot;main&amp;quot; beginnt */&lt;br /&gt;
   int zahl;&lt;br /&gt;
   &lt;br /&gt;
   {   /* ein Block beginnt */&lt;br /&gt;
       /* hier können Deklarationen und Anweisungen stehen */&lt;br /&gt;
   }   /* der Block endet */&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}    /* &amp;quot;main&amp;quot; endet */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Bemerkung:''' &lt;br /&gt;
Der &amp;quot;namenlose&amp;quot; Block ist eigentlich unnötig. In den folgenden Kapiteln lernen Sie jedoch bessere Beispiele kennen!&lt;br /&gt;
&lt;br /&gt;
=Datentypen=&lt;br /&gt;
==Elementare Datentypen==&lt;br /&gt;
Der Datentyp einer Variable gibt an, welche Werte eine Variable enthalten kann, welcher Art diese Daten sind und wie sie verarbeitet werden, etwa in arithmetischen Operationen wie einer Addition. So ist es zum Beispiel möglich, in eine Variable vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ganze Zahlen zwischen ca. -32000 und +32000 einzutragen. In einer char-Variable können ASCII-Zeichen gespeichert werden (alles, was Sie mit der Tastatur erzeugen können) oder ganze Zahlen von -128 bis 127.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da C plattformabhängig ist, hängt die Größe eines Datentypes zum Teil von der genutzten Hardware (z.B. 8, 16 oder 32 Bit-Controller) und dem Compiler und dessen Einstellungen ab!&lt;br /&gt;
&lt;br /&gt;
===int, char, short, long (ganze Zahlen)===&lt;br /&gt;
In Variable dieser Typen können Sie ganze Zahlen abspeichern, also z.B. 1, &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;2, 100, 12345. Jeden dieser Typen gibt es in zwei Ausprägungen: als &amp;quot;&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;quot;, also als vorzeichenbehafteten Typ, und als &amp;quot;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&amp;quot;, also ohne Vorzeichen, d.h. das Vorzeichen wird als 0 oder +1 genommen. &lt;br /&gt;
&lt;br /&gt;
Vorzeichenbehaftete Ganzzahl-Typen werden intern im &amp;lt;tt&amp;gt;n-1&amp;lt;/tt&amp;gt;-Komplement dargestellt, das Vorzeichen selbst findet sich also im höchstwertigen Bit. Werden zur Speicherung ''b'' Bits verwendet, dann reicht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;*zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==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:''' Datentyp Variablenname[Anzahl]&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 3 Variablen. Da der Index immer bei 0 beginnt, greift man also mit [0], [1] und [2] 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;
&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 i;&lt;br /&gt;
  int zahlen[10];  /* zahlen[0] bis zahlen[9] !!! */&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;10; 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;
  printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  for (i=0; i&amp;lt;10; 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;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Bemerkungen:''' &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;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
Wenn Sie einen ungültigen Index angeben (einen, der in der Deklaration nicht enthalten war) können je nach Compiler und Einstellung undefinierbare Dinge passieren, da dadurch andere Variableninhalte oder Programmcode überschrieben wird. Im schlimmsten Fall könnte sogar der Computer/Controller abstürzen. Also achten Sie darauf, daß Sie keine ungültigen Werte als Index angeben!&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;
&amp;lt;pre&amp;gt;&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;
&amp;lt;/pre&amp;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 vier Komponenten angelegt: 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 dieses Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach &lt;br /&gt;
 struct Person Variablenname;&lt;br /&gt;
an. &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;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  struct Person hubert, klaus;&lt;br /&gt;
&lt;br /&gt;
  hubert.alter = 32;&lt;br /&gt;
  klaus.alter = hubert.alter + 1;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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 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 Person u_person;&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_double&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Groß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.&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 chat 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.&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;
/* nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform) */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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;
Teilweise erlauben C-Compiler auch die Verwendung des Dollar-Zeichens &amp;lt;tt&amp;gt;'''$'''&amp;lt;/tt&amp;gt; in Variablennaben.&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;
&amp;lt;pre&amp;gt;&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;
  /* Anweisungen */&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
;Erklärung: 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;wahr&amp;quot;, ansonsten ist sie &amp;quot;unwahr&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;
==Vergleich von Variablen==&lt;br /&gt;
Sie können Variablen miteinander vergleichen. Das geschieht mit einem der folgenden Zeichen mit den normalen mathematischen Regeln: &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;
Als Ergebnis bekommen Sie einen logischen Ausdruck in Form einer int-Zahl. &lt;br /&gt;
 intVariable = zahl1 &amp;lt;= zahl2;&lt;br /&gt;
das komplette Beispiel zeigt es deutlicher:&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;= z1  /* Ein Vergleich. Die int-Variable i wird wahr, da z1 kleiner als z2 */&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Ergebnis: %d\n&amp;quot;, i);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich 0 (&amp;quot;wahr&amp;quot;), wenn z1 kleiner oder gleich z2 ist. Ist z1 jedoch größer als z2, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich 0 (&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 dafür ein Schlüsselwort in C:&lt;br /&gt;
 const ''datentyp'' name = value;  /* 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;  /* 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;. 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 Eigenheit 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, wenn das Ergebnis bereits feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
  (x &amp;gt; 5) || datei_auf_festplatte_gefunden(&amp;quot;hallo.txt&amp;quot;) /* gut */&lt;br /&gt;
  datei_auf_festplatte_gefunden(&amp;quot;hallo.txt&amp;quot;) || (x &amp;gt; 5) /* nicht so gut */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;datei_auf_festplatte_gefunden&amp;lt;/tt&amp;gt; ist fiktiv und steht für eine Funktion,&lt;br /&gt;
die eine aufwändige Operation durchführt.&lt;br /&gt;
Beide Zeilen ergeben &amp;lt;tt&amp;gt;wahr&amp;lt;/tt&amp;gt; wenn die Variable x einen Wert größer 5 hat oder&lt;br /&gt;
es eine Datei namens &amp;lt;tt&amp;gt;hallo.txt&amp;lt;/tt&amp;gt; auf der Festplatte gibt.&lt;br /&gt;
&lt;br /&gt;
Wo ist also der Unterschied?&amp;lt;br&amp;gt;&lt;br /&gt;
In der ersten Zeile wird geprüft, ob x größer als 5 ist und wenn das der Fall ist,&lt;br /&gt;
dann wird ''nicht mehr geprüft'', ob &amp;lt;tt&amp;gt;hallo.txt&amp;lt;/tt&amp;gt; auf der Festplatte existiert.&lt;br /&gt;
In der zweiten Zeile wird ''immer geprüft'', ob &amp;lt;tt&amp;gt;hallo.txt&amp;lt;/tt&amp;gt; auf der Festplatte&lt;br /&gt;
existiert und erst, wenn sie nicht gefunden wird, wird die Variable x ausgewertet.&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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  int x = 5;    /* x ist eine Integervariable und hat den Wert 5 */&lt;br /&gt;
&lt;br /&gt;
  /* z ist ein Zeiger auf eine Integervariable und enthält somit&lt;br /&gt;
     die Speicheradresse einer Integervariablen&lt;br /&gt;
  */&lt;br /&gt;
  int *z;       &lt;br /&gt;
&lt;br /&gt;
  /* Verwendung des Adressoperators... */&lt;br /&gt;
  z = &amp;amp;x;       /* weise z die Speicheradresse von x zu */&lt;br /&gt;
&lt;br /&gt;
  /* Verwendung der Dereferenzierung */&lt;br /&gt;
  /* erhöhe den Wert, der bei Adresse z steht um eins */&lt;br /&gt;
  *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
  /* da z auf x zeigt, hat auch x jetzt den Wert 6 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff&lt;br /&gt;
auf ein Element 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;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&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&lt;br /&gt;
auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu&lt;br /&gt;
einer Änderung '''irgendeiner''' Speicherstelle:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   int *z; /* z ist ein Zeiger auf einen Integer */&lt;br /&gt;
&lt;br /&gt;
   /* An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.&lt;br /&gt;
      z enthält irgendeine(!) Adresse&lt;br /&gt;
   */&lt;br /&gt;
&lt;br /&gt;
   /* &amp;quot;Erhöhe einen Integer irgendwo im Speicher um 1&amp;quot; -&amp;gt; CRASH */&lt;br /&gt;
   *z = *z + 1;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler (z.B. gcc) erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
}}&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'' durch, sondern unterdrückt nur die Compilerwarnungen oder&lt;br /&gt;
-fehler, die bei einer &amp;quot;verdächtigen&amp;quot; Umwandlung passieren. Er kann also nicht benutzt werden, um einen Text in&lt;br /&gt;
eine Zahl oder umgekehrt zu wandeln:&lt;br /&gt;
&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;
&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Speicheradresse, an der der Text &amp;quot;5.6&amp;quot; beginnt. Der Cast-Operator&lt;br /&gt;
unterdrückt nur die Warnung, die auf den Fehler hinweisen will.&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;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Bedingte Zuweisung===&lt;br /&gt;
 lvalue = (bediungung) ? if-ausdruck : else-ausdruck;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Kein ANSI-C&lt;br /&gt;
--[[Benutzer:SprinterSB|SprinterSB]] 17:15, 29. Jun 2006 (CEST)&lt;br /&gt;
==Blöcke==&lt;br /&gt;
Selbst Blöcke haben in C einen Wert, der in einer Berechnung verwendet werden kann.&lt;br /&gt;
Der Wert eines Blockes ist der Wert der letzten Anweisung des Blocks. &lt;br /&gt;
Der Block muss un runden Klammern stehen:&lt;br /&gt;
 int sum;&lt;br /&gt;
 sum = ({&lt;br /&gt;
    int i, s = 0;&lt;br /&gt;
    for (i=1; i&amp;lt;= 100; i++)&lt;br /&gt;
       s += i;&lt;br /&gt;
    s;&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Makro &amp;lt;tt&amp;gt;PSTR&amp;lt;/tt&amp;gt; von avr-gcc, &lt;br /&gt;
das einen String ins Flash legt und die Adresse zurückliefert, was nur in einer&lt;br /&gt;
Instruktion nicht machbar wäre:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define PSTR(s)                         \&lt;br /&gt;
  ({                                    \ &lt;br /&gt;
      static char __c[] PROGMEM = (s);  \&lt;br /&gt;
      __c;                              \&lt;br /&gt;
  })&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
==Boolsche Logik==&lt;br /&gt;
Boolean-Variablen können miteinander verknüpft werden. Dies geschieht mit den boolschen Operatoren &amp;amp;&amp;amp; ( logisches &amp;quot;und&amp;quot;), || (logisches &amp;quot;oder&amp;quot;) und ! (logisches &amp;quot;nicht&amp;quot;) (es gibt noch weitere, auf die hier nicht eingegangen wird). &lt;br /&gt;
&lt;br /&gt;
 b1= b2 &amp;amp;&amp;amp; b3;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der Wert von b1 ist dann 1 (TRUE), wenn b2 und (&amp;quot;AND&amp;quot;) b3 1 (TRUE) sind. Ist eine der beiden (oder auch beide) 0 (FALSE), dann ist b1 ebenfalls 0 (FALSE).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 b1= b2 || b3;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der Wert von b1 ist dann TRUE, wenn b2 oder (&amp;quot;OR&amp;quot;) b3 TRUE ist. Ist also einer (oder beide) TRUE, dann ist auch b1 TRUE, sind beide FALSE, ist auch b1 FALSE.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 b1= !b2;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der Wert von b1 ist dann TRUE, wenn der von b2 FALSE ist. Die NOT Verknüpfung &amp;quot;dreht den logischen Wert der Variablen um&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Anweisung==&lt;br /&gt;
Syntax: IF (Bedingung) Anweisung;&lt;br /&gt;
Mit Hilfe der IF Anweisung kann man Codeteile (Blöcke) ausführen lassen, wenn die dazugehörige Bedingung erfüllt (TRUE) ist. Im Flussdiagramm sieht eine If-Anweisung folgendermassen aus:&lt;br /&gt;
&lt;br /&gt;
[[bild:ifthenelse.png]]&lt;br /&gt;
&lt;br /&gt;
Und in C schreibt man:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if (Bedingung)        /* WENN */&lt;br /&gt;
{                     /* DANN */&lt;br /&gt;
       Anweisung1;&lt;br /&gt;
       Anweisung2;&lt;br /&gt;
       ...&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{                     /* SONST */&lt;br /&gt;
       Anweisung3;&lt;br /&gt;
       Anweisung4;&lt;br /&gt;
       ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wenn die Bedingung wahr ist wird Anweisung1 ausgeführt. Anschliessend wird aus der If-Bedingung herausgesprungen. Anweisung2 wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung unwahr wird gleich zu Anweisung2 gesprungen, diese ausgeführt, und anschliessend wird die If-Bedingung beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Ein häufiger Fehler ist statt if(a == 23) etwas wie if(a = 23) zu schreiben. Hier wird allerdings nicht geprüft ob die Variable a gleich 23 ist, sondern der Variable a wird der Wert 23 zugewiesen, und das ist eine wahre Aussage. Anschliessend wird demzufolge der &amp;quot;DANN&amp;quot;-Teil ausgeführt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken. Somit ist dieser kleine Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise if(23 == a). Wenn man dort anstatt des Vergleichsoperator '==' den Zuweisungsoperator '=' verwendet spuckt der Compiler sehr wohl einen Fehler aus.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist das schreiben von if(Bedingung)''';''' Richtig müsste es heissen &amp;quot;if(Bedingung)&amp;quot; Das fehlerhafte Semikolon im ersten Fall interpretiert der Compiler bereits als Anweisung. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt. Hier also ebenfalls besser zweimal hinschauen.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;-Anweisung==&lt;br /&gt;
Syntax: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
switch(ausdruck) {&lt;br /&gt;
    case wert1:&lt;br /&gt;
        Anweisungen1...&lt;br /&gt;
    case wert2:&lt;br /&gt;
        Anweisungen2...&lt;br /&gt;
    case wert3:&lt;br /&gt;
        Anweisungen3...&lt;br /&gt;
    ...&lt;br /&gt;
    default:&lt;br /&gt;
        Anweisungen4...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der &amp;lt;tt&amp;gt;ausdruck&amp;lt;/tt&amp;gt; muss eine Ganzzahl (int) ergeben und wird dann der Reihe nach mit den Werten, die hinter&lt;br /&gt;
den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Anweisungen angegeben sind verglichen. Bei einer Übereinstimmung werden alle Befehle ab der&lt;br /&gt;
zutreffenden Case-Anweisung ausgeführt. Stimmt der &amp;lt;tt&amp;gt;ausdruck&amp;lt;/tt&amp;gt; mit keinem der Werte hinter &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;&lt;br /&gt;
überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der folgenden &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 eines&lt;br /&gt;
&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, muss aber nach allen &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitten angegeben werden,&lt;br /&gt;
wenn er verwendet wird.&lt;br /&gt;
&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;
===&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;-Schleife===&lt;br /&gt;
'''Syntax:''' while (Bedingung) { Anweisung; }&lt;br /&gt;
&lt;br /&gt;
Die WHILE-Schleife wird solange durchlaufen, wie die Bedingung erfüllt (TRUE) ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Bei mehreren Anweisungen benötigen man einen Block! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Zahl1=0;&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;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife 3 mal durchlaufen. Zu Beginn des 4. Durchlaufes ist die Bedingung FALSE (Zahl1 ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
===&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;-Schleife===&lt;br /&gt;
'''Syntax:''' do  { Anweisung; }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. Das ist dann sinnvoll, wenn der Vergleichswert für die Bedingung erst im Anweisungsblock gesetzt wird &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int i=2;&lt;br /&gt;
do &lt;br /&gt;
{&lt;br /&gt;
    i = i*i;   /* 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;
&amp;lt;/pre&amp;gt;&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.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;-Schleife===&lt;br /&gt;
'''Syntax:''' for (Zuweisung;Bedingung;Inkrement) { Anweisung; }&lt;br /&gt;
&lt;br /&gt;
Die FOR-Schleife ist eine spezielle WHILE-Variante für die Formulierung von Zählschleifen. Die angegebene Variable wird am Anfang auf einen Wert gesetzt. Danach wird sie nach jedem Durchlauf verändert (meist um 1 erhöht). Ist die Bedingung nicht mehr erfüllt, wird die Schleife beendet. Innerhalb des Anweisungsblockes können Sie auf die Variable zugreifen, d.h. Sie können sie auch verändern. Das ist jedoch nicht ratsam. Wollen Sie mehrere Anweisungen ausführen, benötigen Sie eine Block.&lt;br /&gt;
&lt;br /&gt;
Die gesammte Schleife wird solange durchgeführt, wie die Bedingung wahr ist (d.h. Sie brauchen garnicht die Zählvariable abfragen, Sie können hier auch jede andere Variable auswerten). Inkrement letztendlich wird nach jedem Schleifendurchlauf ausgeführt. Hier kann man z.B. den Zähler erhöhen.&lt;br /&gt;
&lt;br /&gt;
Die Theorie ist schwer, die Praxis nicht so sehr. In der Schleife wird die Summe ungerader Zahlen kleinergleich 10 berechnet. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int lauf;&lt;br /&gt;
int summe = 0;&lt;br /&gt;
&lt;br /&gt;
for (lauf = 1; lauf &amp;lt;= 10; lauf = lauf+2 ) &lt;br /&gt;
{&lt;br /&gt;
   summe = summe + lauf;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Das Äquivalent als &amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;-Schleife:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int lauf  = 1;                 /* Anfangswerte */&lt;br /&gt;
int summe = 0;&lt;br /&gt;
&lt;br /&gt;
while (lauf &amp;lt;= 10)             /* Bedingung */&lt;br /&gt;
{&lt;br /&gt;
   summe = summe + lauf;&lt;br /&gt;
   lauf += 2;                  /* Inkrement */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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 1 bis 10 hat, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von 1 bis kleinergleich 10 gespeichert.&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 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 = 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;
=Ein- und Ausgabe=&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;
&lt;br /&gt;
=Allgemeines zu Unterprogrammen=&lt;br /&gt;
Stellen Sie sich vor, Sie haben einen eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben (was Zeit beim Erstellen und Speicherplatz im ausführbaren Programm kostet), können Sie den Abschnitt in ein sogenanntes &amp;quot;Unterprogramm&amp;quot; schreiben. Dieses Unterprogramm können Sie dann von jeder Stelle ihre Hauptprogrammes aus aufrufen.&lt;br /&gt;
Anders als in anderen Programmiersprachen gibt es in C keine generelle Unterscheidung zwischen Funktionen und Prozeduren. Trotzdem möchte ich kurz darauf eingehen: &lt;br /&gt;
&lt;br /&gt;
==Funktionen==&lt;br /&gt;
'''Syntax:''' Rückgabe-Typ Name(Parameterliste);&lt;br /&gt;
&lt;br /&gt;
Funktionen sind Unterprogramme, die am Ende der Ausführung einen Wert zurückliefern, wie z.B. getch. Paradebeispiele für die Anwendung einer Funktion sind jedoch mathematische Formeln: &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 hoch2 (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 (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, 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;zahl1);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = hoch2 (zahl1);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;,zahl1, ergebnis);&lt;br /&gt;
  printf (&amp;quot;5 hoch 2 = %d\n&amp;quot;, hoch2(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;
'''Bemerkungen zum Programm:''' &lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur außerhalb von Blöcken. Siehe auch Prototypen. &lt;br /&gt;
Geschachtelte-Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
In der Deklaration der Funktion kommt zuerst der Rückgabe-Datentyp. Jede Funktion liefert einen Wert zurück, dieser Datentyp gibt den Typ der Variablen an. Danach folgt der Name der Funktion (case-sensitiv!). Dann kommt in Klammern die Parameter-Liste. Dabei handelt es sich um eine Liste von Parametern, die jeweils durch Typ und Name angegeben werden und mittels Komma voneinander getrennt werden.&lt;br /&gt;
Im Block der Funktion können lokale Variablen definiert werden und alle Anweisungen ausgeführt werden. &lt;br /&gt;
Am Ende der Funktion muß diese ordnungsgemäß beendet werden. Dies geschieht mittels der Anweisung &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; und dem Rückgabewert. &lt;br /&gt;
Um eine Funktion aufzurufen (aus einem anderen Unterprogramm oder main), geben Sie folgendes an&lt;br /&gt;
 variable = Funktion (Parameter);&lt;br /&gt;
 Bei Variable muß es sich jedoch nicht unbedingt um eine von Ihnen deklarierte Variable handeln. Es kann z.B. auch der Parameter für ein weiteres Unterprogramm sein (wie im Beispiel, letzte Zeile). &lt;br /&gt;
Die Einrückungen der Anweisungen innerhalb der Funktion nach rechts ist nicht notwendig, sie dient jedoch der Übersicht und ist sehr empfehlenswert.&lt;br /&gt;
&lt;br /&gt;
==Prozedur==&lt;br /&gt;
'''Syntax:''' &amp;lt;tt&amp;gt;void Name (Parameterliste)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Prozedur ist nichts anderes als eine Funktion mit dem speziellen  Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der kennzeichnet, daß die Funktion keinen Wert zurückliefert. Sie ist daher prinzipiell gleich aufgebaut wie eine Funktion, bis auf die folgenden Unterschiede: &lt;br /&gt;
&lt;br /&gt;
Als Rückgabe-Datentyp wird &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; angegeben. &lt;br /&gt;
Einer Variablen kann daher nicht der Rückgabewert einer &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion zugewiesen werden, da diese garkeinen Rückgabewert liefert.&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 param1)&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Der Wert der Variablen ist: %d\n&amp;quot;, param1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
   int zahl1 = 4;&lt;br /&gt;
   &lt;br /&gt;
   ausgeben (23);&lt;br /&gt;
   ausgeben (zahl1);&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;
'''Bemerkungen zum Programm:''' &lt;br /&gt;
Durch den Befehl &amp;quot;&amp;lt;tt&amp;gt;ausgeben(23)&amp;lt;/tt&amp;gt;&amp;quot; wird die Prozedur &amp;quot;&amp;lt;tt&amp;gt;ausgeben&amp;lt;/tt&amp;gt;&amp;quot; mit dem Parameter &amp;lt;tt&amp;gt;23&amp;lt;/tt&amp;gt; aufgerufen. &amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt; hat also den Wert &amp;lt;tt&amp;gt;23&amp;lt;/tt&amp;gt;. Die einzige Anweisung innerhalb der Prozedur ist &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;, was nun ausgeführt wird. &lt;br /&gt;
Der zweite Aufruf von &amp;lt;tt&amp;gt;ausgeben&amp;lt;/tt&amp;gt; erfolgt mit dem Parameter &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, also wird &amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt; der Wert 4 zugewiesen. Dieser wird nun wieder mittels &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; ausgeben. &lt;br /&gt;
&lt;br /&gt;
Unterprogramme ohne Parameter&lt;br /&gt;
Das ist ihnen sicherlich schon aufgefallen: Viele Unterprogramme, haben statt einer Parameterliste nur &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; stehen. Das &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; bedeutet &amp;quot;die Funktion erhält keine Parameter&amp;quot;. &amp;quot;&amp;lt;tt&amp;gt;void main (void)&amp;lt;/tt&amp;gt;&amp;quot; bedeutet also: &amp;quot;Erstelle ein Unterprogramm Namens &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keinen Rückgabewert und keine Parameter hat&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen Sie beim Aufruf trotzdem die Klammern angeben. Beispiel für eine parameterlose Funktion &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 foo();&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;
&lt;br /&gt;
Beispiele:&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;
   /* a ist immer noch 0 */&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;
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 x übergeben. Dass dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void erhoehe (int *x)&lt;br /&gt;
{&lt;br /&gt;
   /* erhöhe 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;
   /* a ist jetzt 1 */&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;
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 Operator &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&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&lt;br /&gt;
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&lt;br /&gt;
den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;
  /* a hat jetzt folgenden Inhalt: 11, 23, 35 */&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;
&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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* 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;
  /* a hat jetzt folgenden Inhalt: 11, 23, 35 */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;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;
=Standard-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;
&lt;br /&gt;
&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;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der Computer 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 scanf - da übergeben Sie ja auch die Adresse einer Variablen (&amp;quot;&amp;amp;Variable&amp;quot;). &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 = *zeiger+1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main (void)&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;
==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: &amp;quot;dir *.exe&amp;quot;, &amp;quot;copy *.* a:&amp;quot; oder &amp;quot;ls -la&amp;quot;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;&amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen! &lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
&lt;br /&gt;
* [[#Speicherklassen|auto]]&lt;br /&gt;
* break&lt;br /&gt;
* [[#Elementare Datentypen|double]]&lt;br /&gt;
* [[#Elementare Datentypen|char]]&lt;br /&gt;
* case&lt;br /&gt;
* [[#Konstanten|const]]&lt;br /&gt;
* continue&lt;br /&gt;
* default&lt;br /&gt;
* do&lt;br /&gt;
* else&lt;br /&gt;
* enum&lt;br /&gt;
* [[#Speicherklassen|extern]]&lt;br /&gt;
* [[#Elementare Datentypen|float]]&lt;br /&gt;
* for&lt;br /&gt;
* goto&lt;br /&gt;
* if&lt;br /&gt;
* [[##Elementare Datentypen|int]]&lt;br /&gt;
* [[#Elementare Datentypen|long]]&lt;br /&gt;
* return&lt;br /&gt;
* [[#Speicherklassen|register]]&lt;br /&gt;
* [[#Elementare Datentypen|short]]&lt;br /&gt;
* signed&lt;br /&gt;
* sizeof&lt;br /&gt;
* [[#Speicherklassen|static]]&lt;br /&gt;
* [[#Strukturen|struct]]&lt;br /&gt;
* switch&lt;br /&gt;
* typedef&lt;br /&gt;
* [[#Unions|union]]&lt;br /&gt;
* unsigned&lt;br /&gt;
* [[#Elementare Datentypen|void]]&lt;br /&gt;
* volatile&lt;br /&gt;
* while&lt;br /&gt;
&lt;br /&gt;
Baustelle&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
Baustelle&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung || Nebeneffekte&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; == &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; != &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || ist nicht gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;lt; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;lt;= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;gt; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;gt;= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;amp; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; = &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; += &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; -= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; *= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; /= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; ^= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; |= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++ &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; ++&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-- &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; --&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;&amp;amp; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~ &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;! &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;(&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/font&amp;gt;) &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; + &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; - &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; * &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; / &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; % &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; %= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;(&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Bedingung&amp;gt;&amp;lt;/font&amp;gt;) ? &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; : &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Struct&amp;gt;&amp;lt;/font&amp;gt;.&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Komponenten-Bezeichner&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Zeiger-auf-Struct&amp;gt;&amp;lt;/font&amp;gt;-&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Komponenten-Bezeichner&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Autoren'''&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
* Kernighan und Ritchie - Buch&lt;br /&gt;
* Christian Wirth , C Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://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>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=8129</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=8129"/>
				<updated>2006-07-05T11:58:42Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Mehrdimensionale Arrays */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ein kurzer Einblick in die Programmiersprache C&lt;br /&gt;
=Allgemeines=&lt;br /&gt;
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 Sprachedefinition entwickelt. C ist mittlerweile von ANSI und ISO standardisiert.&lt;br /&gt;
Heutzutage ist C (und ihr Nachfolger C++) die dominierende Programmiersprache. Sehr viele Anwendungen sind in C geschrieben. Leider ist C jedoch nicht einfach zu lernen, daher eignet es sich nur bedingt für Anfänger. Mit etwas Übung kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
C ist sehr eng an Assembler angelehnt, aber trotzdem Hardware-unabhängig. Das bedeutet, Sie können maschinennahe Programme sehr leicht (aber nicht ganz ohne Aufwand) auf ein anderes System portieren. Sie benötigen dazu 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;
&amp;lt;pre&amp;gt;&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;
   /* Anweisungen */&lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Beschreibung (die Erklärungen folgen): &lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndahs; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* &lt;br /&gt;
 * void Definition von main ist nur beim Controller üblich&lt;br /&gt;
 * spezielle Compilereinstellungen sind nötig, damit bei dieser Definition von main&lt;br /&gt;
 * kein Fehler/Warnung erzeugt wird. &lt;br /&gt;
 */&lt;br /&gt;
void main (void)&lt;br /&gt;
{&lt;br /&gt;
   ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{    /* der Block &amp;quot;main&amp;quot; beginnt */&lt;br /&gt;
   int zahl;&lt;br /&gt;
   &lt;br /&gt;
   {   /* ein Block beginnt */&lt;br /&gt;
       /* hier können Deklarationen und Anweisungen stehen */&lt;br /&gt;
   }   /* der Block endet */&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}    /* &amp;quot;main&amp;quot; endet */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Bemerkung:''' &lt;br /&gt;
Der &amp;quot;namenlose&amp;quot; Block ist eigentlich unnötig. In den folgenden Kapiteln lernen Sie jedoch bessere Beispiele kennen!&lt;br /&gt;
&lt;br /&gt;
=Datentypen=&lt;br /&gt;
==Elementare Datentypen==&lt;br /&gt;
Der Datentyp einer Variable gibt an, welche Werte eine Variable enthalten kann, welcher Art diese Daten sind und wie sie verarbeitet werden, etwa in arithmetischen Operationen wie einer Addition. So ist es zum Beispiel möglich, in eine Variable vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ganze Zahlen zwischen ca. -32000 und +32000 einzutragen. In einer char-Variable können ASCII-Zeichen gespeichert werden (alles, was Sie mit der Tastatur erzeugen können) oder ganze Zahlen von -128 bis 127.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da C plattformabhängig ist, hängt die Größe eines Datentypes zum Teil von der genutzten Hardware (z.B. 8, 16 oder 32 Bit-Controller) und dem Compiler und dessen Einstellungen ab!&lt;br /&gt;
&lt;br /&gt;
===int, char, short, long (ganze Zahlen)===&lt;br /&gt;
In Variable dieser Typen können Sie ganze Zahlen abspeichern, also z.B. 1, &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;2, 100, 12345. Jeden dieser Typen gibt es in zwei Ausprägungen: als &amp;quot;&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;quot;, also als vorzeichenbehafteten Typ, und als &amp;quot;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&amp;quot;, also ohne Vorzeichen, d.h. das Vorzeichen wird als 0 oder +1 genommen. &lt;br /&gt;
&lt;br /&gt;
Vorzeichenbehaftete Ganzzahl-Typen werden intern im &amp;lt;tt&amp;gt;n-1&amp;lt;/tt&amp;gt;-Komplement dargestellt, das Vorzeichen selbst findet sich also im höchstwertigen Bit. Werden zur Speicherung ''b'' Bits verwendet, dann reicht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;*zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==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:''' Datentyp Variablenname[Anzahl]&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 3 Variablen. Da der Index immer bei 0 beginnt, greift man also mit [0], [1] und [2] 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;
&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 i;&lt;br /&gt;
  int zahlen[10];  /* zahlen[0] bis zahlen[9] !!! */&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;10; 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;
  printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  for (i=0; i&amp;lt;10; 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;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Bemerkungen:''' &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;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
Wenn Sie einen ungültigen Index angeben (einen, der in der Deklaration nicht enthalten war) können je nach Compiler und Einstellung undefinierbare Dinge passieren, da dadurch andere Variableninhalte oder Programmcode überschrieben wird. Im schlimmsten Fall könnte sogar der Computer/Controller abstürzen. Also achten Sie darauf, daß Sie keine ungültigen Werte als Index angeben!&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;
&amp;lt;pre&amp;gt;&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;
&amp;lt;/pre&amp;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 vier Komponenten angelege: 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 dieses Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach &lt;br /&gt;
 struct Person Variablenname;&lt;br /&gt;
an. &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;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  struct Person hubert, klaus;&lt;br /&gt;
&lt;br /&gt;
  hubert.alter = 32;&lt;br /&gt;
  klaus.alter = hubert.alter + 1;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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 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 Person u_person;&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_double&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Groß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.&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 chat 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.&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;
/* nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform) */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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;
Teilweise erlauben C-Compiler auch die Verwendung des Dollar-Zeichens &amp;lt;tt&amp;gt;'''$'''&amp;lt;/tt&amp;gt; in Variablennaben.&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;
&amp;lt;pre&amp;gt;&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;
  /* Anweisungen */&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
;Erklärung: 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;wahr&amp;quot;, ansonsten ist sie &amp;quot;unwahr&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;
==Vergleich von Variablen==&lt;br /&gt;
Sie können Variablen miteinander vergleichen. Das geschieht mit einem der folgenden Zeichen mit den normalen mathematischen Regeln: &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;
Als Ergebnis bekommen Sie einen logischen Ausdruck in Form einer int-Zahl. &lt;br /&gt;
 intVariable = zahl1 &amp;lt;= zahl2;&lt;br /&gt;
das komplette Beispiel zeigt es deutlicher:&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;= z1  /* Ein Vergleich. Die int-Variable i wird wahr, da z1 kleiner als z2 */&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Ergebnis: %d\n&amp;quot;, i);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich 0 (&amp;quot;wahr&amp;quot;), wenn z1 kleiner oder gleich z2 ist. Ist z1 jedoch größer als z2, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich 0 (&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 dafür ein Schlüsselwort in C:&lt;br /&gt;
 const ''datentyp'' name = value;  /* 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;  /* 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;. 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 Eigenheit 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, wenn das Ergebnis bereits feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
  (x &amp;gt; 5) || datei_auf_festplatte_gefunden(&amp;quot;hallo.txt&amp;quot;) /* gut */&lt;br /&gt;
  datei_auf_festplatte_gefunden(&amp;quot;hallo.txt&amp;quot;) || (x &amp;gt; 5) /* nicht so gut */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;datei_auf_festplatte_gefunden&amp;lt;/tt&amp;gt; ist fiktiv und steht für eine Funktion,&lt;br /&gt;
die eine aufwändige Operation durchführt.&lt;br /&gt;
Beide Zeilen ergeben &amp;lt;tt&amp;gt;wahr&amp;lt;/tt&amp;gt; wenn die Variable x einen Wert größer 5 hat oder&lt;br /&gt;
es eine Datei namens &amp;lt;tt&amp;gt;hallo.txt&amp;lt;/tt&amp;gt; auf der Festplatte gibt.&lt;br /&gt;
&lt;br /&gt;
Wo ist also der Unterschied?&amp;lt;br&amp;gt;&lt;br /&gt;
In der ersten Zeile wird geprüft, ob x größer als 5 ist und wenn das der Fall ist,&lt;br /&gt;
dann wird ''nicht mehr geprüft'', ob &amp;lt;tt&amp;gt;hallo.txt&amp;lt;/tt&amp;gt; auf der Festplatte existiert.&lt;br /&gt;
In der zweiten Zeile wird ''immer geprüft'', ob &amp;lt;tt&amp;gt;hallo.txt&amp;lt;/tt&amp;gt; auf der Festplatte&lt;br /&gt;
existiert und erst, wenn sie nicht gefunden wird, wird die Variable x ausgewertet.&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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  int x = 5;    /* x ist eine Integervariable und hat den Wert 5 */&lt;br /&gt;
&lt;br /&gt;
  /* z ist ein Zeiger auf eine Integervariable und enthält somit&lt;br /&gt;
     die Speicheradresse einer Integervariablen&lt;br /&gt;
  */&lt;br /&gt;
  int *z;       &lt;br /&gt;
&lt;br /&gt;
  /* Verwendung des Adressoperators... */&lt;br /&gt;
  z = &amp;amp;x;       /* weise z die Speicheradresse von x zu */&lt;br /&gt;
&lt;br /&gt;
  /* Verwendung der Dereferenzierung */&lt;br /&gt;
  /* erhöhe den Wert, der bei Adresse z steht um eins */&lt;br /&gt;
  *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
  /* da z auf x zeigt, hat auch x jetzt den Wert 6 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff&lt;br /&gt;
auf ein Element 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;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&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&lt;br /&gt;
auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu&lt;br /&gt;
einer Änderung '''irgendeiner''' Speicherstelle:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   int *z; /* z ist ein Zeiger auf einen Integer */&lt;br /&gt;
&lt;br /&gt;
   /* An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.&lt;br /&gt;
      z enthält irgendeine(!) Adresse&lt;br /&gt;
   */&lt;br /&gt;
&lt;br /&gt;
   /* &amp;quot;Erhöhe einen Integer irgendwo im Speicher um 1&amp;quot; -&amp;gt; CRASH */&lt;br /&gt;
   *z = *z + 1;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler (z.B. gcc) erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
}}&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'' durch, sondern unterdrückt nur die Compilerwarnungen oder&lt;br /&gt;
-fehler, die bei einer &amp;quot;verdächtigen&amp;quot; Umwandlung passieren. Er kann also nicht benutzt werden, um einen Text in&lt;br /&gt;
eine Zahl oder umgekehrt zu wandeln:&lt;br /&gt;
&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;
&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Speicheradresse, an der der Text &amp;quot;5.6&amp;quot; beginnt. Der Cast-Operator&lt;br /&gt;
unterdrückt nur die Warnung, die auf den Fehler hinweisen will.&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;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Bedingte Zuweisung===&lt;br /&gt;
 lvalue = (bediungung) ? if-ausdruck : else-ausdruck;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Kein ANSI-C&lt;br /&gt;
--[[Benutzer:SprinterSB|SprinterSB]] 17:15, 29. Jun 2006 (CEST)&lt;br /&gt;
==Blöcke==&lt;br /&gt;
Selbst Blöcke haben in C einen Wert, der in einer Berechnung verwendet werden kann.&lt;br /&gt;
Der Wert eines Blockes ist der Wert der letzten Anweisung des Blocks. &lt;br /&gt;
Der Block muss un runden Klammern stehen:&lt;br /&gt;
 int sum;&lt;br /&gt;
 sum = ({&lt;br /&gt;
    int i, s = 0;&lt;br /&gt;
    for (i=1; i&amp;lt;= 100; i++)&lt;br /&gt;
       s += i;&lt;br /&gt;
    s;&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Makro &amp;lt;tt&amp;gt;PSTR&amp;lt;/tt&amp;gt; von avr-gcc, &lt;br /&gt;
das einen String ins Flash legt und die Adresse zurückliefert, was nur in einer&lt;br /&gt;
Instruktion nicht machbar wäre:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define PSTR(s)                         \&lt;br /&gt;
  ({                                    \ &lt;br /&gt;
      static char __c[] PROGMEM = (s);  \&lt;br /&gt;
      __c;                              \&lt;br /&gt;
  })&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
==Boolsche Logik==&lt;br /&gt;
Boolean-Variablen können miteinander verknüpft werden. Dies geschieht mit den boolschen Operatoren &amp;amp;&amp;amp; ( logisches &amp;quot;und&amp;quot;), || (logisches &amp;quot;oder&amp;quot;) und ! (logisches &amp;quot;nicht&amp;quot;) (es gibt noch weitere, auf die hier nicht eingegangen wird). &lt;br /&gt;
&lt;br /&gt;
 b1= b2 &amp;amp;&amp;amp; b3;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der Wert von b1 ist dann 1 (TRUE), wenn b2 und (&amp;quot;AND&amp;quot;) b3 1 (TRUE) sind. Ist eine der beiden (oder auch beide) 0 (FALSE), dann ist b1 ebenfalls 0 (FALSE).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 b1= b2 || b3;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der Wert von b1 ist dann TRUE, wenn b2 oder (&amp;quot;OR&amp;quot;) b3 TRUE ist. Ist also einer (oder beide) TRUE, dann ist auch b1 TRUE, sind beide FALSE, ist auch b1 FALSE.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 b1= !b2;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der Wert von b1 ist dann TRUE, wenn der von b2 FALSE ist. Die NOT Verknüpfung &amp;quot;dreht den logischen Wert der Variablen um&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Anweisung==&lt;br /&gt;
Syntax: IF (Bedingung) Anweisung;&lt;br /&gt;
Mit Hilfe der IF Anweisung kann man Codeteile (Blöcke) ausführen lassen, wenn die dazugehörige Bedingung erfüllt (TRUE) ist. Im Flussdiagramm sieht eine If-Anweisung folgendermassen aus:&lt;br /&gt;
&lt;br /&gt;
[[bild:ifthenelse.png]]&lt;br /&gt;
&lt;br /&gt;
Und in C schreibt man:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if (Bedingung)        /* WENN */&lt;br /&gt;
{                     /* DANN */&lt;br /&gt;
       Anweisung1;&lt;br /&gt;
       Anweisung2;&lt;br /&gt;
       ...&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{                     /* SONST */&lt;br /&gt;
       Anweisung3;&lt;br /&gt;
       Anweisung4;&lt;br /&gt;
       ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wenn die Bedingung wahr ist wird Anweisung1 ausgeführt. Anschliessend wird aus der If-Bedingung herausgesprungen. Anweisung2 wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung unwahr wird gleich zu Anweisung2 gesprungen, diese ausgeführt, und anschliessend wird die If-Bedingung beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Ein häufiger Fehler ist statt if(a == 23) etwas wie if(a = 23) zu schreiben. Hier wird allerdings nicht geprüft ob die Variable a gleich 23 ist, sondern der Variable a wird der Wert 23 zugewiesen, und das ist eine wahre Aussage. Anschliessend wird demzufolge der &amp;quot;DANN&amp;quot;-Teil ausgeführt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken. Somit ist dieser kleine Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise if(23 == a). Wenn man dort anstatt des Vergleichsoperator '==' den Zuweisungsoperator '=' verwendet spuckt der Compiler sehr wohl einen Fehler aus.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist das schreiben von if(Bedingung)''';''' Richtig müsste es heissen &amp;quot;if(Bedingung)&amp;quot; Das fehlerhafte Semikolon im ersten Fall interpretiert der Compiler bereits als Anweisung. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt. Hier also ebenfalls besser zweimal hinschauen.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;-Anweisung==&lt;br /&gt;
Syntax: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
switch(ausdruck) {&lt;br /&gt;
    case wert1:&lt;br /&gt;
        Anweisungen1...&lt;br /&gt;
    case wert2:&lt;br /&gt;
        Anweisungen2...&lt;br /&gt;
    case wert3:&lt;br /&gt;
        Anweisungen3...&lt;br /&gt;
    ...&lt;br /&gt;
    default:&lt;br /&gt;
        Anweisungen4...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der &amp;lt;tt&amp;gt;ausdruck&amp;lt;/tt&amp;gt; muss eine Ganzzahl (int) ergeben und wird dann der Reihe nach mit den Werten, die hinter&lt;br /&gt;
den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Anweisungen angegeben sind verglichen. Bei einer Übereinstimmung werden alle Befehle ab der&lt;br /&gt;
zutreffenden Case-Anweisung ausgeführt. Stimmt der &amp;lt;tt&amp;gt;ausdruck&amp;lt;/tt&amp;gt; mit keinem der Werte hinter &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;&lt;br /&gt;
überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der folgenden &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 eines&lt;br /&gt;
&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, muss aber nach allen &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitten angegeben werden,&lt;br /&gt;
wenn er verwendet wird.&lt;br /&gt;
&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;
===&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;-Schleife===&lt;br /&gt;
'''Syntax:''' while (Bedingung) { Anweisung; }&lt;br /&gt;
&lt;br /&gt;
Die WHILE-Schleife wird solange durchlaufen, wie die Bedingung erfüllt (TRUE) ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Bei mehreren Anweisungen benötigen man einen Block! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Zahl1=0;&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;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife 3 mal durchlaufen. Zu Beginn des 4. Durchlaufes ist die Bedingung FALSE (Zahl1 ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
===&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;-Schleife===&lt;br /&gt;
'''Syntax:''' do  { Anweisung; }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. Das ist dann sinnvoll, wenn der Vergleichswert für die Bedingung erst im Anweisungsblock gesetzt wird &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int i=2;&lt;br /&gt;
do &lt;br /&gt;
{&lt;br /&gt;
    i = i*i;   /* 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;
&amp;lt;/pre&amp;gt;&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.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;-Schleife===&lt;br /&gt;
'''Syntax:''' for (Zuweisung;Bedingung;Inkrement) { Anweisung; }&lt;br /&gt;
&lt;br /&gt;
Die FOR-Schleife ist eine spezielle WHILE-Variante für die Formulierung von Zählschleifen. Die angegebene Variable wird am Anfang auf einen Wert gesetzt. Danach wird sie nach jedem Durchlauf verändert (meist um 1 erhöht). Ist die Bedingung nicht mehr erfüllt, wird die Schleife beendet. Innerhalb des Anweisungsblockes können Sie auf die Variable zugreifen, d.h. Sie können sie auch verändern. Das ist jedoch nicht ratsam. Wollen Sie mehrere Anweisungen ausführen, benötigen Sie eine Block.&lt;br /&gt;
&lt;br /&gt;
Die gesammte Schleife wird solange durchgeführt, wie die Bedingung wahr ist (d.h. Sie brauchen garnicht die Zählvariable abfragen, Sie können hier auch jede andere Variable auswerten). Inkrement letztendlich wird nach jedem Schleifendurchlauf ausgeführt. Hier kann man z.B. den Zähler erhöhen.&lt;br /&gt;
&lt;br /&gt;
Die Theorie ist schwer, die Praxis nicht so sehr. In der Schleife wird die Summe ungerader Zahlen kleinergleich 10 berechnet. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int lauf;&lt;br /&gt;
int summe = 0;&lt;br /&gt;
&lt;br /&gt;
for (lauf = 1; lauf &amp;lt;= 10; lauf = lauf+2 ) &lt;br /&gt;
{&lt;br /&gt;
   summe = summe + lauf;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Das Äquivalent als &amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;-Schleife:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int lauf  = 1;                 /* Anfangswerte */&lt;br /&gt;
int summe = 0;&lt;br /&gt;
&lt;br /&gt;
while (lauf &amp;lt;= 10)             /* Bedingung */&lt;br /&gt;
{&lt;br /&gt;
   summe = summe + lauf;&lt;br /&gt;
   lauf += 2;                  /* Inkrement */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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 1 bis 10 hat, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von 1 bis kleinergleich 10 gespeichert.&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 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 = 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;
=Ein- und Ausgabe=&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;
&lt;br /&gt;
=Allgemeines zu Unterprogrammen=&lt;br /&gt;
Stellen Sie sich vor, Sie haben einen eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben (was Zeit beim Erstellen und Speicherplatz im ausführbaren Programm kostet), können Sie den Abschnitt in ein sogenanntes &amp;quot;Unterprogramm&amp;quot; schreiben. Dieses Unterprogramm können Sie dann von jeder Stelle ihre Hauptprogrammes aus aufrufen.&lt;br /&gt;
Anders als in anderen Programmiersprachen gibt es in C keine generelle Unterscheidung zwischen Funktionen und Prozeduren. Trotzdem möchte ich kurz darauf eingehen: &lt;br /&gt;
&lt;br /&gt;
==Funktionen==&lt;br /&gt;
'''Syntax:''' Rückgabe-Typ Name(Parameterliste);&lt;br /&gt;
&lt;br /&gt;
Funktionen sind Unterprogramme, die am Ende der Ausführung einen Wert zurückliefern, wie z.B. getch. Paradebeispiele für die Anwendung einer Funktion sind jedoch mathematische Formeln: &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 hoch2 (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 (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, 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;zahl1);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = hoch2 (zahl1);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;,zahl1, ergebnis);&lt;br /&gt;
  printf (&amp;quot;5 hoch 2 = %d\n&amp;quot;, hoch2(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;
'''Bemerkungen zum Programm:''' &lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur außerhalb von Blöcken. Siehe auch Prototypen. &lt;br /&gt;
Geschachtelte-Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
In der Deklaration der Funktion kommt zuerst der Rückgabe-Datentyp. Jede Funktion liefert einen Wert zurück, dieser Datentyp gibt den Typ der Variablen an. Danach folgt der Name der Funktion (case-sensitiv!). Dann kommt in Klammern die Parameter-Liste. Dabei handelt es sich um eine Liste von Parametern, die jeweils durch Typ und Name angegeben werden und mittels Komma voneinander getrennt werden.&lt;br /&gt;
Im Block der Funktion können lokale Variablen definiert werden und alle Anweisungen ausgeführt werden. &lt;br /&gt;
Am Ende der Funktion muß diese ordnungsgemäß beendet werden. Dies geschieht mittels der Anweisung &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; und dem Rückgabewert. &lt;br /&gt;
Um eine Funktion aufzurufen (aus einem anderen Unterprogramm oder main), geben Sie folgendes an&lt;br /&gt;
 variable = Funktion (Parameter);&lt;br /&gt;
 Bei Variable muß es sich jedoch nicht unbedingt um eine von Ihnen deklarierte Variable handeln. Es kann z.B. auch der Parameter für ein weiteres Unterprogramm sein (wie im Beispiel, letzte Zeile). &lt;br /&gt;
Die Einrückungen der Anweisungen innerhalb der Funktion nach rechts ist nicht notwendig, sie dient jedoch der Übersicht und ist sehr empfehlenswert.&lt;br /&gt;
&lt;br /&gt;
==Prozedur==&lt;br /&gt;
'''Syntax:''' &amp;lt;tt&amp;gt;void Name (Parameterliste)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Prozedur ist nichts anderes als eine Funktion mit dem speziellen  Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der kennzeichnet, daß die Funktion keinen Wert zurückliefert. Sie ist daher prinzipiell gleich aufgebaut wie eine Funktion, bis auf die folgenden Unterschiede: &lt;br /&gt;
&lt;br /&gt;
Als Rückgabe-Datentyp wird &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; angegeben. &lt;br /&gt;
Einer Variablen kann daher nicht der Rückgabewert einer &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion zugewiesen werden, da diese garkeinen Rückgabewert liefert.&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 param1)&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Der Wert der Variablen ist: %d\n&amp;quot;, param1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
   int zahl1 = 4;&lt;br /&gt;
   &lt;br /&gt;
   ausgeben (23);&lt;br /&gt;
   ausgeben (zahl1);&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;
'''Bemerkungen zum Programm:''' &lt;br /&gt;
Durch den Befehl &amp;quot;&amp;lt;tt&amp;gt;ausgeben(23)&amp;lt;/tt&amp;gt;&amp;quot; wird die Prozedur &amp;quot;&amp;lt;tt&amp;gt;ausgeben&amp;lt;/tt&amp;gt;&amp;quot; mit dem Parameter &amp;lt;tt&amp;gt;23&amp;lt;/tt&amp;gt; aufgerufen. &amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt; hat also den Wert &amp;lt;tt&amp;gt;23&amp;lt;/tt&amp;gt;. Die einzige Anweisung innerhalb der Prozedur ist &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;, was nun ausgeführt wird. &lt;br /&gt;
Der zweite Aufruf von &amp;lt;tt&amp;gt;ausgeben&amp;lt;/tt&amp;gt; erfolgt mit dem Parameter &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, also wird &amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt; der Wert 4 zugewiesen. Dieser wird nun wieder mittels &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; ausgeben. &lt;br /&gt;
&lt;br /&gt;
Unterprogramme ohne Parameter&lt;br /&gt;
Das ist ihnen sicherlich schon aufgefallen: Viele Unterprogramme, haben statt einer Parameterliste nur &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; stehen. Das &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; bedeutet &amp;quot;die Funktion erhält keine Parameter&amp;quot;. &amp;quot;&amp;lt;tt&amp;gt;void main (void)&amp;lt;/tt&amp;gt;&amp;quot; bedeutet also: &amp;quot;Erstelle ein Unterprogramm Namens &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keinen Rückgabewert und keine Parameter hat&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen Sie beim Aufruf trotzdem die Klammern angeben. Beispiel für eine parameterlose Funktion &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 foo();&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;
&lt;br /&gt;
Beispiele:&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;
   /* a ist immer noch 0 */&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;
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 x übergeben. Dass dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void erhoehe (int *x)&lt;br /&gt;
{&lt;br /&gt;
   /* erhöhe 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;
   /* a ist jetzt 1 */&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;
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 Operator &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&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&lt;br /&gt;
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&lt;br /&gt;
den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;
  /* a hat jetzt folgenden Inhalt: 11, 23, 35 */&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;
&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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* 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;
  /* a hat jetzt folgenden Inhalt: 11, 23, 35 */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;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;
=Standard-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;
&lt;br /&gt;
&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;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der Computer 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 scanf - da übergeben Sie ja auch die Adresse einer Variablen (&amp;quot;&amp;amp;Variable&amp;quot;). &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 = *zeiger+1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main (void)&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;
==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: &amp;quot;dir *.exe&amp;quot;, &amp;quot;copy *.* a:&amp;quot; oder &amp;quot;ls -la&amp;quot;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;&amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen! &lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
&lt;br /&gt;
* [[#Speicherklassen|auto]]&lt;br /&gt;
* break&lt;br /&gt;
* [[#Elementare Datentypen|double]]&lt;br /&gt;
* [[#Elementare Datentypen|char]]&lt;br /&gt;
* case&lt;br /&gt;
* [[#Konstanten|const]]&lt;br /&gt;
* continue&lt;br /&gt;
* default&lt;br /&gt;
* do&lt;br /&gt;
* else&lt;br /&gt;
* enum&lt;br /&gt;
* [[#Speicherklassen|extern]]&lt;br /&gt;
* [[#Elementare Datentypen|float]]&lt;br /&gt;
* for&lt;br /&gt;
* goto&lt;br /&gt;
* if&lt;br /&gt;
* [[##Elementare Datentypen|int]]&lt;br /&gt;
* [[#Elementare Datentypen|long]]&lt;br /&gt;
* return&lt;br /&gt;
* [[#Speicherklassen|register]]&lt;br /&gt;
* [[#Elementare Datentypen|short]]&lt;br /&gt;
* signed&lt;br /&gt;
* sizeof&lt;br /&gt;
* [[#Speicherklassen|static]]&lt;br /&gt;
* [[#Strukturen|struct]]&lt;br /&gt;
* switch&lt;br /&gt;
* typedef&lt;br /&gt;
* [[#Unions|union]]&lt;br /&gt;
* unsigned&lt;br /&gt;
* [[#Elementare Datentypen|void]]&lt;br /&gt;
* volatile&lt;br /&gt;
* while&lt;br /&gt;
&lt;br /&gt;
Baustelle&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
Baustelle&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung || Nebeneffekte&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; == &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; != &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || ist nicht gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;lt; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;lt;= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;gt; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;gt;= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;amp; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; = &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; += &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; -= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; *= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; /= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; ^= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; |= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++ &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; ++&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-- &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; --&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;&amp;amp; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~ &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;! &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;(&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/font&amp;gt;) &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; + &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; - &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; * &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; / &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; % &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; %= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;(&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Bedingung&amp;gt;&amp;lt;/font&amp;gt;) ? &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; : &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Struct&amp;gt;&amp;lt;/font&amp;gt;.&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Komponenten-Bezeichner&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Zeiger-auf-Struct&amp;gt;&amp;lt;/font&amp;gt;-&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Komponenten-Bezeichner&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Autoren'''&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
* Kernighan und Ritchie - Buch&lt;br /&gt;
* Christian Wirth , C Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://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>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=8127</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=8127"/>
				<updated>2006-07-05T11:53:23Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Strings (Zeichenketten) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ein kurzer Einblick in die Programmiersprache C&lt;br /&gt;
=Allgemeines=&lt;br /&gt;
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 Sprachedefinition entwickelt. C ist mittlerweile von ANSI und ISO standardisiert.&lt;br /&gt;
Heutzutage ist C (und ihr Nachfolger C++) die dominierende Programmiersprache. Sehr viele Anwendungen sind in C geschrieben. Leider ist C jedoch nicht einfach zu lernen, daher eignet es sich nur bedingt für Anfänger. Mit etwas Übung kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
C ist sehr eng an Assembler angelehnt, aber trotzdem Hardware-unabhängig. Das bedeutet, Sie können maschinennahe Programme sehr leicht (aber nicht ganz ohne Aufwand) auf ein anderes System portieren. Sie benötigen dazu 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;
&amp;lt;pre&amp;gt;&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;
   /* Anweisungen */&lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Beschreibung (die Erklärungen folgen): &lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndahs; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* &lt;br /&gt;
 * void Definition von main ist nur beim Controller üblich&lt;br /&gt;
 * spezielle Compilereinstellungen sind nötig, damit bei dieser Definition von main&lt;br /&gt;
 * kein Fehler/Warnung erzeugt wird. &lt;br /&gt;
 */&lt;br /&gt;
void main (void)&lt;br /&gt;
{&lt;br /&gt;
   ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{    /* der Block &amp;quot;main&amp;quot; beginnt */&lt;br /&gt;
   int zahl;&lt;br /&gt;
   &lt;br /&gt;
   {   /* ein Block beginnt */&lt;br /&gt;
       /* hier können Deklarationen und Anweisungen stehen */&lt;br /&gt;
   }   /* der Block endet */&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}    /* &amp;quot;main&amp;quot; endet */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Bemerkung:''' &lt;br /&gt;
Der &amp;quot;namenlose&amp;quot; Block ist eigentlich unnötig. In den folgenden Kapiteln lernen Sie jedoch bessere Beispiele kennen!&lt;br /&gt;
&lt;br /&gt;
=Datentypen=&lt;br /&gt;
==Elementare Datentypen==&lt;br /&gt;
Der Datentyp einer Variable gibt an, welche Werte eine Variable enthalten kann, welcher Art diese Daten sind und wie sie verarbeitet werden, etwa in arithmetischen Operationen wie einer Addition. So ist es zum Beispiel möglich, in eine Variable vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ganze Zahlen zwischen ca. -32000 und +32000 einzutragen. In einer char-Variable können ASCII-Zeichen gespeichert werden (alles, was Sie mit der Tastatur erzeugen können) oder ganze Zahlen von -128 bis 127.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da C plattformabhängig ist, hängt die Größe eines Datentypes zum Teil von der genutzten Hardware (z.B. 8, 16 oder 32 Bit-Controller) und dem Compiler und dessen Einstellungen ab!&lt;br /&gt;
&lt;br /&gt;
===int, char, short, long (ganze Zahlen)===&lt;br /&gt;
In Variable dieser Typen können Sie ganze Zahlen abspeichern, also z.B. 1, &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;2, 100, 12345. Jeden dieser Typen gibt es in zwei Ausprägungen: als &amp;quot;&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;quot;, also als vorzeichenbehafteten Typ, und als &amp;quot;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&amp;quot;, also ohne Vorzeichen, d.h. das Vorzeichen wird als 0 oder +1 genommen. &lt;br /&gt;
&lt;br /&gt;
Vorzeichenbehaftete Ganzzahl-Typen werden intern im &amp;lt;tt&amp;gt;n-1&amp;lt;/tt&amp;gt;-Komplement dargestellt, das Vorzeichen selbst findet sich also im höchstwertigen Bit. Werden zur Speicherung ''b'' Bits verwendet, dann reicht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;*zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==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:''' Datentyp Variablenname[Anzahl]&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 3 Variablen. Da der Index immer bei 0 beginnt, greift man also mit [0], [1] und [2] 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;
&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 i;&lt;br /&gt;
  int zahlen[10];  /* zahlen[0] bis zahlen[9] !!! */&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;10; 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;
  printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  for (i=0; i&amp;lt;10; 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;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Bemerkungen:''' &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;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
Wenn Sie einen ungültigen Index angeben (einen, der in der Deklaration nicht enthalten war) können je nach Compiler und Einstellung undefinierbare Dinge passieren, da dadurch andere Variableninhalte oder Programmcode überschrieben wird. Im schlimmsten Fall könnte sogar der Computer/Controller abstürzen. Also achten Sie darauf, daß Sie keine ungültigen Werte als Index angeben!&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ötigen 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;
&amp;lt;pre&amp;gt;&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;
&amp;lt;/pre&amp;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 vier Komponenten angelege: 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 dieses Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach &lt;br /&gt;
 struct Person Variablenname;&lt;br /&gt;
an. &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;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  struct Person hubert, klaus;&lt;br /&gt;
&lt;br /&gt;
  hubert.alter = 32;&lt;br /&gt;
  klaus.alter = hubert.alter + 1;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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 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 Person u_person;&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_double&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Groß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.&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 chat 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.&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;
/* nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform) */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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;
Teilweise erlauben C-Compiler auch die Verwendung des Dollar-Zeichens &amp;lt;tt&amp;gt;'''$'''&amp;lt;/tt&amp;gt; in Variablennaben.&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;
&amp;lt;pre&amp;gt;&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;
  /* Anweisungen */&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
;Erklärung: 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;wahr&amp;quot;, ansonsten ist sie &amp;quot;unwahr&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;
==Vergleich von Variablen==&lt;br /&gt;
Sie können Variablen miteinander vergleichen. Das geschieht mit einem der folgenden Zeichen mit den normalen mathematischen Regeln: &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;
Als Ergebnis bekommen Sie einen logischen Ausdruck in Form einer int-Zahl. &lt;br /&gt;
 intVariable = zahl1 &amp;lt;= zahl2;&lt;br /&gt;
das komplette Beispiel zeigt es deutlicher:&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;= z1  /* Ein Vergleich. Die int-Variable i wird wahr, da z1 kleiner als z2 */&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Ergebnis: %d\n&amp;quot;, i);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich 0 (&amp;quot;wahr&amp;quot;), wenn z1 kleiner oder gleich z2 ist. Ist z1 jedoch größer als z2, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich 0 (&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 dafür ein Schlüsselwort in C:&lt;br /&gt;
 const ''datentyp'' name = value;  /* 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;  /* 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;. 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 Eigenheit 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, wenn das Ergebnis bereits feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
  (x &amp;gt; 5) || datei_auf_festplatte_gefunden(&amp;quot;hallo.txt&amp;quot;) /* gut */&lt;br /&gt;
  datei_auf_festplatte_gefunden(&amp;quot;hallo.txt&amp;quot;) || (x &amp;gt; 5) /* nicht so gut */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;datei_auf_festplatte_gefunden&amp;lt;/tt&amp;gt; ist fiktiv und steht für eine Funktion,&lt;br /&gt;
die eine aufwändige Operation durchführt.&lt;br /&gt;
Beide Zeilen ergeben &amp;lt;tt&amp;gt;wahr&amp;lt;/tt&amp;gt; wenn die Variable x einen Wert größer 5 hat oder&lt;br /&gt;
es eine Datei namens &amp;lt;tt&amp;gt;hallo.txt&amp;lt;/tt&amp;gt; auf der Festplatte gibt.&lt;br /&gt;
&lt;br /&gt;
Wo ist also der Unterschied?&amp;lt;br&amp;gt;&lt;br /&gt;
In der ersten Zeile wird geprüft, ob x größer als 5 ist und wenn das der Fall ist,&lt;br /&gt;
dann wird ''nicht mehr geprüft'', ob &amp;lt;tt&amp;gt;hallo.txt&amp;lt;/tt&amp;gt; auf der Festplatte existiert.&lt;br /&gt;
In der zweiten Zeile wird ''immer geprüft'', ob &amp;lt;tt&amp;gt;hallo.txt&amp;lt;/tt&amp;gt; auf der Festplatte&lt;br /&gt;
existiert und erst, wenn sie nicht gefunden wird, wird die Variable x ausgewertet.&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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  int x = 5;    /* x ist eine Integervariable und hat den Wert 5 */&lt;br /&gt;
&lt;br /&gt;
  /* z ist ein Zeiger auf eine Integervariable und enthält somit&lt;br /&gt;
     die Speicheradresse einer Integervariablen&lt;br /&gt;
  */&lt;br /&gt;
  int *z;       &lt;br /&gt;
&lt;br /&gt;
  /* Verwendung des Adressoperators... */&lt;br /&gt;
  z = &amp;amp;x;       /* weise z die Speicheradresse von x zu */&lt;br /&gt;
&lt;br /&gt;
  /* Verwendung der Dereferenzierung */&lt;br /&gt;
  /* erhöhe den Wert, der bei Adresse z steht um eins */&lt;br /&gt;
  *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
  /* da z auf x zeigt, hat auch x jetzt den Wert 6 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff&lt;br /&gt;
auf ein Element 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;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&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&lt;br /&gt;
auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu&lt;br /&gt;
einer Änderung '''irgendeiner''' Speicherstelle:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   int *z; /* z ist ein Zeiger auf einen Integer */&lt;br /&gt;
&lt;br /&gt;
   /* An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.&lt;br /&gt;
      z enthält irgendeine(!) Adresse&lt;br /&gt;
   */&lt;br /&gt;
&lt;br /&gt;
   /* &amp;quot;Erhöhe einen Integer irgendwo im Speicher um 1&amp;quot; -&amp;gt; CRASH */&lt;br /&gt;
   *z = *z + 1;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler (z.B. gcc) erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
}}&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'' durch, sondern unterdrückt nur die Compilerwarnungen oder&lt;br /&gt;
-fehler, die bei einer &amp;quot;verdächtigen&amp;quot; Umwandlung passieren. Er kann also nicht benutzt werden, um einen Text in&lt;br /&gt;
eine Zahl oder umgekehrt zu wandeln:&lt;br /&gt;
&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;
&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Speicheradresse, an der der Text &amp;quot;5.6&amp;quot; beginnt. Der Cast-Operator&lt;br /&gt;
unterdrückt nur die Warnung, die auf den Fehler hinweisen will.&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;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Bedingte Zuweisung===&lt;br /&gt;
 lvalue = (bediungung) ? if-ausdruck : else-ausdruck;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Kein ANSI-C&lt;br /&gt;
--[[Benutzer:SprinterSB|SprinterSB]] 17:15, 29. Jun 2006 (CEST)&lt;br /&gt;
==Blöcke==&lt;br /&gt;
Selbst Blöcke haben in C einen Wert, der in einer Berechnung verwendet werden kann.&lt;br /&gt;
Der Wert eines Blockes ist der Wert der letzten Anweisung des Blocks. &lt;br /&gt;
Der Block muss un runden Klammern stehen:&lt;br /&gt;
 int sum;&lt;br /&gt;
 sum = ({&lt;br /&gt;
    int i, s = 0;&lt;br /&gt;
    for (i=1; i&amp;lt;= 100; i++)&lt;br /&gt;
       s += i;&lt;br /&gt;
    s;&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Makro &amp;lt;tt&amp;gt;PSTR&amp;lt;/tt&amp;gt; von avr-gcc, &lt;br /&gt;
das einen String ins Flash legt und die Adresse zurückliefert, was nur in einer&lt;br /&gt;
Instruktion nicht machbar wäre:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define PSTR(s)                         \&lt;br /&gt;
  ({                                    \ &lt;br /&gt;
      static char __c[] PROGMEM = (s);  \&lt;br /&gt;
      __c;                              \&lt;br /&gt;
  })&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
==Boolsche Logik==&lt;br /&gt;
Boolean-Variablen können miteinander verknüpft werden. Dies geschieht mit den boolschen Operatoren &amp;amp;&amp;amp; ( logisches &amp;quot;und&amp;quot;), || (logisches &amp;quot;oder&amp;quot;) und ! (logisches &amp;quot;nicht&amp;quot;) (es gibt noch weitere, auf die hier nicht eingegangen wird). &lt;br /&gt;
&lt;br /&gt;
 b1= b2 &amp;amp;&amp;amp; b3;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der Wert von b1 ist dann 1 (TRUE), wenn b2 und (&amp;quot;AND&amp;quot;) b3 1 (TRUE) sind. Ist eine der beiden (oder auch beide) 0 (FALSE), dann ist b1 ebenfalls 0 (FALSE).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 b1= b2 || b3;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der Wert von b1 ist dann TRUE, wenn b2 oder (&amp;quot;OR&amp;quot;) b3 TRUE ist. Ist also einer (oder beide) TRUE, dann ist auch b1 TRUE, sind beide FALSE, ist auch b1 FALSE.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 b1= !b2;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der Wert von b1 ist dann TRUE, wenn der von b2 FALSE ist. Die NOT Verknüpfung &amp;quot;dreht den logischen Wert der Variablen um&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Anweisung==&lt;br /&gt;
Syntax: IF (Bedingung) Anweisung;&lt;br /&gt;
Mit Hilfe der IF Anweisung kann man Codeteile (Blöcke) ausführen lassen, wenn die dazugehörige Bedingung erfüllt (TRUE) ist. Im Flussdiagramm sieht eine If-Anweisung folgendermassen aus:&lt;br /&gt;
&lt;br /&gt;
[[bild:ifthenelse.png]]&lt;br /&gt;
&lt;br /&gt;
Und in C schreibt man:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if (Bedingung)        /* WENN */&lt;br /&gt;
{                     /* DANN */&lt;br /&gt;
       Anweisung1;&lt;br /&gt;
       Anweisung2;&lt;br /&gt;
       ...&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{                     /* SONST */&lt;br /&gt;
       Anweisung3;&lt;br /&gt;
       Anweisung4;&lt;br /&gt;
       ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wenn die Bedingung wahr ist wird Anweisung1 ausgeführt. Anschliessend wird aus der If-Bedingung herausgesprungen. Anweisung2 wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung unwahr wird gleich zu Anweisung2 gesprungen, diese ausgeführt, und anschliessend wird die If-Bedingung beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Ein häufiger Fehler ist statt if(a == 23) etwas wie if(a = 23) zu schreiben. Hier wird allerdings nicht geprüft ob die Variable a gleich 23 ist, sondern der Variable a wird der Wert 23 zugewiesen, und das ist eine wahre Aussage. Anschliessend wird demzufolge der &amp;quot;DANN&amp;quot;-Teil ausgeführt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken. Somit ist dieser kleine Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise if(23 == a). Wenn man dort anstatt des Vergleichsoperator '==' den Zuweisungsoperator '=' verwendet spuckt der Compiler sehr wohl einen Fehler aus.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist das schreiben von if(Bedingung)''';''' Richtig müsste es heissen &amp;quot;if(Bedingung)&amp;quot; Das fehlerhafte Semikolon im ersten Fall interpretiert der Compiler bereits als Anweisung. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt. Hier also ebenfalls besser zweimal hinschauen.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;-Anweisung==&lt;br /&gt;
Syntax: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
switch(ausdruck) {&lt;br /&gt;
    case wert1:&lt;br /&gt;
        Anweisungen1...&lt;br /&gt;
    case wert2:&lt;br /&gt;
        Anweisungen2...&lt;br /&gt;
    case wert3:&lt;br /&gt;
        Anweisungen3...&lt;br /&gt;
    ...&lt;br /&gt;
    default:&lt;br /&gt;
        Anweisungen4...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der &amp;lt;tt&amp;gt;ausdruck&amp;lt;/tt&amp;gt; muss eine Ganzzahl (int) ergeben und wird dann der Reihe nach mit den Werten, die hinter&lt;br /&gt;
den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Anweisungen angegeben sind verglichen. Bei einer Übereinstimmung werden alle Befehle ab der&lt;br /&gt;
zutreffenden Case-Anweisung ausgeführt. Stimmt der &amp;lt;tt&amp;gt;ausdruck&amp;lt;/tt&amp;gt; mit keinem der Werte hinter &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;&lt;br /&gt;
überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der folgenden &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 eines&lt;br /&gt;
&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, muss aber nach allen &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitten angegeben werden,&lt;br /&gt;
wenn er verwendet wird.&lt;br /&gt;
&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;
===&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;-Schleife===&lt;br /&gt;
'''Syntax:''' while (Bedingung) { Anweisung; }&lt;br /&gt;
&lt;br /&gt;
Die WHILE-Schleife wird solange durchlaufen, wie die Bedingung erfüllt (TRUE) ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Bei mehreren Anweisungen benötigen man einen Block! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Zahl1=0;&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;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife 3 mal durchlaufen. Zu Beginn des 4. Durchlaufes ist die Bedingung FALSE (Zahl1 ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
===&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;-Schleife===&lt;br /&gt;
'''Syntax:''' do  { Anweisung; }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. Das ist dann sinnvoll, wenn der Vergleichswert für die Bedingung erst im Anweisungsblock gesetzt wird &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int i=2;&lt;br /&gt;
do &lt;br /&gt;
{&lt;br /&gt;
    i = i*i;   /* 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;
&amp;lt;/pre&amp;gt;&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.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;-Schleife===&lt;br /&gt;
'''Syntax:''' for (Zuweisung;Bedingung;Inkrement) { Anweisung; }&lt;br /&gt;
&lt;br /&gt;
Die FOR-Schleife ist eine spezielle WHILE-Variante für die Formulierung von Zählschleifen. Die angegebene Variable wird am Anfang auf einen Wert gesetzt. Danach wird sie nach jedem Durchlauf verändert (meist um 1 erhöht). Ist die Bedingung nicht mehr erfüllt, wird die Schleife beendet. Innerhalb des Anweisungsblockes können Sie auf die Variable zugreifen, d.h. Sie können sie auch verändern. Das ist jedoch nicht ratsam. Wollen Sie mehrere Anweisungen ausführen, benötigen Sie eine Block.&lt;br /&gt;
&lt;br /&gt;
Die gesammte Schleife wird solange durchgeführt, wie die Bedingung wahr ist (d.h. Sie brauchen garnicht die Zählvariable abfragen, Sie können hier auch jede andere Variable auswerten). Inkrement letztendlich wird nach jedem Schleifendurchlauf ausgeführt. Hier kann man z.B. den Zähler erhöhen.&lt;br /&gt;
&lt;br /&gt;
Die Theorie ist schwer, die Praxis nicht so sehr. In der Schleife wird die Summe ungerader Zahlen kleinergleich 10 berechnet. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int lauf;&lt;br /&gt;
int summe = 0;&lt;br /&gt;
&lt;br /&gt;
for (lauf = 1; lauf &amp;lt;= 10; lauf = lauf+2 ) &lt;br /&gt;
{&lt;br /&gt;
   summe = summe + lauf;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Das Äquivalent als &amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;-Schleife:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int lauf  = 1;                 /* Anfangswerte */&lt;br /&gt;
int summe = 0;&lt;br /&gt;
&lt;br /&gt;
while (lauf &amp;lt;= 10)             /* Bedingung */&lt;br /&gt;
{&lt;br /&gt;
   summe = summe + lauf;&lt;br /&gt;
   lauf += 2;                  /* Inkrement */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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 1 bis 10 hat, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von 1 bis kleinergleich 10 gespeichert.&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 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 = 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;
=Ein- und Ausgabe=&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;
&lt;br /&gt;
=Allgemeines zu Unterprogrammen=&lt;br /&gt;
Stellen Sie sich vor, Sie haben einen eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben (was Zeit beim Erstellen und Speicherplatz im ausführbaren Programm kostet), können Sie den Abschnitt in ein sogenanntes &amp;quot;Unterprogramm&amp;quot; schreiben. Dieses Unterprogramm können Sie dann von jeder Stelle ihre Hauptprogrammes aus aufrufen.&lt;br /&gt;
Anders als in anderen Programmiersprachen gibt es in C keine generelle Unterscheidung zwischen Funktionen und Prozeduren. Trotzdem möchte ich kurz darauf eingehen: &lt;br /&gt;
&lt;br /&gt;
==Funktionen==&lt;br /&gt;
'''Syntax:''' Rückgabe-Typ Name(Parameterliste);&lt;br /&gt;
&lt;br /&gt;
Funktionen sind Unterprogramme, die am Ende der Ausführung einen Wert zurückliefern, wie z.B. getch. Paradebeispiele für die Anwendung einer Funktion sind jedoch mathematische Formeln: &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 hoch2 (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 (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, 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;zahl1);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = hoch2 (zahl1);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;,zahl1, ergebnis);&lt;br /&gt;
  printf (&amp;quot;5 hoch 2 = %d\n&amp;quot;, hoch2(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;
'''Bemerkungen zum Programm:''' &lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur außerhalb von Blöcken. Siehe auch Prototypen. &lt;br /&gt;
Geschachtelte-Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
In der Deklaration der Funktion kommt zuerst der Rückgabe-Datentyp. Jede Funktion liefert einen Wert zurück, dieser Datentyp gibt den Typ der Variablen an. Danach folgt der Name der Funktion (case-sensitiv!). Dann kommt in Klammern die Parameter-Liste. Dabei handelt es sich um eine Liste von Parametern, die jeweils durch Typ und Name angegeben werden und mittels Komma voneinander getrennt werden.&lt;br /&gt;
Im Block der Funktion können lokale Variablen definiert werden und alle Anweisungen ausgeführt werden. &lt;br /&gt;
Am Ende der Funktion muß diese ordnungsgemäß beendet werden. Dies geschieht mittels der Anweisung &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; und dem Rückgabewert. &lt;br /&gt;
Um eine Funktion aufzurufen (aus einem anderen Unterprogramm oder main), geben Sie folgendes an&lt;br /&gt;
 variable = Funktion (Parameter);&lt;br /&gt;
 Bei Variable muß es sich jedoch nicht unbedingt um eine von Ihnen deklarierte Variable handeln. Es kann z.B. auch der Parameter für ein weiteres Unterprogramm sein (wie im Beispiel, letzte Zeile). &lt;br /&gt;
Die Einrückungen der Anweisungen innerhalb der Funktion nach rechts ist nicht notwendig, sie dient jedoch der Übersicht und ist sehr empfehlenswert.&lt;br /&gt;
&lt;br /&gt;
==Prozedur==&lt;br /&gt;
'''Syntax:''' &amp;lt;tt&amp;gt;void Name (Parameterliste)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Prozedur ist nichts anderes als eine Funktion mit dem speziellen  Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der kennzeichnet, daß die Funktion keinen Wert zurückliefert. Sie ist daher prinzipiell gleich aufgebaut wie eine Funktion, bis auf die folgenden Unterschiede: &lt;br /&gt;
&lt;br /&gt;
Als Rückgabe-Datentyp wird &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; angegeben. &lt;br /&gt;
Einer Variablen kann daher nicht der Rückgabewert einer &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion zugewiesen werden, da diese garkeinen Rückgabewert liefert.&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 param1)&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Der Wert der Variablen ist: %d\n&amp;quot;, param1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
   int zahl1 = 4;&lt;br /&gt;
   &lt;br /&gt;
   ausgeben (23);&lt;br /&gt;
   ausgeben (zahl1);&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;
'''Bemerkungen zum Programm:''' &lt;br /&gt;
Durch den Befehl &amp;quot;&amp;lt;tt&amp;gt;ausgeben(23)&amp;lt;/tt&amp;gt;&amp;quot; wird die Prozedur &amp;quot;&amp;lt;tt&amp;gt;ausgeben&amp;lt;/tt&amp;gt;&amp;quot; mit dem Parameter &amp;lt;tt&amp;gt;23&amp;lt;/tt&amp;gt; aufgerufen. &amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt; hat also den Wert &amp;lt;tt&amp;gt;23&amp;lt;/tt&amp;gt;. Die einzige Anweisung innerhalb der Prozedur ist &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;, was nun ausgeführt wird. &lt;br /&gt;
Der zweite Aufruf von &amp;lt;tt&amp;gt;ausgeben&amp;lt;/tt&amp;gt; erfolgt mit dem Parameter &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, also wird &amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt; der Wert 4 zugewiesen. Dieser wird nun wieder mittels &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; ausgeben. &lt;br /&gt;
&lt;br /&gt;
Unterprogramme ohne Parameter&lt;br /&gt;
Das ist ihnen sicherlich schon aufgefallen: Viele Unterprogramme, haben statt einer Parameterliste nur &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; stehen. Das &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; bedeutet &amp;quot;die Funktion erhält keine Parameter&amp;quot;. &amp;quot;&amp;lt;tt&amp;gt;void main (void)&amp;lt;/tt&amp;gt;&amp;quot; bedeutet also: &amp;quot;Erstelle ein Unterprogramm Namens &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keinen Rückgabewert und keine Parameter hat&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen Sie beim Aufruf trotzdem die Klammern angeben. Beispiel für eine parameterlose Funktion &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 foo();&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;
&lt;br /&gt;
Beispiele:&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;
   /* a ist immer noch 0 */&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;
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 x übergeben. Dass dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void erhoehe (int *x)&lt;br /&gt;
{&lt;br /&gt;
   /* erhöhe 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;
   /* a ist jetzt 1 */&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;
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 Operator &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&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&lt;br /&gt;
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&lt;br /&gt;
den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;
  /* a hat jetzt folgenden Inhalt: 11, 23, 35 */&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;
&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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* 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;
  /* a hat jetzt folgenden Inhalt: 11, 23, 35 */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;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;
=Standard-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;
&lt;br /&gt;
&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;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der Computer 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 scanf - da übergeben Sie ja auch die Adresse einer Variablen (&amp;quot;&amp;amp;Variable&amp;quot;). &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 = *zeiger+1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main (void)&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;
==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: &amp;quot;dir *.exe&amp;quot;, &amp;quot;copy *.* a:&amp;quot; oder &amp;quot;ls -la&amp;quot;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;&amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen! &lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
&lt;br /&gt;
* [[#Speicherklassen|auto]]&lt;br /&gt;
* break&lt;br /&gt;
* [[#Elementare Datentypen|double]]&lt;br /&gt;
* [[#Elementare Datentypen|char]]&lt;br /&gt;
* case&lt;br /&gt;
* [[#Konstanten|const]]&lt;br /&gt;
* continue&lt;br /&gt;
* default&lt;br /&gt;
* do&lt;br /&gt;
* else&lt;br /&gt;
* enum&lt;br /&gt;
* [[#Speicherklassen|extern]]&lt;br /&gt;
* [[#Elementare Datentypen|float]]&lt;br /&gt;
* for&lt;br /&gt;
* goto&lt;br /&gt;
* if&lt;br /&gt;
* [[##Elementare Datentypen|int]]&lt;br /&gt;
* [[#Elementare Datentypen|long]]&lt;br /&gt;
* return&lt;br /&gt;
* [[#Speicherklassen|register]]&lt;br /&gt;
* [[#Elementare Datentypen|short]]&lt;br /&gt;
* signed&lt;br /&gt;
* sizeof&lt;br /&gt;
* [[#Speicherklassen|static]]&lt;br /&gt;
* [[#Strukturen|struct]]&lt;br /&gt;
* switch&lt;br /&gt;
* typedef&lt;br /&gt;
* [[#Unions|union]]&lt;br /&gt;
* unsigned&lt;br /&gt;
* [[#Elementare Datentypen|void]]&lt;br /&gt;
* volatile&lt;br /&gt;
* while&lt;br /&gt;
&lt;br /&gt;
Baustelle&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
Baustelle&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung || Nebeneffekte&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; == &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; != &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || ist nicht gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;lt; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;lt;= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;gt; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;gt;= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;amp; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; = &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; += &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; -= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; *= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; /= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; ^= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; |= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++ &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; ++&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-- &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; --&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;&amp;amp; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~ &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;! &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;(&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/font&amp;gt;) &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; + &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; - &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; * &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; / &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; % &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; %= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;(&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Bedingung&amp;gt;&amp;lt;/font&amp;gt;) ? &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; : &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Struct&amp;gt;&amp;lt;/font&amp;gt;.&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Komponenten-Bezeichner&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Zeiger-auf-Struct&amp;gt;&amp;lt;/font&amp;gt;-&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Komponenten-Bezeichner&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Autoren'''&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
* Kernighan und Ritchie - Buch&lt;br /&gt;
* Christian Wirth , C Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://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>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=8126</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=8126"/>
				<updated>2006-07-05T11:47:38Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Arrays */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ein kurzer Einblick in die Programmiersprache C&lt;br /&gt;
=Allgemeines=&lt;br /&gt;
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 Sprachedefinition entwickelt. C ist mittlerweile von ANSI und ISO standardisiert.&lt;br /&gt;
Heutzutage ist C (und ihr Nachfolger C++) die dominierende Programmiersprache. Sehr viele Anwendungen sind in C geschrieben. Leider ist C jedoch nicht einfach zu lernen, daher eignet es sich nur bedingt für Anfänger. Mit etwas Übung kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
C ist sehr eng an Assembler angelehnt, aber trotzdem Hardware-unabhängig. Das bedeutet, Sie können maschinennahe Programme sehr leicht (aber nicht ganz ohne Aufwand) auf ein anderes System portieren. Sie benötigen dazu 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;
&amp;lt;pre&amp;gt;&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;
   /* Anweisungen */&lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Beschreibung (die Erklärungen folgen): &lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndahs; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* &lt;br /&gt;
 * void Definition von main ist nur beim Controller üblich&lt;br /&gt;
 * spezielle Compilereinstellungen sind nötig, damit bei dieser Definition von main&lt;br /&gt;
 * kein Fehler/Warnung erzeugt wird. &lt;br /&gt;
 */&lt;br /&gt;
void main (void)&lt;br /&gt;
{&lt;br /&gt;
   ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{    /* der Block &amp;quot;main&amp;quot; beginnt */&lt;br /&gt;
   int zahl;&lt;br /&gt;
   &lt;br /&gt;
   {   /* ein Block beginnt */&lt;br /&gt;
       /* hier können Deklarationen und Anweisungen stehen */&lt;br /&gt;
   }   /* der Block endet */&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}    /* &amp;quot;main&amp;quot; endet */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Bemerkung:''' &lt;br /&gt;
Der &amp;quot;namenlose&amp;quot; Block ist eigentlich unnötig. In den folgenden Kapiteln lernen Sie jedoch bessere Beispiele kennen!&lt;br /&gt;
&lt;br /&gt;
=Datentypen=&lt;br /&gt;
==Elementare Datentypen==&lt;br /&gt;
Der Datentyp einer Variable gibt an, welche Werte eine Variable enthalten kann, welcher Art diese Daten sind und wie sie verarbeitet werden, etwa in arithmetischen Operationen wie einer Addition. So ist es zum Beispiel möglich, in eine Variable vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ganze Zahlen zwischen ca. -32000 und +32000 einzutragen. In einer char-Variable können ASCII-Zeichen gespeichert werden (alles, was Sie mit der Tastatur erzeugen können) oder ganze Zahlen von -128 bis 127.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da C plattformabhängig ist, hängt die Größe eines Datentypes zum Teil von der genutzten Hardware (z.B. 8, 16 oder 32 Bit-Controller) und dem Compiler und dessen Einstellungen ab!&lt;br /&gt;
&lt;br /&gt;
===int, char, short, long (ganze Zahlen)===&lt;br /&gt;
In Variable dieser Typen können Sie ganze Zahlen abspeichern, also z.B. 1, &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;2, 100, 12345. Jeden dieser Typen gibt es in zwei Ausprägungen: als &amp;quot;&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;quot;, also als vorzeichenbehafteten Typ, und als &amp;quot;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&amp;quot;, also ohne Vorzeichen, d.h. das Vorzeichen wird als 0 oder +1 genommen. &lt;br /&gt;
&lt;br /&gt;
Vorzeichenbehaftete Ganzzahl-Typen werden intern im &amp;lt;tt&amp;gt;n-1&amp;lt;/tt&amp;gt;-Komplement dargestellt, das Vorzeichen selbst findet sich also im höchstwertigen Bit. Werden zur Speicherung ''b'' Bits verwendet, dann reicht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;*zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==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:''' Datentyp Variablenname[Anzahl]&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 3 Variablen. Da der Index immer bei 0 beginnt, greift man also mit [0], [1] und [2] 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;
&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 i;&lt;br /&gt;
  int zahlen[10];  /* zahlen[0] bis zahlen[9] !!! */&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;10; 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;
  printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  for (i=0; i&amp;lt;10; 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;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Bemerkungen:''' &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;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
Wenn Sie einen ungültigen Index angeben (einen, der in der Deklaration nicht enthalten war) können je nach Compiler und Einstellung undefinierbare Dinge passieren, da dadurch andere Variableninhalte oder Programmcode überschrieben wird. Im schlimmsten Fall könnte sogar der Computer/Controller abstürzen. Also achten Sie darauf, daß Sie keine ungültigen Werte als Index angeben!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Strings (Zeichenketten)===&lt;br /&gt;
Ein String ist nicht sanderes 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ötigen 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;
&amp;lt;pre&amp;gt;&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;
&amp;lt;/pre&amp;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 vier Komponenten angelege: 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 dieses Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach &lt;br /&gt;
 struct Person Variablenname;&lt;br /&gt;
an. &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;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  struct Person hubert, klaus;&lt;br /&gt;
&lt;br /&gt;
  hubert.alter = 32;&lt;br /&gt;
  klaus.alter = hubert.alter + 1;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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 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 Person u_person;&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_double&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Groß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.&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 chat 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.&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;
/* nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform) */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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;
Teilweise erlauben C-Compiler auch die Verwendung des Dollar-Zeichens &amp;lt;tt&amp;gt;'''$'''&amp;lt;/tt&amp;gt; in Variablennaben.&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;
&amp;lt;pre&amp;gt;&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;
  /* Anweisungen */&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
;Erklärung: 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;wahr&amp;quot;, ansonsten ist sie &amp;quot;unwahr&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;
==Vergleich von Variablen==&lt;br /&gt;
Sie können Variablen miteinander vergleichen. Das geschieht mit einem der folgenden Zeichen mit den normalen mathematischen Regeln: &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;
Als Ergebnis bekommen Sie einen logischen Ausdruck in Form einer int-Zahl. &lt;br /&gt;
 intVariable = zahl1 &amp;lt;= zahl2;&lt;br /&gt;
das komplette Beispiel zeigt es deutlicher:&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;= z1  /* Ein Vergleich. Die int-Variable i wird wahr, da z1 kleiner als z2 */&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Ergebnis: %d\n&amp;quot;, i);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich 0 (&amp;quot;wahr&amp;quot;), wenn z1 kleiner oder gleich z2 ist. Ist z1 jedoch größer als z2, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich 0 (&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 dafür ein Schlüsselwort in C:&lt;br /&gt;
 const ''datentyp'' name = value;  /* 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;  /* 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;. 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 Eigenheit 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, wenn das Ergebnis bereits feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
  (x &amp;gt; 5) || datei_auf_festplatte_gefunden(&amp;quot;hallo.txt&amp;quot;) /* gut */&lt;br /&gt;
  datei_auf_festplatte_gefunden(&amp;quot;hallo.txt&amp;quot;) || (x &amp;gt; 5) /* nicht so gut */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;datei_auf_festplatte_gefunden&amp;lt;/tt&amp;gt; ist fiktiv und steht für eine Funktion,&lt;br /&gt;
die eine aufwändige Operation durchführt.&lt;br /&gt;
Beide Zeilen ergeben &amp;lt;tt&amp;gt;wahr&amp;lt;/tt&amp;gt; wenn die Variable x einen Wert größer 5 hat oder&lt;br /&gt;
es eine Datei namens &amp;lt;tt&amp;gt;hallo.txt&amp;lt;/tt&amp;gt; auf der Festplatte gibt.&lt;br /&gt;
&lt;br /&gt;
Wo ist also der Unterschied?&amp;lt;br&amp;gt;&lt;br /&gt;
In der ersten Zeile wird geprüft, ob x größer als 5 ist und wenn das der Fall ist,&lt;br /&gt;
dann wird ''nicht mehr geprüft'', ob &amp;lt;tt&amp;gt;hallo.txt&amp;lt;/tt&amp;gt; auf der Festplatte existiert.&lt;br /&gt;
In der zweiten Zeile wird ''immer geprüft'', ob &amp;lt;tt&amp;gt;hallo.txt&amp;lt;/tt&amp;gt; auf der Festplatte&lt;br /&gt;
existiert und erst, wenn sie nicht gefunden wird, wird die Variable x ausgewertet.&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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  int x = 5;    /* x ist eine Integervariable und hat den Wert 5 */&lt;br /&gt;
&lt;br /&gt;
  /* z ist ein Zeiger auf eine Integervariable und enthält somit&lt;br /&gt;
     die Speicheradresse einer Integervariablen&lt;br /&gt;
  */&lt;br /&gt;
  int *z;       &lt;br /&gt;
&lt;br /&gt;
  /* Verwendung des Adressoperators... */&lt;br /&gt;
  z = &amp;amp;x;       /* weise z die Speicheradresse von x zu */&lt;br /&gt;
&lt;br /&gt;
  /* Verwendung der Dereferenzierung */&lt;br /&gt;
  /* erhöhe den Wert, der bei Adresse z steht um eins */&lt;br /&gt;
  *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
  /* da z auf x zeigt, hat auch x jetzt den Wert 6 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff&lt;br /&gt;
auf ein Element 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;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&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&lt;br /&gt;
auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu&lt;br /&gt;
einer Änderung '''irgendeiner''' Speicherstelle:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   int *z; /* z ist ein Zeiger auf einen Integer */&lt;br /&gt;
&lt;br /&gt;
   /* An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.&lt;br /&gt;
      z enthält irgendeine(!) Adresse&lt;br /&gt;
   */&lt;br /&gt;
&lt;br /&gt;
   /* &amp;quot;Erhöhe einen Integer irgendwo im Speicher um 1&amp;quot; -&amp;gt; CRASH */&lt;br /&gt;
   *z = *z + 1;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler (z.B. gcc) erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
}}&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'' durch, sondern unterdrückt nur die Compilerwarnungen oder&lt;br /&gt;
-fehler, die bei einer &amp;quot;verdächtigen&amp;quot; Umwandlung passieren. Er kann also nicht benutzt werden, um einen Text in&lt;br /&gt;
eine Zahl oder umgekehrt zu wandeln:&lt;br /&gt;
&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;
&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Speicheradresse, an der der Text &amp;quot;5.6&amp;quot; beginnt. Der Cast-Operator&lt;br /&gt;
unterdrückt nur die Warnung, die auf den Fehler hinweisen will.&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;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Bedingte Zuweisung===&lt;br /&gt;
 lvalue = (bediungung) ? if-ausdruck : else-ausdruck;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Kein ANSI-C&lt;br /&gt;
--[[Benutzer:SprinterSB|SprinterSB]] 17:15, 29. Jun 2006 (CEST)&lt;br /&gt;
==Blöcke==&lt;br /&gt;
Selbst Blöcke haben in C einen Wert, der in einer Berechnung verwendet werden kann.&lt;br /&gt;
Der Wert eines Blockes ist der Wert der letzten Anweisung des Blocks. &lt;br /&gt;
Der Block muss un runden Klammern stehen:&lt;br /&gt;
 int sum;&lt;br /&gt;
 sum = ({&lt;br /&gt;
    int i, s = 0;&lt;br /&gt;
    for (i=1; i&amp;lt;= 100; i++)&lt;br /&gt;
       s += i;&lt;br /&gt;
    s;&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Makro &amp;lt;tt&amp;gt;PSTR&amp;lt;/tt&amp;gt; von avr-gcc, &lt;br /&gt;
das einen String ins Flash legt und die Adresse zurückliefert, was nur in einer&lt;br /&gt;
Instruktion nicht machbar wäre:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define PSTR(s)                         \&lt;br /&gt;
  ({                                    \ &lt;br /&gt;
      static char __c[] PROGMEM = (s);  \&lt;br /&gt;
      __c;                              \&lt;br /&gt;
  })&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
==Boolsche Logik==&lt;br /&gt;
Boolean-Variablen können miteinander verknüpft werden. Dies geschieht mit den boolschen Operatoren &amp;amp;&amp;amp; ( logisches &amp;quot;und&amp;quot;), || (logisches &amp;quot;oder&amp;quot;) und ! (logisches &amp;quot;nicht&amp;quot;) (es gibt noch weitere, auf die hier nicht eingegangen wird). &lt;br /&gt;
&lt;br /&gt;
 b1= b2 &amp;amp;&amp;amp; b3;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der Wert von b1 ist dann 1 (TRUE), wenn b2 und (&amp;quot;AND&amp;quot;) b3 1 (TRUE) sind. Ist eine der beiden (oder auch beide) 0 (FALSE), dann ist b1 ebenfalls 0 (FALSE).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 b1= b2 || b3;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der Wert von b1 ist dann TRUE, wenn b2 oder (&amp;quot;OR&amp;quot;) b3 TRUE ist. Ist also einer (oder beide) TRUE, dann ist auch b1 TRUE, sind beide FALSE, ist auch b1 FALSE.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 b1= !b2;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der Wert von b1 ist dann TRUE, wenn der von b2 FALSE ist. Die NOT Verknüpfung &amp;quot;dreht den logischen Wert der Variablen um&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Anweisung==&lt;br /&gt;
Syntax: IF (Bedingung) Anweisung;&lt;br /&gt;
Mit Hilfe der IF Anweisung kann man Codeteile (Blöcke) ausführen lassen, wenn die dazugehörige Bedingung erfüllt (TRUE) ist. Im Flussdiagramm sieht eine If-Anweisung folgendermassen aus:&lt;br /&gt;
&lt;br /&gt;
[[bild:ifthenelse.png]]&lt;br /&gt;
&lt;br /&gt;
Und in C schreibt man:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if (Bedingung)        /* WENN */&lt;br /&gt;
{                     /* DANN */&lt;br /&gt;
       Anweisung1;&lt;br /&gt;
       Anweisung2;&lt;br /&gt;
       ...&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{                     /* SONST */&lt;br /&gt;
       Anweisung3;&lt;br /&gt;
       Anweisung4;&lt;br /&gt;
       ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wenn die Bedingung wahr ist wird Anweisung1 ausgeführt. Anschliessend wird aus der If-Bedingung herausgesprungen. Anweisung2 wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung unwahr wird gleich zu Anweisung2 gesprungen, diese ausgeführt, und anschliessend wird die If-Bedingung beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Ein häufiger Fehler ist statt if(a == 23) etwas wie if(a = 23) zu schreiben. Hier wird allerdings nicht geprüft ob die Variable a gleich 23 ist, sondern der Variable a wird der Wert 23 zugewiesen, und das ist eine wahre Aussage. Anschliessend wird demzufolge der &amp;quot;DANN&amp;quot;-Teil ausgeführt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken. Somit ist dieser kleine Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise if(23 == a). Wenn man dort anstatt des Vergleichsoperator '==' den Zuweisungsoperator '=' verwendet spuckt der Compiler sehr wohl einen Fehler aus.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist das schreiben von if(Bedingung)''';''' Richtig müsste es heissen &amp;quot;if(Bedingung)&amp;quot; Das fehlerhafte Semikolon im ersten Fall interpretiert der Compiler bereits als Anweisung. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt. Hier also ebenfalls besser zweimal hinschauen.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;-Anweisung==&lt;br /&gt;
Syntax: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
switch(ausdruck) {&lt;br /&gt;
    case wert1:&lt;br /&gt;
        Anweisungen1...&lt;br /&gt;
    case wert2:&lt;br /&gt;
        Anweisungen2...&lt;br /&gt;
    case wert3:&lt;br /&gt;
        Anweisungen3...&lt;br /&gt;
    ...&lt;br /&gt;
    default:&lt;br /&gt;
        Anweisungen4...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der &amp;lt;tt&amp;gt;ausdruck&amp;lt;/tt&amp;gt; muss eine Ganzzahl (int) ergeben und wird dann der Reihe nach mit den Werten, die hinter&lt;br /&gt;
den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Anweisungen angegeben sind verglichen. Bei einer Übereinstimmung werden alle Befehle ab der&lt;br /&gt;
zutreffenden Case-Anweisung ausgeführt. Stimmt der &amp;lt;tt&amp;gt;ausdruck&amp;lt;/tt&amp;gt; mit keinem der Werte hinter &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;&lt;br /&gt;
überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der folgenden &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 eines&lt;br /&gt;
&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, muss aber nach allen &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitten angegeben werden,&lt;br /&gt;
wenn er verwendet wird.&lt;br /&gt;
&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;
===&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;-Schleife===&lt;br /&gt;
'''Syntax:''' while (Bedingung) { Anweisung; }&lt;br /&gt;
&lt;br /&gt;
Die WHILE-Schleife wird solange durchlaufen, wie die Bedingung erfüllt (TRUE) ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Bei mehreren Anweisungen benötigen man einen Block! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Zahl1=0;&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;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife 3 mal durchlaufen. Zu Beginn des 4. Durchlaufes ist die Bedingung FALSE (Zahl1 ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
===&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;-Schleife===&lt;br /&gt;
'''Syntax:''' do  { Anweisung; }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. Das ist dann sinnvoll, wenn der Vergleichswert für die Bedingung erst im Anweisungsblock gesetzt wird &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int i=2;&lt;br /&gt;
do &lt;br /&gt;
{&lt;br /&gt;
    i = i*i;   /* 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;
&amp;lt;/pre&amp;gt;&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.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;-Schleife===&lt;br /&gt;
'''Syntax:''' for (Zuweisung;Bedingung;Inkrement) { Anweisung; }&lt;br /&gt;
&lt;br /&gt;
Die FOR-Schleife ist eine spezielle WHILE-Variante für die Formulierung von Zählschleifen. Die angegebene Variable wird am Anfang auf einen Wert gesetzt. Danach wird sie nach jedem Durchlauf verändert (meist um 1 erhöht). Ist die Bedingung nicht mehr erfüllt, wird die Schleife beendet. Innerhalb des Anweisungsblockes können Sie auf die Variable zugreifen, d.h. Sie können sie auch verändern. Das ist jedoch nicht ratsam. Wollen Sie mehrere Anweisungen ausführen, benötigen Sie eine Block.&lt;br /&gt;
&lt;br /&gt;
Die gesammte Schleife wird solange durchgeführt, wie die Bedingung wahr ist (d.h. Sie brauchen garnicht die Zählvariable abfragen, Sie können hier auch jede andere Variable auswerten). Inkrement letztendlich wird nach jedem Schleifendurchlauf ausgeführt. Hier kann man z.B. den Zähler erhöhen.&lt;br /&gt;
&lt;br /&gt;
Die Theorie ist schwer, die Praxis nicht so sehr. In der Schleife wird die Summe ungerader Zahlen kleinergleich 10 berechnet. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int lauf;&lt;br /&gt;
int summe = 0;&lt;br /&gt;
&lt;br /&gt;
for (lauf = 1; lauf &amp;lt;= 10; lauf = lauf+2 ) &lt;br /&gt;
{&lt;br /&gt;
   summe = summe + lauf;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Das Äquivalent als &amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;-Schleife:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int lauf  = 1;                 /* Anfangswerte */&lt;br /&gt;
int summe = 0;&lt;br /&gt;
&lt;br /&gt;
while (lauf &amp;lt;= 10)             /* Bedingung */&lt;br /&gt;
{&lt;br /&gt;
   summe = summe + lauf;&lt;br /&gt;
   lauf += 2;                  /* Inkrement */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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 1 bis 10 hat, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von 1 bis kleinergleich 10 gespeichert.&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 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 = 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;
=Ein- und Ausgabe=&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;
&lt;br /&gt;
=Allgemeines zu Unterprogrammen=&lt;br /&gt;
Stellen Sie sich vor, Sie haben einen eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben (was Zeit beim Erstellen und Speicherplatz im ausführbaren Programm kostet), können Sie den Abschnitt in ein sogenanntes &amp;quot;Unterprogramm&amp;quot; schreiben. Dieses Unterprogramm können Sie dann von jeder Stelle ihre Hauptprogrammes aus aufrufen.&lt;br /&gt;
Anders als in anderen Programmiersprachen gibt es in C keine generelle Unterscheidung zwischen Funktionen und Prozeduren. Trotzdem möchte ich kurz darauf eingehen: &lt;br /&gt;
&lt;br /&gt;
==Funktionen==&lt;br /&gt;
'''Syntax:''' Rückgabe-Typ Name(Parameterliste);&lt;br /&gt;
&lt;br /&gt;
Funktionen sind Unterprogramme, die am Ende der Ausführung einen Wert zurückliefern, wie z.B. getch. Paradebeispiele für die Anwendung einer Funktion sind jedoch mathematische Formeln: &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 hoch2 (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 (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, 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;zahl1);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = hoch2 (zahl1);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;,zahl1, ergebnis);&lt;br /&gt;
  printf (&amp;quot;5 hoch 2 = %d\n&amp;quot;, hoch2(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;
'''Bemerkungen zum Programm:''' &lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur außerhalb von Blöcken. Siehe auch Prototypen. &lt;br /&gt;
Geschachtelte-Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
In der Deklaration der Funktion kommt zuerst der Rückgabe-Datentyp. Jede Funktion liefert einen Wert zurück, dieser Datentyp gibt den Typ der Variablen an. Danach folgt der Name der Funktion (case-sensitiv!). Dann kommt in Klammern die Parameter-Liste. Dabei handelt es sich um eine Liste von Parametern, die jeweils durch Typ und Name angegeben werden und mittels Komma voneinander getrennt werden.&lt;br /&gt;
Im Block der Funktion können lokale Variablen definiert werden und alle Anweisungen ausgeführt werden. &lt;br /&gt;
Am Ende der Funktion muß diese ordnungsgemäß beendet werden. Dies geschieht mittels der Anweisung &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; und dem Rückgabewert. &lt;br /&gt;
Um eine Funktion aufzurufen (aus einem anderen Unterprogramm oder main), geben Sie folgendes an&lt;br /&gt;
 variable = Funktion (Parameter);&lt;br /&gt;
 Bei Variable muß es sich jedoch nicht unbedingt um eine von Ihnen deklarierte Variable handeln. Es kann z.B. auch der Parameter für ein weiteres Unterprogramm sein (wie im Beispiel, letzte Zeile). &lt;br /&gt;
Die Einrückungen der Anweisungen innerhalb der Funktion nach rechts ist nicht notwendig, sie dient jedoch der Übersicht und ist sehr empfehlenswert.&lt;br /&gt;
&lt;br /&gt;
==Prozedur==&lt;br /&gt;
'''Syntax:''' &amp;lt;tt&amp;gt;void Name (Parameterliste)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Prozedur ist nichts anderes als eine Funktion mit dem speziellen  Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der kennzeichnet, daß die Funktion keinen Wert zurückliefert. Sie ist daher prinzipiell gleich aufgebaut wie eine Funktion, bis auf die folgenden Unterschiede: &lt;br /&gt;
&lt;br /&gt;
Als Rückgabe-Datentyp wird &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; angegeben. &lt;br /&gt;
Einer Variablen kann daher nicht der Rückgabewert einer &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion zugewiesen werden, da diese garkeinen Rückgabewert liefert.&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 param1)&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Der Wert der Variablen ist: %d\n&amp;quot;, param1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
   int zahl1 = 4;&lt;br /&gt;
   &lt;br /&gt;
   ausgeben (23);&lt;br /&gt;
   ausgeben (zahl1);&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;
'''Bemerkungen zum Programm:''' &lt;br /&gt;
Durch den Befehl &amp;quot;&amp;lt;tt&amp;gt;ausgeben(23)&amp;lt;/tt&amp;gt;&amp;quot; wird die Prozedur &amp;quot;&amp;lt;tt&amp;gt;ausgeben&amp;lt;/tt&amp;gt;&amp;quot; mit dem Parameter &amp;lt;tt&amp;gt;23&amp;lt;/tt&amp;gt; aufgerufen. &amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt; hat also den Wert &amp;lt;tt&amp;gt;23&amp;lt;/tt&amp;gt;. Die einzige Anweisung innerhalb der Prozedur ist &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;, was nun ausgeführt wird. &lt;br /&gt;
Der zweite Aufruf von &amp;lt;tt&amp;gt;ausgeben&amp;lt;/tt&amp;gt; erfolgt mit dem Parameter &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, also wird &amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt; der Wert 4 zugewiesen. Dieser wird nun wieder mittels &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; ausgeben. &lt;br /&gt;
&lt;br /&gt;
Unterprogramme ohne Parameter&lt;br /&gt;
Das ist ihnen sicherlich schon aufgefallen: Viele Unterprogramme, haben statt einer Parameterliste nur &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; stehen. Das &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; bedeutet &amp;quot;die Funktion erhält keine Parameter&amp;quot;. &amp;quot;&amp;lt;tt&amp;gt;void main (void)&amp;lt;/tt&amp;gt;&amp;quot; bedeutet also: &amp;quot;Erstelle ein Unterprogramm Namens &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keinen Rückgabewert und keine Parameter hat&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen Sie beim Aufruf trotzdem die Klammern angeben. Beispiel für eine parameterlose Funktion &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 foo();&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;
&lt;br /&gt;
Beispiele:&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;
   /* a ist immer noch 0 */&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;
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 x übergeben. Dass dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void erhoehe (int *x)&lt;br /&gt;
{&lt;br /&gt;
   /* erhöhe 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;
   /* a ist jetzt 1 */&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;
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 Operator &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&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&lt;br /&gt;
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&lt;br /&gt;
den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;
  /* a hat jetzt folgenden Inhalt: 11, 23, 35 */&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;
&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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* 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;
  /* a hat jetzt folgenden Inhalt: 11, 23, 35 */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;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;
=Standard-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;
&lt;br /&gt;
&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;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der Computer 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 scanf - da übergeben Sie ja auch die Adresse einer Variablen (&amp;quot;&amp;amp;Variable&amp;quot;). &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 = *zeiger+1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main (void)&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;
==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: &amp;quot;dir *.exe&amp;quot;, &amp;quot;copy *.* a:&amp;quot; oder &amp;quot;ls -la&amp;quot;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;&amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen! &lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
&lt;br /&gt;
* [[#Speicherklassen|auto]]&lt;br /&gt;
* break&lt;br /&gt;
* [[#Elementare Datentypen|double]]&lt;br /&gt;
* [[#Elementare Datentypen|char]]&lt;br /&gt;
* case&lt;br /&gt;
* [[#Konstanten|const]]&lt;br /&gt;
* continue&lt;br /&gt;
* default&lt;br /&gt;
* do&lt;br /&gt;
* else&lt;br /&gt;
* enum&lt;br /&gt;
* [[#Speicherklassen|extern]]&lt;br /&gt;
* [[#Elementare Datentypen|float]]&lt;br /&gt;
* for&lt;br /&gt;
* goto&lt;br /&gt;
* if&lt;br /&gt;
* [[##Elementare Datentypen|int]]&lt;br /&gt;
* [[#Elementare Datentypen|long]]&lt;br /&gt;
* return&lt;br /&gt;
* [[#Speicherklassen|register]]&lt;br /&gt;
* [[#Elementare Datentypen|short]]&lt;br /&gt;
* signed&lt;br /&gt;
* sizeof&lt;br /&gt;
* [[#Speicherklassen|static]]&lt;br /&gt;
* [[#Strukturen|struct]]&lt;br /&gt;
* switch&lt;br /&gt;
* typedef&lt;br /&gt;
* [[#Unions|union]]&lt;br /&gt;
* unsigned&lt;br /&gt;
* [[#Elementare Datentypen|void]]&lt;br /&gt;
* volatile&lt;br /&gt;
* while&lt;br /&gt;
&lt;br /&gt;
Baustelle&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
Baustelle&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung || Nebeneffekte&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; == &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; != &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || ist nicht gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;lt; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;lt;= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;gt; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;gt;= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;amp; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; = &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; += &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; -= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; *= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; /= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; ^= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; |= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++ &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; ++&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-- &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; --&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;&amp;amp; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~ &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;! &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;(&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/font&amp;gt;) &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; + &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; - &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; * &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; / &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; % &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; %= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;(&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Bedingung&amp;gt;&amp;lt;/font&amp;gt;) ? &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; : &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Struct&amp;gt;&amp;lt;/font&amp;gt;.&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Komponenten-Bezeichner&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Zeiger-auf-Struct&amp;gt;&amp;lt;/font&amp;gt;-&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Komponenten-Bezeichner&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Autoren'''&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
* Kernighan und Ritchie - Buch&lt;br /&gt;
* Christian Wirth , C Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://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>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=8122</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=8122"/>
				<updated>2006-07-05T11:10:20Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* int, char, short, long (ganze Zahlen) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ein kurzer Einblick in die Programmiersprache C&lt;br /&gt;
=Allgemeines=&lt;br /&gt;
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 Sprachedefinition entwickelt. C ist mittlerweile von ANSI und ISO standardisiert.&lt;br /&gt;
Heutzutage ist C (und ihr Nachfolger C++) die dominierende Programmiersprache. Sehr viele Anwendungen sind in C geschrieben. Leider ist C jedoch nicht einfach zu lernen, daher eignet es sich nur bedingt für Anfänger. Mit etwas Übung kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
C ist sehr eng an Assembler angelehnt, aber trotzdem Hardware-unabhängig. Das bedeutet, Sie können maschinennahe Programme sehr leicht (aber nicht ganz ohne Aufwand) auf ein anderes System portieren. Sie benötigen dazu 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;
&amp;lt;pre&amp;gt;&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;
   /* Anweisungen */&lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Beschreibung (die Erklärungen folgen): &lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndahs; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* &lt;br /&gt;
 * void Definition von main ist nur beim Controller üblich&lt;br /&gt;
 * spezielle Compilereinstellungen sind nötig, damit bei dieser Definition von main&lt;br /&gt;
 * kein Fehler/Warnung erzeugt wird. &lt;br /&gt;
 */&lt;br /&gt;
void main (void)&lt;br /&gt;
{&lt;br /&gt;
   ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{    /* der Block &amp;quot;main&amp;quot; beginnt */&lt;br /&gt;
   int zahl;&lt;br /&gt;
   &lt;br /&gt;
   {   /* ein Block beginnt */&lt;br /&gt;
       /* hier können Deklarationen und Anweisungen stehen */&lt;br /&gt;
   }   /* der Block endet */&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}    /* &amp;quot;main&amp;quot; endet */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Bemerkung:''' &lt;br /&gt;
Der &amp;quot;namenlose&amp;quot; Block ist eigentlich unnötig. In den folgenden Kapiteln lernen Sie jedoch bessere Beispiele kennen!&lt;br /&gt;
&lt;br /&gt;
=Datentypen=&lt;br /&gt;
==Elementare Datentypen==&lt;br /&gt;
Der Datentyp einer Variable gibt an, welche Werte eine Variable enthalten kann, welcher Art diese Daten sind und wie sie verarbeitet werden, etwa in arithmetischen Operationen wie einer Addition. So ist es zum Beispiel möglich, in eine Variable vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ganze Zahlen zwischen ca. -32000 und +32000 einzutragen. In einer char-Variable können ASCII-Zeichen gespeichert werden (alles, was Sie mit der Tastatur erzeugen können) oder ganze Zahlen von -128 bis 127.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da C plattformabhängig ist, hängt die Größe eines Datentypes zum Teil von der genutzten Hardware (z.B. 8, 16 oder 32 Bit-Controller) und dem Compiler und dessen Einstellungen ab!&lt;br /&gt;
&lt;br /&gt;
===int, char, short, long (ganze Zahlen)===&lt;br /&gt;
In Variable dieser Typen können Sie ganze Zahlen abspeichern, also z.B. 1, &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;2, 100, 12345. Jeden dieser Typen gibt es in zwei Ausprägungen: als &amp;quot;&amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;quot;, also als vorzeichenbehafteten Typ, und als &amp;quot;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&amp;quot;, also ohne Vorzeichen, d.h. das Vorzeichen wird als 0 oder +1 genommen. &lt;br /&gt;
&lt;br /&gt;
Vorzeichenbehaftete Ganzzahl-Typen werden intern im &amp;lt;tt&amp;gt;n-1&amp;lt;/tt&amp;gt;-Komplement dargestellt, das Vorzeichen selbst findet sich also im höchstwertigen Bit. Werden zur Speicherung ''b'' Bits verwendet, dann reicht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;*zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==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:''' Datentyp Variablenname[Anzahl]&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 3 Variablen. Da der Index immer bei 0 beginnt, greift man also mit [0], [1] und [2] 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;
&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 i;&lt;br /&gt;
  int zahlen[10];  /* zahlen[0] bis zahlen[9] !!! */&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;10; 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;
  printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  for (i=0; i&amp;lt;10; 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;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Bemerkungen:''' &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;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
Wenn Sie einen ungültigen Index angeben (einen, der in der Deklaration nicht enthalten war) können je nach Compiler und Einstellung undefinierbare Dinge passieren, da dadurch andere Variableninhalte oder Programmcode überschrieben wird. Im schlimmsten Fall könnte sogar der Computer/Controller abstürzen. Also achten Sie darauf, daß Sie keine ungültigen Werte als Index angeben!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Strings (Zeichenketten)===&lt;br /&gt;
Ein String ist nicht sanderes 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ötigen 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;
&amp;lt;pre&amp;gt;&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;
&amp;lt;/pre&amp;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 vier Komponenten angelege: 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 dieses Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach &lt;br /&gt;
 struct Person Variablenname;&lt;br /&gt;
an. &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;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  struct Person hubert, klaus;&lt;br /&gt;
&lt;br /&gt;
  hubert.alter = 32;&lt;br /&gt;
  klaus.alter = hubert.alter + 1;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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 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 Person u_person;&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_double&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Groß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.&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 chat 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.&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;
/* nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform) */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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;
Teilweise erlauben C-Compiler auch die Verwendung des Dollar-Zeichens &amp;lt;tt&amp;gt;'''$'''&amp;lt;/tt&amp;gt; in Variablennaben.&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;
&amp;lt;pre&amp;gt;&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;
  /* Anweisungen */&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
;Erklärung: 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;wahr&amp;quot;, ansonsten ist sie &amp;quot;unwahr&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;
==Vergleich von Variablen==&lt;br /&gt;
Sie können Variablen miteinander vergleichen. Das geschieht mit einem der folgenden Zeichen mit den normalen mathematischen Regeln: &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;
Als Ergebnis bekommen Sie einen logischen Ausdruck in Form einer int-Zahl. &lt;br /&gt;
 intVariable = zahl1 &amp;lt;= zahl2;&lt;br /&gt;
das komplette Beispiel zeigt es deutlicher:&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;= z1  /* Ein Vergleich. Die int-Variable i wird wahr, da z1 kleiner als z2 */&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Ergebnis: %d\n&amp;quot;, i);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich 0 (&amp;quot;wahr&amp;quot;), wenn z1 kleiner oder gleich z2 ist. Ist z1 jedoch größer als z2, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich 0 (&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 dafür ein Schlüsselwort in C:&lt;br /&gt;
 const ''datentyp'' name = value;  /* 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;  /* 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;. 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 Eigenheit 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, wenn das Ergebnis bereits feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
  (x &amp;gt; 5) || datei_auf_festplatte_gefunden(&amp;quot;hallo.txt&amp;quot;) /* gut */&lt;br /&gt;
  datei_auf_festplatte_gefunden(&amp;quot;hallo.txt&amp;quot;) || (x &amp;gt; 5) /* nicht so gut */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;datei_auf_festplatte_gefunden&amp;lt;/tt&amp;gt; ist fiktiv und steht für eine Funktion,&lt;br /&gt;
die eine aufwändige Operation durchführt.&lt;br /&gt;
Beide Zeilen ergeben &amp;lt;tt&amp;gt;wahr&amp;lt;/tt&amp;gt; wenn die Variable x einen Wert größer 5 hat oder&lt;br /&gt;
es eine Datei namens &amp;lt;tt&amp;gt;hallo.txt&amp;lt;/tt&amp;gt; auf der Festplatte gibt.&lt;br /&gt;
&lt;br /&gt;
Wo ist also der Unterschied?&amp;lt;br&amp;gt;&lt;br /&gt;
In der ersten Zeile wird geprüft, ob x größer als 5 ist und wenn das der Fall ist,&lt;br /&gt;
dann wird ''nicht mehr geprüft'', ob &amp;lt;tt&amp;gt;hallo.txt&amp;lt;/tt&amp;gt; auf der Festplatte existiert.&lt;br /&gt;
In der zweiten Zeile wird ''immer geprüft'', ob &amp;lt;tt&amp;gt;hallo.txt&amp;lt;/tt&amp;gt; auf der Festplatte&lt;br /&gt;
existiert und erst, wenn sie nicht gefunden wird, wird die Variable x ausgewertet.&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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  int x = 5;    /* x ist eine Integervariable und hat den Wert 5 */&lt;br /&gt;
&lt;br /&gt;
  /* z ist ein Zeiger auf eine Integervariable und enthält somit&lt;br /&gt;
     die Speicheradresse einer Integervariablen&lt;br /&gt;
  */&lt;br /&gt;
  int *z;       &lt;br /&gt;
&lt;br /&gt;
  /* Verwendung des Adressoperators... */&lt;br /&gt;
  z = &amp;amp;x;       /* weise z die Speicheradresse von x zu */&lt;br /&gt;
&lt;br /&gt;
  /* Verwendung der Dereferenzierung */&lt;br /&gt;
  /* erhöhe den Wert, der bei Adresse z steht um eins */&lt;br /&gt;
  *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
  /* da z auf x zeigt, hat auch x jetzt den Wert 6 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff&lt;br /&gt;
auf ein Element 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;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&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&lt;br /&gt;
auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu&lt;br /&gt;
einer Änderung '''irgendeiner''' Speicherstelle:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   int *z; /* z ist ein Zeiger auf einen Integer */&lt;br /&gt;
&lt;br /&gt;
   /* An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.&lt;br /&gt;
      z enthält irgendeine(!) Adresse&lt;br /&gt;
   */&lt;br /&gt;
&lt;br /&gt;
   /* &amp;quot;Erhöhe einen Integer irgendwo im Speicher um 1&amp;quot; -&amp;gt; CRASH */&lt;br /&gt;
   *z = *z + 1;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler (z.B. gcc) erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
}}&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'' durch, sondern unterdrückt nur die Compilerwarnungen oder&lt;br /&gt;
-fehler, die bei einer &amp;quot;verdächtigen&amp;quot; Umwandlung passieren. Er kann also nicht benutzt werden, um einen Text in&lt;br /&gt;
eine Zahl oder umgekehrt zu wandeln:&lt;br /&gt;
&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;
&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Speicheradresse, an der der Text &amp;quot;5.6&amp;quot; beginnt. Der Cast-Operator&lt;br /&gt;
unterdrückt nur die Warnung, die auf den Fehler hinweisen will.&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;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Bedingte Zuweisung===&lt;br /&gt;
 lvalue = (bediungung) ? if-ausdruck : else-ausdruck;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Kein ANSI-C&lt;br /&gt;
--[[Benutzer:SprinterSB|SprinterSB]] 17:15, 29. Jun 2006 (CEST)&lt;br /&gt;
==Blöcke==&lt;br /&gt;
Selbst Blöcke haben in C einen Wert, der in einer Berechnung verwendet werden kann.&lt;br /&gt;
Der Wert eines Blockes ist der Wert der letzten Anweisung des Blocks. &lt;br /&gt;
Der Block muss un runden Klammern stehen:&lt;br /&gt;
 int sum;&lt;br /&gt;
 sum = ({&lt;br /&gt;
    int i, s = 0;&lt;br /&gt;
    for (i=1; i&amp;lt;= 100; i++)&lt;br /&gt;
       s += i;&lt;br /&gt;
    s;&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Makro &amp;lt;tt&amp;gt;PSTR&amp;lt;/tt&amp;gt; von avr-gcc, &lt;br /&gt;
das einen String ins Flash legt und die Adresse zurückliefert, was nur in einer&lt;br /&gt;
Instruktion nicht machbar wäre:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define PSTR(s)                         \&lt;br /&gt;
  ({                                    \ &lt;br /&gt;
      static char __c[] PROGMEM = (s);  \&lt;br /&gt;
      __c;                              \&lt;br /&gt;
  })&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
==Boolsche Logik==&lt;br /&gt;
Boolean-Variablen können miteinander verknüpft werden. Dies geschieht mit den boolschen Operatoren &amp;amp;&amp;amp; ( logisches &amp;quot;und&amp;quot;), || (logisches &amp;quot;oder&amp;quot;) und ! (logisches &amp;quot;nicht&amp;quot;) (es gibt noch weitere, auf die hier nicht eingegangen wird). &lt;br /&gt;
&lt;br /&gt;
 b1= b2 &amp;amp;&amp;amp; b3;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der Wert von b1 ist dann 1 (TRUE), wenn b2 und (&amp;quot;AND&amp;quot;) b3 1 (TRUE) sind. Ist eine der beiden (oder auch beide) 0 (FALSE), dann ist b1 ebenfalls 0 (FALSE).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 b1= b2 || b3;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der Wert von b1 ist dann TRUE, wenn b2 oder (&amp;quot;OR&amp;quot;) b3 TRUE ist. Ist also einer (oder beide) TRUE, dann ist auch b1 TRUE, sind beide FALSE, ist auch b1 FALSE.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 b1= !b2;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der Wert von b1 ist dann TRUE, wenn der von b2 FALSE ist. Die NOT Verknüpfung &amp;quot;dreht den logischen Wert der Variablen um&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Anweisung==&lt;br /&gt;
Syntax: IF (Bedingung) Anweisung;&lt;br /&gt;
Mit Hilfe der IF Anweisung kann man Codeteile (Blöcke) ausführen lassen, wenn die dazugehörige Bedingung erfüllt (TRUE) ist. Im Flussdiagramm sieht eine If-Anweisung folgendermassen aus:&lt;br /&gt;
&lt;br /&gt;
[[bild:ifthenelse.png]]&lt;br /&gt;
&lt;br /&gt;
Und in C schreibt man:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if (Bedingung)        /* WENN */&lt;br /&gt;
{                     /* DANN */&lt;br /&gt;
       Anweisung1;&lt;br /&gt;
       Anweisung2;&lt;br /&gt;
       ...&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{                     /* SONST */&lt;br /&gt;
       Anweisung3;&lt;br /&gt;
       Anweisung4;&lt;br /&gt;
       ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wenn die Bedingung wahr ist wird Anweisung1 ausgeführt. Anschliessend wird aus der If-Bedingung herausgesprungen. Anweisung2 wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung unwahr wird gleich zu Anweisung2 gesprungen, diese ausgeführt, und anschliessend wird die If-Bedingung beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Ein häufiger Fehler ist statt if(a == 23) etwas wie if(a = 23) zu schreiben. Hier wird allerdings nicht geprüft ob die Variable a gleich 23 ist, sondern der Variable a wird der Wert 23 zugewiesen, und das ist eine wahre Aussage. Anschliessend wird demzufolge der &amp;quot;DANN&amp;quot;-Teil ausgeführt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken. Somit ist dieser kleine Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise if(23 == a). Wenn man dort anstatt des Vergleichsoperator '==' den Zuweisungsoperator '=' verwendet spuckt der Compiler sehr wohl einen Fehler aus.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist das schreiben von if(Bedingung)''';''' Richtig müsste es heissen &amp;quot;if(Bedingung)&amp;quot; Das fehlerhafte Semikolon im ersten Fall interpretiert der Compiler bereits als Anweisung. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt. Hier also ebenfalls besser zweimal hinschauen.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;-Anweisung==&lt;br /&gt;
Syntax: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
switch(ausdruck) {&lt;br /&gt;
    case wert1:&lt;br /&gt;
        Anweisungen1...&lt;br /&gt;
    case wert2:&lt;br /&gt;
        Anweisungen2...&lt;br /&gt;
    case wert3:&lt;br /&gt;
        Anweisungen3...&lt;br /&gt;
    ...&lt;br /&gt;
    default:&lt;br /&gt;
        Anweisungen4...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der &amp;lt;tt&amp;gt;ausdruck&amp;lt;/tt&amp;gt; muss eine Ganzzahl (int) ergeben und wird dann der Reihe nach mit den Werten, die hinter&lt;br /&gt;
den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Anweisungen angegeben sind verglichen. Bei einer Übereinstimmung werden alle Befehle ab der&lt;br /&gt;
zutreffenden Case-Anweisung ausgeführt. Stimmt der &amp;lt;tt&amp;gt;ausdruck&amp;lt;/tt&amp;gt; mit keinem der Werte hinter &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;&lt;br /&gt;
überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der folgenden &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 eines&lt;br /&gt;
&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, muss aber nach allen &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitten angegeben werden,&lt;br /&gt;
wenn er verwendet wird.&lt;br /&gt;
&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;
===&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;-Schleife===&lt;br /&gt;
'''Syntax:''' while (Bedingung) { Anweisung; }&lt;br /&gt;
&lt;br /&gt;
Die WHILE-Schleife wird solange durchlaufen, wie die Bedingung erfüllt (TRUE) ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Bei mehreren Anweisungen benötigen man einen Block! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Zahl1=0;&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;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife 3 mal durchlaufen. Zu Beginn des 4. Durchlaufes ist die Bedingung FALSE (Zahl1 ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
===&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;-Schleife===&lt;br /&gt;
'''Syntax:''' do  { Anweisung; }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. Das ist dann sinnvoll, wenn der Vergleichswert für die Bedingung erst im Anweisungsblock gesetzt wird &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int i=2;&lt;br /&gt;
do &lt;br /&gt;
{&lt;br /&gt;
    i = i*i;   /* 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;
&amp;lt;/pre&amp;gt;&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.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;-Schleife===&lt;br /&gt;
'''Syntax:''' for (Zuweisung;Bedingung;Inkrement) { Anweisung; }&lt;br /&gt;
&lt;br /&gt;
Die FOR-Schleife ist eine spezielle WHILE-Variante für die Formulierung von Zählschleifen. Die angegebene Variable wird am Anfang auf einen Wert gesetzt. Danach wird sie nach jedem Durchlauf verändert (meist um 1 erhöht). Ist die Bedingung nicht mehr erfüllt, wird die Schleife beendet. Innerhalb des Anweisungsblockes können Sie auf die Variable zugreifen, d.h. Sie können sie auch verändern. Das ist jedoch nicht ratsam. Wollen Sie mehrere Anweisungen ausführen, benötigen Sie eine Block.&lt;br /&gt;
&lt;br /&gt;
Die gesammte Schleife wird solange durchgeführt, wie die Bedingung wahr ist (d.h. Sie brauchen garnicht die Zählvariable abfragen, Sie können hier auch jede andere Variable auswerten). Inkrement letztendlich wird nach jedem Schleifendurchlauf ausgeführt. Hier kann man z.B. den Zähler erhöhen.&lt;br /&gt;
&lt;br /&gt;
Die Theorie ist schwer, die Praxis nicht so sehr. In der Schleife wird die Summe ungerader Zahlen kleinergleich 10 berechnet. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int lauf;&lt;br /&gt;
int summe = 0;&lt;br /&gt;
&lt;br /&gt;
for (lauf = 1; lauf &amp;lt;= 10; lauf = lauf+2 ) &lt;br /&gt;
{&lt;br /&gt;
   summe = summe + lauf;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Das Äquivalent als &amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;-Schleife:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int lauf  = 1;                 /* Anfangswerte */&lt;br /&gt;
int summe = 0;&lt;br /&gt;
&lt;br /&gt;
while (lauf &amp;lt;= 10)             /* Bedingung */&lt;br /&gt;
{&lt;br /&gt;
   summe = summe + lauf;&lt;br /&gt;
   lauf += 2;                  /* Inkrement */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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 1 bis 10 hat, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von 1 bis kleinergleich 10 gespeichert.&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 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 = 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;
=Ein- und Ausgabe=&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;
&lt;br /&gt;
=Allgemeines zu Unterprogrammen=&lt;br /&gt;
Stellen Sie sich vor, Sie haben einen eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben (was Zeit beim Erstellen und Speicherplatz im ausführbaren Programm kostet), können Sie den Abschnitt in ein sogenanntes &amp;quot;Unterprogramm&amp;quot; schreiben. Dieses Unterprogramm können Sie dann von jeder Stelle ihre Hauptprogrammes aus aufrufen.&lt;br /&gt;
Anders als in anderen Programmiersprachen gibt es in C keine generelle Unterscheidung zwischen Funktionen und Prozeduren. Trotzdem möchte ich kurz darauf eingehen: &lt;br /&gt;
&lt;br /&gt;
==Funktionen==&lt;br /&gt;
'''Syntax:''' Rückgabe-Typ Name(Parameterliste);&lt;br /&gt;
&lt;br /&gt;
Funktionen sind Unterprogramme, die am Ende der Ausführung einen Wert zurückliefern, wie z.B. getch. Paradebeispiele für die Anwendung einer Funktion sind jedoch mathematische Formeln: &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 hoch2 (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 (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, 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;zahl1);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = hoch2 (zahl1);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;,zahl1, ergebnis);&lt;br /&gt;
  printf (&amp;quot;5 hoch 2 = %d\n&amp;quot;, hoch2(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;
'''Bemerkungen zum Programm:''' &lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur außerhalb von Blöcken. Siehe auch Prototypen. &lt;br /&gt;
Geschachtelte-Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
In der Deklaration der Funktion kommt zuerst der Rückgabe-Datentyp. Jede Funktion liefert einen Wert zurück, dieser Datentyp gibt den Typ der Variablen an. Danach folgt der Name der Funktion (case-sensitiv!). Dann kommt in Klammern die Parameter-Liste. Dabei handelt es sich um eine Liste von Parametern, die jeweils durch Typ und Name angegeben werden und mittels Komma voneinander getrennt werden.&lt;br /&gt;
Im Block der Funktion können lokale Variablen definiert werden und alle Anweisungen ausgeführt werden. &lt;br /&gt;
Am Ende der Funktion muß diese ordnungsgemäß beendet werden. Dies geschieht mittels der Anweisung &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; und dem Rückgabewert. &lt;br /&gt;
Um eine Funktion aufzurufen (aus einem anderen Unterprogramm oder main), geben Sie folgendes an&lt;br /&gt;
 variable = Funktion (Parameter);&lt;br /&gt;
 Bei Variable muß es sich jedoch nicht unbedingt um eine von Ihnen deklarierte Variable handeln. Es kann z.B. auch der Parameter für ein weiteres Unterprogramm sein (wie im Beispiel, letzte Zeile). &lt;br /&gt;
Die Einrückungen der Anweisungen innerhalb der Funktion nach rechts ist nicht notwendig, sie dient jedoch der Übersicht und ist sehr empfehlenswert.&lt;br /&gt;
&lt;br /&gt;
==Prozedur==&lt;br /&gt;
'''Syntax:''' &amp;lt;tt&amp;gt;void Name (Parameterliste)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Prozedur ist nichts anderes als eine Funktion mit dem speziellen  Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der kennzeichnet, daß die Funktion keinen Wert zurückliefert. Sie ist daher prinzipiell gleich aufgebaut wie eine Funktion, bis auf die folgenden Unterschiede: &lt;br /&gt;
&lt;br /&gt;
Als Rückgabe-Datentyp wird &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; angegeben. &lt;br /&gt;
Einer Variablen kann daher nicht der Rückgabewert einer &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion zugewiesen werden, da diese garkeinen Rückgabewert liefert.&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 param1)&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Der Wert der Variablen ist: %d\n&amp;quot;, param1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
   int zahl1 = 4;&lt;br /&gt;
   &lt;br /&gt;
   ausgeben (23);&lt;br /&gt;
   ausgeben (zahl1);&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;
'''Bemerkungen zum Programm:''' &lt;br /&gt;
Durch den Befehl &amp;quot;&amp;lt;tt&amp;gt;ausgeben(23)&amp;lt;/tt&amp;gt;&amp;quot; wird die Prozedur &amp;quot;&amp;lt;tt&amp;gt;ausgeben&amp;lt;/tt&amp;gt;&amp;quot; mit dem Parameter &amp;lt;tt&amp;gt;23&amp;lt;/tt&amp;gt; aufgerufen. &amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt; hat also den Wert &amp;lt;tt&amp;gt;23&amp;lt;/tt&amp;gt;. Die einzige Anweisung innerhalb der Prozedur ist &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;, was nun ausgeführt wird. &lt;br /&gt;
Der zweite Aufruf von &amp;lt;tt&amp;gt;ausgeben&amp;lt;/tt&amp;gt; erfolgt mit dem Parameter &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, also wird &amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt; der Wert 4 zugewiesen. Dieser wird nun wieder mittels &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; ausgeben. &lt;br /&gt;
&lt;br /&gt;
Unterprogramme ohne Parameter&lt;br /&gt;
Das ist ihnen sicherlich schon aufgefallen: Viele Unterprogramme, haben statt einer Parameterliste nur &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; stehen. Das &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; bedeutet &amp;quot;die Funktion erhält keine Parameter&amp;quot;. &amp;quot;&amp;lt;tt&amp;gt;void main (void)&amp;lt;/tt&amp;gt;&amp;quot; bedeutet also: &amp;quot;Erstelle ein Unterprogramm Namens &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keinen Rückgabewert und keine Parameter hat&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen Sie beim Aufruf trotzdem die Klammern angeben. Beispiel für eine parameterlose Funktion &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 foo();&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;
&lt;br /&gt;
Beispiele:&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;
   /* a ist immer noch 0 */&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;
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 x übergeben. Dass dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void erhoehe (int *x)&lt;br /&gt;
{&lt;br /&gt;
   /* erhöhe 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;
   /* a ist jetzt 1 */&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;
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 Operator &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&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&lt;br /&gt;
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&lt;br /&gt;
den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;
  /* a hat jetzt folgenden Inhalt: 11, 23, 35 */&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;
&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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* 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;
  /* a hat jetzt folgenden Inhalt: 11, 23, 35 */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;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;
=Standard-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;
&lt;br /&gt;
&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;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der Computer 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 scanf - da übergeben Sie ja auch die Adresse einer Variablen (&amp;quot;&amp;amp;Variable&amp;quot;). &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 = *zeiger+1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main (void)&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;
==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: &amp;quot;dir *.exe&amp;quot;, &amp;quot;copy *.* a:&amp;quot; oder &amp;quot;ls -la&amp;quot;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;&amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen! &lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
&lt;br /&gt;
* [[#Speicherklassen|auto]]&lt;br /&gt;
* break&lt;br /&gt;
* [[#Elementare Datentypen|double]]&lt;br /&gt;
* [[#Elementare Datentypen|char]]&lt;br /&gt;
* case&lt;br /&gt;
* [[#Konstanten|const]]&lt;br /&gt;
* continue&lt;br /&gt;
* default&lt;br /&gt;
* do&lt;br /&gt;
* else&lt;br /&gt;
* enum&lt;br /&gt;
* [[#Speicherklassen|extern]]&lt;br /&gt;
* [[#Elementare Datentypen|float]]&lt;br /&gt;
* for&lt;br /&gt;
* goto&lt;br /&gt;
* if&lt;br /&gt;
* [[##Elementare Datentypen|int]]&lt;br /&gt;
* [[#Elementare Datentypen|long]]&lt;br /&gt;
* return&lt;br /&gt;
* [[#Speicherklassen|register]]&lt;br /&gt;
* [[#Elementare Datentypen|short]]&lt;br /&gt;
* signed&lt;br /&gt;
* sizeof&lt;br /&gt;
* [[#Speicherklassen|static]]&lt;br /&gt;
* [[#Strukturen|struct]]&lt;br /&gt;
* switch&lt;br /&gt;
* typedef&lt;br /&gt;
* [[#Unions|union]]&lt;br /&gt;
* unsigned&lt;br /&gt;
* [[#Elementare Datentypen|void]]&lt;br /&gt;
* volatile&lt;br /&gt;
* while&lt;br /&gt;
&lt;br /&gt;
Baustelle&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
Baustelle&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung || Nebeneffekte&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; == &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; != &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || ist nicht gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;lt; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;lt;= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;gt; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;gt;= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;amp; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; = &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; += &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; -= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; *= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; /= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; ^= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; |= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++ &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; ++&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-- &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; --&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;&amp;amp; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~ &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;! &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;(&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/font&amp;gt;) &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; + &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; - &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; * &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; / &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; % &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; %= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;(&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Bedingung&amp;gt;&amp;lt;/font&amp;gt;) ? &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; : &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Struct&amp;gt;&amp;lt;/font&amp;gt;.&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Komponenten-Bezeichner&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Zeiger-auf-Struct&amp;gt;&amp;lt;/font&amp;gt;-&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Komponenten-Bezeichner&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Autoren'''&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
* Kernighan und Ritchie - Buch&lt;br /&gt;
* Christian Wirth , C Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://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>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=8119</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=8119"/>
				<updated>2006-07-05T11:05:54Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Blöcke */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ein kurzer Einblick in die Programmiersprache C&lt;br /&gt;
=Allgemeines=&lt;br /&gt;
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 Sprachedefinition entwickelt. C ist mittlerweile von ANSI und ISO standardisiert.&lt;br /&gt;
Heutzutage ist C (und ihr Nachfolger C++) die dominierende Programmiersprache. Sehr viele Anwendungen sind in C geschrieben. Leider ist C jedoch nicht einfach zu lernen, daher eignet es sich nur bedingt für Anfänger. Mit etwas Übung kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
C ist sehr eng an Assembler angelehnt, aber trotzdem Hardware-unabhängig. Das bedeutet, Sie können maschinennahe Programme sehr leicht (aber nicht ganz ohne Aufwand) auf ein anderes System portieren. Sie benötigen dazu 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;
&amp;lt;pre&amp;gt;&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;
   /* Anweisungen */&lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Beschreibung (die Erklärungen folgen): &lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndahs; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* &lt;br /&gt;
 * void Definition von main ist nur beim Controller üblich&lt;br /&gt;
 * spezielle Compilereinstellungen sind nötig, damit bei dieser Definition von main&lt;br /&gt;
 * kein Fehler/Warnung erzeugt wird. &lt;br /&gt;
 */&lt;br /&gt;
void main (void)&lt;br /&gt;
{&lt;br /&gt;
   ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{    /* der Block &amp;quot;main&amp;quot; beginnt */&lt;br /&gt;
   int zahl;&lt;br /&gt;
   &lt;br /&gt;
   {   /* ein Block beginnt */&lt;br /&gt;
       /* hier können Deklarationen und Anweisungen stehen */&lt;br /&gt;
   }   /* der Block endet */&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}    /* &amp;quot;main&amp;quot; endet */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Bemerkung:''' &lt;br /&gt;
Der &amp;quot;namenlose&amp;quot; Block ist eigentlich unnötig. In den folgenden Kapiteln lernen Sie jedoch bessere Beispiele kennen!&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 recht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;*zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==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:''' Datentyp Variablenname[Anzahl]&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 3 Variablen. Da der Index immer bei 0 beginnt, greift man also mit [0], [1] und [2] 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;
&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 i;&lt;br /&gt;
  int zahlen[10];  /* zahlen[0] bis zahlen[9] !!! */&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;10; 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;
  printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  for (i=0; i&amp;lt;10; 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;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Bemerkungen:''' &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;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
Wenn Sie einen ungültigen Index angeben (einen, der in der Deklaration nicht enthalten war) können je nach Compiler und Einstellung undefinierbare Dinge passieren, da dadurch andere Variableninhalte oder Programmcode überschrieben wird. Im schlimmsten Fall könnte sogar der Computer/Controller abstürzen. Also achten Sie darauf, daß Sie keine ungültigen Werte als Index angeben!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Strings (Zeichenketten)===&lt;br /&gt;
Ein String ist nicht sanderes 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ötigen 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;
&amp;lt;pre&amp;gt;&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;
&amp;lt;/pre&amp;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 vier Komponenten angelege: 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 dieses Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach &lt;br /&gt;
 struct Person Variablenname;&lt;br /&gt;
an. &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;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  struct Person hubert, klaus;&lt;br /&gt;
&lt;br /&gt;
  hubert.alter = 32;&lt;br /&gt;
  klaus.alter = hubert.alter + 1;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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 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 Person u_person;&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_double&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Groß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.&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 chat 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.&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;
/* nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform) */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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;
Teilweise erlauben C-Compiler auch die Verwendung des Dollar-Zeichens &amp;lt;tt&amp;gt;'''$'''&amp;lt;/tt&amp;gt; in Variablennaben.&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;
&amp;lt;pre&amp;gt;&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;
  /* Anweisungen */&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
;Erklärung: 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;wahr&amp;quot;, ansonsten ist sie &amp;quot;unwahr&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;
==Vergleich von Variablen==&lt;br /&gt;
Sie können Variablen miteinander vergleichen. Das geschieht mit einem der folgenden Zeichen mit den normalen mathematischen Regeln: &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;
Als Ergebnis bekommen Sie einen logischen Ausdruck in Form einer int-Zahl. &lt;br /&gt;
 intVariable = zahl1 &amp;lt;= zahl2;&lt;br /&gt;
das komplette Beispiel zeigt es deutlicher:&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;= z1  /* Ein Vergleich. Die int-Variable i wird wahr, da z1 kleiner als z2 */&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Ergebnis: %d\n&amp;quot;, i);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich 0 (&amp;quot;wahr&amp;quot;), wenn z1 kleiner oder gleich z2 ist. Ist z1 jedoch größer als z2, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich 0 (&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 dafür ein Schlüsselwort in C:&lt;br /&gt;
 const ''datentyp'' name = value;  /* 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;  /* 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;. 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 Eigenheit 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, wenn das Ergebnis bereits feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
  (x &amp;gt; 5) || datei_auf_festplatte_gefunden(&amp;quot;hallo.txt&amp;quot;) /* gut */&lt;br /&gt;
  datei_auf_festplatte_gefunden(&amp;quot;hallo.txt&amp;quot;) || (x &amp;gt; 5) /* nicht so gut */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;datei_auf_festplatte_gefunden&amp;lt;/tt&amp;gt; ist fiktiv und steht für eine Funktion,&lt;br /&gt;
die eine aufwändige Operation durchführt.&lt;br /&gt;
Beide Zeilen ergeben &amp;lt;tt&amp;gt;wahr&amp;lt;/tt&amp;gt; wenn die Variable x einen Wert größer 5 hat oder&lt;br /&gt;
es eine Datei namens &amp;lt;tt&amp;gt;hallo.txt&amp;lt;/tt&amp;gt; auf der Festplatte gibt.&lt;br /&gt;
&lt;br /&gt;
Wo ist also der Unterschied?&amp;lt;br&amp;gt;&lt;br /&gt;
In der ersten Zeile wird geprüft, ob x größer als 5 ist und wenn das der Fall ist,&lt;br /&gt;
dann wird ''nicht mehr geprüft'', ob &amp;lt;tt&amp;gt;hallo.txt&amp;lt;/tt&amp;gt; auf der Festplatte existiert.&lt;br /&gt;
In der zweiten Zeile wird ''immer geprüft'', ob &amp;lt;tt&amp;gt;hallo.txt&amp;lt;/tt&amp;gt; auf der Festplatte&lt;br /&gt;
existiert und erst, wenn sie nicht gefunden wird, wird die Variable x ausgewertet.&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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  int x = 5;    /* x ist eine Integervariable und hat den Wert 5 */&lt;br /&gt;
&lt;br /&gt;
  /* z ist ein Zeiger auf eine Integervariable und enthält somit&lt;br /&gt;
     die Speicheradresse einer Integervariablen&lt;br /&gt;
  */&lt;br /&gt;
  int *z;       &lt;br /&gt;
&lt;br /&gt;
  /* Verwendung des Adressoperators... */&lt;br /&gt;
  z = &amp;amp;x;       /* weise z die Speicheradresse von x zu */&lt;br /&gt;
&lt;br /&gt;
  /* Verwendung der Dereferenzierung */&lt;br /&gt;
  /* erhöhe den Wert, der bei Adresse z steht um eins */&lt;br /&gt;
  *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
  /* da z auf x zeigt, hat auch x jetzt den Wert 6 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff&lt;br /&gt;
auf ein Element 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;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&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&lt;br /&gt;
auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu&lt;br /&gt;
einer Änderung '''irgendeiner''' Speicherstelle:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   int *z; /* z ist ein Zeiger auf einen Integer */&lt;br /&gt;
&lt;br /&gt;
   /* An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.&lt;br /&gt;
      z enthält irgendeine(!) Adresse&lt;br /&gt;
   */&lt;br /&gt;
&lt;br /&gt;
   /* &amp;quot;Erhöhe einen Integer irgendwo im Speicher um 1&amp;quot; -&amp;gt; CRASH */&lt;br /&gt;
   *z = *z + 1;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler (z.B. gcc) erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
}}&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'' durch, sondern unterdrückt nur die Compilerwarnungen oder&lt;br /&gt;
-fehler, die bei einer &amp;quot;verdächtigen&amp;quot; Umwandlung passieren. Er kann also nicht benutzt werden, um einen Text in&lt;br /&gt;
eine Zahl oder umgekehrt zu wandeln:&lt;br /&gt;
&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;
&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Speicheradresse, an der der Text &amp;quot;5.6&amp;quot; beginnt. Der Cast-Operator&lt;br /&gt;
unterdrückt nur die Warnung, die auf den Fehler hinweisen will.&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;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Bedingte Zuweisung===&lt;br /&gt;
 lvalue = (bediungung) ? if-ausdruck : else-ausdruck;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Kein ANSI-C&lt;br /&gt;
--[[Benutzer:SprinterSB|SprinterSB]] 17:15, 29. Jun 2006 (CEST)&lt;br /&gt;
==Blöcke==&lt;br /&gt;
Selbst Blöcke haben in C einen Wert, der in einer Berechnung verwendet werden kann.&lt;br /&gt;
Der Wert eines Blockes ist der Wert der letzten Anweisung des Blocks. &lt;br /&gt;
Der Block muss un runden Klammern stehen:&lt;br /&gt;
 int sum;&lt;br /&gt;
 sum = ({&lt;br /&gt;
    int i, s = 0;&lt;br /&gt;
    for (i=1; i&amp;lt;= 100; i++)&lt;br /&gt;
       s += i;&lt;br /&gt;
    s;&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Makro &amp;lt;tt&amp;gt;PSTR&amp;lt;/tt&amp;gt; von avr-gcc, &lt;br /&gt;
das einen String ins Flash legt und die Adresse zurückliefert, was nur in einer&lt;br /&gt;
Instruktion nicht machbar wäre:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define PSTR(s)                         \&lt;br /&gt;
  ({                                    \ &lt;br /&gt;
      static char __c[] PROGMEM = (s);  \&lt;br /&gt;
      __c;                              \&lt;br /&gt;
  })&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
==Boolsche Logik==&lt;br /&gt;
Boolean-Variablen können miteinander verknüpft werden. Dies geschieht mit den boolschen Operatoren &amp;amp;&amp;amp; ( logisches &amp;quot;und&amp;quot;), || (logisches &amp;quot;oder&amp;quot;) und ! (logisches &amp;quot;nicht&amp;quot;) (es gibt noch weitere, auf die hier nicht eingegangen wird). &lt;br /&gt;
&lt;br /&gt;
 b1= b2 &amp;amp;&amp;amp; b3;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der Wert von b1 ist dann 1 (TRUE), wenn b2 und (&amp;quot;AND&amp;quot;) b3 1 (TRUE) sind. Ist eine der beiden (oder auch beide) 0 (FALSE), dann ist b1 ebenfalls 0 (FALSE).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 b1= b2 || b3;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der Wert von b1 ist dann TRUE, wenn b2 oder (&amp;quot;OR&amp;quot;) b3 TRUE ist. Ist also einer (oder beide) TRUE, dann ist auch b1 TRUE, sind beide FALSE, ist auch b1 FALSE.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 b1= !b2;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der Wert von b1 ist dann TRUE, wenn der von b2 FALSE ist. Die NOT Verknüpfung &amp;quot;dreht den logischen Wert der Variablen um&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Anweisung==&lt;br /&gt;
Syntax: IF (Bedingung) Anweisung;&lt;br /&gt;
Mit Hilfe der IF Anweisung kann man Codeteile (Blöcke) ausführen lassen, wenn die dazugehörige Bedingung erfüllt (TRUE) ist. Im Flussdiagramm sieht eine If-Anweisung folgendermassen aus:&lt;br /&gt;
&lt;br /&gt;
[[bild:ifthenelse.png]]&lt;br /&gt;
&lt;br /&gt;
Und in C schreibt man:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if (Bedingung)        /* WENN */&lt;br /&gt;
{                     /* DANN */&lt;br /&gt;
       Anweisung1;&lt;br /&gt;
       Anweisung2;&lt;br /&gt;
       ...&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{                     /* SONST */&lt;br /&gt;
       Anweisung3;&lt;br /&gt;
       Anweisung4;&lt;br /&gt;
       ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wenn die Bedingung wahr ist wird Anweisung1 ausgeführt. Anschliessend wird aus der If-Bedingung herausgesprungen. Anweisung2 wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung unwahr wird gleich zu Anweisung2 gesprungen, diese ausgeführt, und anschliessend wird die If-Bedingung beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Ein häufiger Fehler ist statt if(a == 23) etwas wie if(a = 23) zu schreiben. Hier wird allerdings nicht geprüft ob die Variable a gleich 23 ist, sondern der Variable a wird der Wert 23 zugewiesen, und das ist eine wahre Aussage. Anschliessend wird demzufolge der &amp;quot;DANN&amp;quot;-Teil ausgeführt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken. Somit ist dieser kleine Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise if(23 == a). Wenn man dort anstatt des Vergleichsoperator '==' den Zuweisungsoperator '=' verwendet spuckt der Compiler sehr wohl einen Fehler aus.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist das schreiben von if(Bedingung)''';''' Richtig müsste es heissen &amp;quot;if(Bedingung)&amp;quot; Das fehlerhafte Semikolon im ersten Fall interpretiert der Compiler bereits als Anweisung. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt. Hier also ebenfalls besser zweimal hinschauen.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;-Anweisung==&lt;br /&gt;
Syntax: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
switch(ausdruck) {&lt;br /&gt;
    case wert1:&lt;br /&gt;
        Anweisungen1...&lt;br /&gt;
    case wert2:&lt;br /&gt;
        Anweisungen2...&lt;br /&gt;
    case wert3:&lt;br /&gt;
        Anweisungen3...&lt;br /&gt;
    ...&lt;br /&gt;
    default:&lt;br /&gt;
        Anweisungen4...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der &amp;lt;tt&amp;gt;ausdruck&amp;lt;/tt&amp;gt; muss eine Ganzzahl (int) ergeben und wird dann der Reihe nach mit den Werten, die hinter&lt;br /&gt;
den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Anweisungen angegeben sind verglichen. Bei einer Übereinstimmung werden alle Befehle ab der&lt;br /&gt;
zutreffenden Case-Anweisung ausgeführt. Stimmt der &amp;lt;tt&amp;gt;ausdruck&amp;lt;/tt&amp;gt; mit keinem der Werte hinter &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;&lt;br /&gt;
überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der folgenden &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 eines&lt;br /&gt;
&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, muss aber nach allen &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitten angegeben werden,&lt;br /&gt;
wenn er verwendet wird.&lt;br /&gt;
&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;
===&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;-Schleife===&lt;br /&gt;
'''Syntax:''' while (Bedingung) { Anweisung; }&lt;br /&gt;
&lt;br /&gt;
Die WHILE-Schleife wird solange durchlaufen, wie die Bedingung erfüllt (TRUE) ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Bei mehreren Anweisungen benötigen man einen Block! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Zahl1=0;&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;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife 3 mal durchlaufen. Zu Beginn des 4. Durchlaufes ist die Bedingung FALSE (Zahl1 ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
===&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;-Schleife===&lt;br /&gt;
'''Syntax:''' do  { Anweisung; }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. Das ist dann sinnvoll, wenn der Vergleichswert für die Bedingung erst im Anweisungsblock gesetzt wird &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int i=2;&lt;br /&gt;
do &lt;br /&gt;
{&lt;br /&gt;
    i = i*i;   /* 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;
&amp;lt;/pre&amp;gt;&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.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;-Schleife===&lt;br /&gt;
'''Syntax:''' for (Zuweisung;Bedingung;Inkrement) { Anweisung; }&lt;br /&gt;
&lt;br /&gt;
Die FOR-Schleife ist eine spezielle WHILE-Variante für die Formulierung von Zählschleifen. Die angegebene Variable wird am Anfang auf einen Wert gesetzt. Danach wird sie nach jedem Durchlauf verändert (meist um 1 erhöht). Ist die Bedingung nicht mehr erfüllt, wird die Schleife beendet. Innerhalb des Anweisungsblockes können Sie auf die Variable zugreifen, d.h. Sie können sie auch verändern. Das ist jedoch nicht ratsam. Wollen Sie mehrere Anweisungen ausführen, benötigen Sie eine Block.&lt;br /&gt;
&lt;br /&gt;
Die gesammte Schleife wird solange durchgeführt, wie die Bedingung wahr ist (d.h. Sie brauchen garnicht die Zählvariable abfragen, Sie können hier auch jede andere Variable auswerten). Inkrement letztendlich wird nach jedem Schleifendurchlauf ausgeführt. Hier kann man z.B. den Zähler erhöhen.&lt;br /&gt;
&lt;br /&gt;
Die Theorie ist schwer, die Praxis nicht so sehr. In der Schleife wird die Summe ungerader Zahlen kleinergleich 10 berechnet. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int lauf;&lt;br /&gt;
int summe = 0;&lt;br /&gt;
&lt;br /&gt;
for (lauf = 1; lauf &amp;lt;= 10; lauf = lauf+2 ) &lt;br /&gt;
{&lt;br /&gt;
   summe = summe + lauf;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Das Äquivalent als &amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;-Schleife:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int lauf  = 1;                 /* Anfangswerte */&lt;br /&gt;
int summe = 0;&lt;br /&gt;
&lt;br /&gt;
while (lauf &amp;lt;= 10)             /* Bedingung */&lt;br /&gt;
{&lt;br /&gt;
   summe = summe + lauf;&lt;br /&gt;
   lauf += 2;                  /* Inkrement */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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 1 bis 10 hat, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von 1 bis kleinergleich 10 gespeichert.&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 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 = 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;
=Ein- und Ausgabe=&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;
&lt;br /&gt;
=Allgemeines zu Unterprogrammen=&lt;br /&gt;
Stellen Sie sich vor, Sie haben einen eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben (was Zeit beim Erstellen und Speicherplatz im ausführbaren Programm kostet), können Sie den Abschnitt in ein sogenanntes &amp;quot;Unterprogramm&amp;quot; schreiben. Dieses Unterprogramm können Sie dann von jeder Stelle ihre Hauptprogrammes aus aufrufen.&lt;br /&gt;
Anders als in anderen Programmiersprachen gibt es in C keine generelle Unterscheidung zwischen Funktionen und Prozeduren. Trotzdem möchte ich kurz darauf eingehen: &lt;br /&gt;
&lt;br /&gt;
==Funktionen==&lt;br /&gt;
'''Syntax:''' Rückgabe-Typ Name(Parameterliste);&lt;br /&gt;
&lt;br /&gt;
Funktionen sind Unterprogramme, die am Ende der Ausführung einen Wert zurückliefern, wie z.B. getch. Paradebeispiele für die Anwendung einer Funktion sind jedoch mathematische Formeln: &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 hoch2 (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 (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, 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;zahl1);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = hoch2 (zahl1);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;,zahl1, ergebnis);&lt;br /&gt;
  printf (&amp;quot;5 hoch 2 = %d\n&amp;quot;, hoch2(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;
'''Bemerkungen zum Programm:''' &lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur außerhalb von Blöcken. Siehe auch Prototypen. &lt;br /&gt;
Geschachtelte-Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
In der Deklaration der Funktion kommt zuerst der Rückgabe-Datentyp. Jede Funktion liefert einen Wert zurück, dieser Datentyp gibt den Typ der Variablen an. Danach folgt der Name der Funktion (case-sensitiv!). Dann kommt in Klammern die Parameter-Liste. Dabei handelt es sich um eine Liste von Parametern, die jeweils durch Typ und Name angegeben werden und mittels Komma voneinander getrennt werden.&lt;br /&gt;
Im Block der Funktion können lokale Variablen definiert werden und alle Anweisungen ausgeführt werden. &lt;br /&gt;
Am Ende der Funktion muß diese ordnungsgemäß beendet werden. Dies geschieht mittels der Anweisung &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; und dem Rückgabewert. &lt;br /&gt;
Um eine Funktion aufzurufen (aus einem anderen Unterprogramm oder main), geben Sie folgendes an&lt;br /&gt;
 variable = Funktion (Parameter);&lt;br /&gt;
 Bei Variable muß es sich jedoch nicht unbedingt um eine von Ihnen deklarierte Variable handeln. Es kann z.B. auch der Parameter für ein weiteres Unterprogramm sein (wie im Beispiel, letzte Zeile). &lt;br /&gt;
Die Einrückungen der Anweisungen innerhalb der Funktion nach rechts ist nicht notwendig, sie dient jedoch der Übersicht und ist sehr empfehlenswert.&lt;br /&gt;
&lt;br /&gt;
==Prozedur==&lt;br /&gt;
'''Syntax:''' &amp;lt;tt&amp;gt;void Name (Parameterliste)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Prozedur ist nichts anderes als eine Funktion mit dem speziellen  Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der kennzeichnet, daß die Funktion keinen Wert zurückliefert. Sie ist daher prinzipiell gleich aufgebaut wie eine Funktion, bis auf die folgenden Unterschiede: &lt;br /&gt;
&lt;br /&gt;
Als Rückgabe-Datentyp wird &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; angegeben. &lt;br /&gt;
Einer Variablen kann daher nicht der Rückgabewert einer &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion zugewiesen werden, da diese garkeinen Rückgabewert liefert.&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 param1)&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Der Wert der Variablen ist: %d\n&amp;quot;, param1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
   int zahl1 = 4;&lt;br /&gt;
   &lt;br /&gt;
   ausgeben (23);&lt;br /&gt;
   ausgeben (zahl1);&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;
'''Bemerkungen zum Programm:''' &lt;br /&gt;
Durch den Befehl &amp;quot;&amp;lt;tt&amp;gt;ausgeben(23)&amp;lt;/tt&amp;gt;&amp;quot; wird die Prozedur &amp;quot;&amp;lt;tt&amp;gt;ausgeben&amp;lt;/tt&amp;gt;&amp;quot; mit dem Parameter &amp;lt;tt&amp;gt;23&amp;lt;/tt&amp;gt; aufgerufen. &amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt; hat also den Wert &amp;lt;tt&amp;gt;23&amp;lt;/tt&amp;gt;. Die einzige Anweisung innerhalb der Prozedur ist &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;, was nun ausgeführt wird. &lt;br /&gt;
Der zweite Aufruf von &amp;lt;tt&amp;gt;ausgeben&amp;lt;/tt&amp;gt; erfolgt mit dem Parameter &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, also wird &amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt; der Wert 4 zugewiesen. Dieser wird nun wieder mittels &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; ausgeben. &lt;br /&gt;
&lt;br /&gt;
Unterprogramme ohne Parameter&lt;br /&gt;
Das ist ihnen sicherlich schon aufgefallen: Viele Unterprogramme, haben statt einer Parameterliste nur &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; stehen. Das &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; bedeutet &amp;quot;die Funktion erhält keine Parameter&amp;quot;. &amp;quot;&amp;lt;tt&amp;gt;void main (void)&amp;lt;/tt&amp;gt;&amp;quot; bedeutet also: &amp;quot;Erstelle ein Unterprogramm Namens &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keinen Rückgabewert und keine Parameter hat&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen Sie beim Aufruf trotzdem die Klammern angeben. Beispiel für eine parameterlose Funktion &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 foo();&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;
&lt;br /&gt;
Beispiele:&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;
   /* a ist immer noch 0 */&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;
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 x übergeben. Dass dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void erhoehe (int *x)&lt;br /&gt;
{&lt;br /&gt;
   /* erhöhe 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;
   /* a ist jetzt 1 */&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;
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 Operator &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&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&lt;br /&gt;
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&lt;br /&gt;
den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;
  /* a hat jetzt folgenden Inhalt: 11, 23, 35 */&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;
&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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* 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;
  /* a hat jetzt folgenden Inhalt: 11, 23, 35 */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;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;
=Standard-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;
&lt;br /&gt;
&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;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der Computer 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 scanf - da übergeben Sie ja auch die Adresse einer Variablen (&amp;quot;&amp;amp;Variable&amp;quot;). &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 = *zeiger+1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main (void)&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;
==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: &amp;quot;dir *.exe&amp;quot;, &amp;quot;copy *.* a:&amp;quot; oder &amp;quot;ls -la&amp;quot;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;&amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen! &lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
&lt;br /&gt;
* [[#Speicherklassen|auto]]&lt;br /&gt;
* break&lt;br /&gt;
* [[#Elementare Datentypen|double]]&lt;br /&gt;
* [[#Elementare Datentypen|char]]&lt;br /&gt;
* case&lt;br /&gt;
* [[#Konstanten|const]]&lt;br /&gt;
* continue&lt;br /&gt;
* default&lt;br /&gt;
* do&lt;br /&gt;
* else&lt;br /&gt;
* enum&lt;br /&gt;
* [[#Speicherklassen|extern]]&lt;br /&gt;
* [[#Elementare Datentypen|float]]&lt;br /&gt;
* for&lt;br /&gt;
* goto&lt;br /&gt;
* if&lt;br /&gt;
* [[##Elementare Datentypen|int]]&lt;br /&gt;
* [[#Elementare Datentypen|long]]&lt;br /&gt;
* return&lt;br /&gt;
* [[#Speicherklassen|register]]&lt;br /&gt;
* [[#Elementare Datentypen|short]]&lt;br /&gt;
* signed&lt;br /&gt;
* sizeof&lt;br /&gt;
* [[#Speicherklassen|static]]&lt;br /&gt;
* [[#Strukturen|struct]]&lt;br /&gt;
* switch&lt;br /&gt;
* typedef&lt;br /&gt;
* [[#Unions|union]]&lt;br /&gt;
* unsigned&lt;br /&gt;
* [[#Elementare Datentypen|void]]&lt;br /&gt;
* volatile&lt;br /&gt;
* while&lt;br /&gt;
&lt;br /&gt;
Baustelle&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
Baustelle&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung || Nebeneffekte&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; == &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || ist gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; != &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || ist nicht gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;lt; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt;  || ist kleiner &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;lt;= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || ist kleiner oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;gt; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt;  || ist größer &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;gt;= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || ist größer oder gleich &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;amp; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; = &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; += &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; -= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; *= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; /= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; ^= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; |= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++ &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; ++&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-- &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; --&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;amp;&amp;amp; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~ &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;! &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;(&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/font&amp;gt;) &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; + &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; - &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; * &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; / &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; % &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Lvalue&amp;gt;&amp;lt;/font&amp;gt; %= &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;(&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Bedingung&amp;gt;&amp;lt;/font&amp;gt;) ? &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt; : &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Struct&amp;gt;&amp;lt;/font&amp;gt;.&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Komponenten-Bezeichner&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Zeiger-auf-Struct&amp;gt;&amp;lt;/font&amp;gt;-&amp;gt;&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Komponenten-Bezeichner&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Autoren'''&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
* Kernighan und Ritchie - Buch&lt;br /&gt;
* Christian Wirth , C Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://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>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=8116</id>
		<title>C-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=C-Tutorial&amp;diff=8116"/>
				<updated>2006-07-05T09:48:41Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Aufbau eines C-Programmes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ein kurzer Einblick in die Programmiersprache C&lt;br /&gt;
=Allgemeines=&lt;br /&gt;
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 Sprachedefinition entwickelt. C ist mittlerweile von ANSI und ISO standardisiert.&lt;br /&gt;
Heutzutage ist C (und ihr Nachfolger C++) die dominierende Programmiersprache. Sehr viele Anwendungen sind in C geschrieben. Leider ist C jedoch nicht einfach zu lernen, daher eignet es sich nur bedingt für Anfänger. Mit etwas Übung kann man damit jedoch sehr effiziente Programme schreiben.&lt;br /&gt;
&lt;br /&gt;
C ist sehr eng an Assembler angelehnt, aber trotzdem Hardware-unabhängig. Das bedeutet, Sie können maschinennahe Programme sehr leicht (aber nicht ganz ohne Aufwand) auf ein anderes System portieren. Sie benötigen dazu 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;
&amp;lt;pre&amp;gt;&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;
   /* Anweisungen */&lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Beschreibung (die Erklärungen folgen): &lt;br /&gt;
&lt;br /&gt;
;&amp;lt;nowiki&amp;gt;#include &amp;lt;...&amp;gt;&amp;lt;/nowiki&amp;gt;: Die Include-Direktive sagt dem Compiler, welche Header-Dateien er einbinden soll. In den Header-Dateien und den dazugehörigen Bibliotheken stehen Funktionen und Datentypen, die nicht im Compiler selbst implementiert sind, etwa komplexe Ausgabefunktionen wie &amp;quot;&amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;&amp;quot;, die weiter unten erklärt wird. Durch den Include kann man solche Funktionen nutzen. Elementare Dinge hingegen, wie die mathematischen Operatoren &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;, etc. sind im Compiler selbst eingebaut.&lt;br /&gt;
;int Zahl1;: Diese Zeile definiert eine Variable vom Typ int. Diese Variable ist im ganzen Programm gültig, sie ist ''global''. Jede Deklaration/Anweisung in C wird mit einem Strichpunkt (Semikolon  &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt;) abgeschlossen und dadurch von der nächsten Deklaration/Anweisung getrennt.&lt;br /&gt;
;char Zeichen1;: Hier geschieht das selbe, nur wird diesmal eine Variable des [[#Datentypen|Types char]] definiert. &lt;br /&gt;
;int main (void): definiert ein Unterprogramm mit dem Namen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keine Parameter hat (&amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;) und eine ganze Zahl ([[#Datentypen|&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;]]) zurückliefert. &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot; ist das Hauptprogramm in C, wo mit der Ausführung nach dem Programmstart begonnen wird.&lt;br /&gt;
;{: Die linke geschwungenen Klammer beginnt den Rumpf (auch &amp;quot;''body''&amp;quot; genannt) der main-Funktion. Danach folgen Variablendefinitionen, Kommentare und Anweisungen von &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;int zahl2;: Innerhalb von &amp;quot;main&amp;quot; wird die lokale Variable &amp;lt;tt&amp;gt;zahl2&amp;lt;/tt&amp;gt; definiert. &lt;br /&gt;
;/* Anweisungen */: Das ist ein Kommentar in C. Hier kann man Anmerkungen zum Code hinschreiben oder Codestücke &amp;quot;auskommentieren&amp;quot;, um sie zu deaktivieren. Der Kommentar beginnt mit &amp;lt;tt&amp;gt;/*&amp;lt;/tt&amp;gt; und wird beendet mit einem &amp;lt;tt&amp;gt;*/&amp;lt;/tt&amp;gt;. Er kann mehrere Zeilen überspannen. Je nach C-Compiler werden auch einzeilige Kommentare mit &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; akzeptiert, die nur bis zum nächsten Zeilenende reichen. Sie gehören jedoch nicht zum standard ANSI-C. Die Leerzeile nach dem Kommentar wird nicht weiter berücksichtig, sie kann zur Untergliederung des Codes zur besseren Lesbarkeit eingefügt werden.&lt;br /&gt;
;return 0;: Gibt den Wert&amp;amp;nbsp;0 zurück und beendet das Programm. Vor dem &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; können natürlich noch C-Anweisungen stehen, die aber erst weiter unten erklärt werden.&lt;br /&gt;
;}: Die schliessende geschwungenen Klammer beendet den Rumpf des Hauptprogramms.&lt;br /&gt;
&lt;br /&gt;
=Das Hauptprogramm main=&lt;br /&gt;
Die erste Funktion, die nach dem Programmstart ausgeführt wird, ist immer die Funktion mit dem Namen &amp;quot;&amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;&amp;quot;. Diese ist das Hauptprogramm. &lt;br /&gt;
&lt;br /&gt;
Der main-Funktion können beim PC Parameter übergeben werden. Dies sind die sogenannten Kommandozeilenparameter, die beim Aufruf eines Programmes hinter dem Dateinamen stehen. Zudem wird auch ein int-Wert als Ergebnis zurückgeliefert, der den Aufrufer &amp;amp;ndash; üblicher weise eine Shell &amp;amp;ndahs; den Erfolg bzw. Fehlerstatus des Programmes mitteilt. &lt;br /&gt;
&lt;br /&gt;
Beim [[Microcontroller]] ist &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; das Startprogramm, das nach dem RESET aufgerufen wird. Hier gibt es also keine Funktionsparameter. Ein Rückgabewert ist auch nicht sinnvoll, so daß &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; oft als  &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion (ohne Rückgabewert) definiert wird. Um Compilerfehler/Warnungen zu vermeiden, muss der Compiler dann aber mit speziellen Einstellungen gestartet werden, denn C-Standard ist, daß main einen Wert zurückliefert!&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* &lt;br /&gt;
 * void Definition von main ist nur beim Controller üblich&lt;br /&gt;
 * spezielle Compilereinstellungen sind nötig, damit bei dieser Definition von main&lt;br /&gt;
 * kein Fehler/Warnung erzeugt wird. &lt;br /&gt;
 */&lt;br /&gt;
void main (void)&lt;br /&gt;
{&lt;br /&gt;
   ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Blöcke=&lt;br /&gt;
Im vorigen Abschnitt haben Sie bereits die geschwungenen Klammern { und } kennen gelernt. Doch was bedeuten Sie? Einem Pascal-Kenner ist das schnell erklärt: { entspricht BEGIN, } entspricht END. Wenn ihnen auch das unbekannt ist, dann hilft Ihnen hoffentlich die folgende Erklärung.&lt;br /&gt;
Programme sind in Abschnitte unterteilt. Da gibt es zum einen das Hauptprogramm und die jeweiligen Unterprogramme, aber auch Schleifen und bedingte Anweisungen. Jedes dieser Beispiele stellt ein eigenständiges Stück Code dar. Daher müssen Sie es auch als solches kennzeichnen. Dies geschieht mit { und }. { bedeutet so viel wie &amp;quot;Block Anfang&amp;quot; und } bedeutet &amp;quot;Block Ende&amp;quot;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (void)&lt;br /&gt;
{    /* der Block &amp;quot;main&amp;quot; beginnt */&lt;br /&gt;
   int zahl;&lt;br /&gt;
   &lt;br /&gt;
   {   /* ein Block beginnt */&lt;br /&gt;
       /* hier können Deklarationen und stehen Anweisungen stehen */&lt;br /&gt;
   }   /* der Block endet */&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
}    /* &amp;quot;main&amp;quot; endet */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Bemerkung:''' &lt;br /&gt;
Der &amp;quot;namenlose&amp;quot; Block ist eigentlich unnötig. In den folgenden Kapiteln lernen Sie jedoch bessere Beispiele kennen! &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 recht der Wertebereich von &amp;lt;tt&amp;gt;-2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''-1&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Bei Ganzzahl-Typen ohne Vorzeichen reicht der Wertebereich von &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; bis zu &amp;lt;tt&amp;gt;2&amp;lt;sup&amp;gt;''b''&amp;lt;/sup&amp;gt;-1&amp;lt;/tt&amp;gt;, wenn der Typ ''b'' Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
! Größe (Bit) || Typ || Vorzeichen || colspan=&amp;quot;2&amp;quot;| Grenzen des Wertebereichs&lt;br /&gt;
|- &lt;br /&gt;
| 8  || &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; &lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -128&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 127&amp;lt;br /&amp;gt;255&lt;br /&gt;
|- &lt;br /&gt;
| 16 || &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -32.768&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32.767&amp;lt;br /&amp;gt;65.535&lt;br /&gt;
|- &lt;br /&gt;
| 32 || &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -2.147.483.648&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2.147.483.647&amp;lt;br /&amp;gt;4.294.967.295&lt;br /&gt;
|- &lt;br /&gt;
| 64 || &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | -9.223.372.036.854.775.808&amp;lt;br /&amp;gt;0&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 9.223.372.036.854.775.807&amp;lt;br /&amp;gt;18.446.744.073.709.551.615&lt;br /&gt;
|-&lt;br /&gt;
|8, 16, 32, 64&amp;lt;br/&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;signed&amp;lt;/tt&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt;&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|plattform-/compilerabhängig&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Boolean (Logische Variablen)====&lt;br /&gt;
In der Sprache C gibt es keinen Datentyp für boolsche Werte &amp;quot;wahr&amp;quot; bzw. &amp;quot;TRUE&amp;quot; oder &amp;quot;falsch&amp;quot; bzw. &amp;quot;FALSE&amp;quot;. Statt dessen wird gerne der Datentyp &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; dafür verwendet.&lt;br /&gt;
Hat die jeweilige Variable den Wert 0, so ist sie FALSE, sonst (ungleich 0) ist sie TRUE.&lt;br /&gt;
;Hinweis: Bitte beachten, daß eine Variable, die TRUE ist, nicht unbedingt den Wert&amp;amp;nbsp;1 haben muß. Sie muß lediglich ungleich&amp;amp;nbsp;0 sein!&lt;br /&gt;
&lt;br /&gt;
====char (Zeichen)====&lt;br /&gt;
In einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variable können Sie 8-Bit-Werte speichern. Dieser Datentyp wird oft für ASCII-Zeichen genutzt, denn für den Computer ist es egal, ob sich eine Zahl oder ein Zeichen in der Variablen befindet. Er speichert alles in Form von Binärzahlen. &lt;br /&gt;
&lt;br /&gt;
Dabei darf man eines nicht vergessen: Es macht einen großen Unterschied, ob man in einer &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;-Variablen das Zeichen &amp;lt;tt&amp;gt;'1'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 49) abspeichert, oder die Zahl &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (das entspricht ASCII-Zeichen Nr. 1, also irgendeinem Sonderzeichen). Man kann zwar mit beiden rechnen, aber &amp;lt;tt&amp;gt;'1' * 2&amp;lt;/tt&amp;gt; ergibt nicht &amp;lt;tt&amp;gt;'2'&amp;lt;/tt&amp;gt;, sondern &amp;lt;tt&amp;gt;'b'&amp;lt;/tt&amp;gt; (ASCII-Zeichen Nr. 98)!&lt;br /&gt;
&lt;br /&gt;
===float, double (Gleitkommazahlen)===&lt;br /&gt;
In einer Gleitkomma-Variable können Kommazahlen gespeichert werden, z.B. 3.141592654. &lt;br /&gt;
&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; reicht für die meisten Kommazahlen. Werden jedoch noch höhere Genauigkeiten benötigt, kommt der Datentyp &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; zum Einsatz.&lt;br /&gt;
;Vorsicht: bei PIC (microchip) ist die innere Darstellung dieser Zahlen anders als bei den meisten anderen Compilern, beim binären Senden z.B. zum PC muß dann konvertiert werden! Bei [[avr-gcc]] finden die Rechnungen intern mit &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; statt, auch wenn ein Typ als &amp;lt;tt&amp;gt;double&amp;lt;/tt&amp;gt; deklariert ist.&lt;br /&gt;
&lt;br /&gt;
===void===&lt;br /&gt;
Dies ist ein spezieller Typ, der soviel bedeutet wie &amp;quot;nicht vorhanden&amp;quot;. Eine Funktion, die keinen Rückgabewert zurückliefert, definiert als Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, und kennzeichnet damit, daß sie eben nichts zurückliefert. Objekte vom Typ &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; können nicht angelegt werden.&lt;br /&gt;
&lt;br /&gt;
==Zeiger==&lt;br /&gt;
Jede Variable steht an einer definierten Stelle im Speicher, an ihrer sogenannten ''Adresse''. &lt;br /&gt;
&lt;br /&gt;
Ein Zeiger ist eine Variable, in der eine Adresse gespeichert werden kann. Diese stellt eine bestimmte Position im Arbeitsspeicher dar. Die Adresse eines Objektes erhält man, indem man ihm ein&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; voranstellt. Die Umkehrung davon &amp;amp;ndash; also der Zugriff auf die Speicherstelle, die im Zeiger enthalten ist &amp;amp;ndash; erledigt ein vorgestellter&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;. Der Operator &amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; gibt also den ''Inhalt'' der Adresse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
  int * zeiger;&lt;br /&gt;
  int zahl;&lt;br /&gt;
 &lt;br /&gt;
  zeiger = &amp;amp;zahl;&lt;br /&gt;
  *zeiger = 12;&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d = %d&amp;quot;, zahl, *zeiger);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Definition von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; als Zeiger ist so zu lesen: Der Inhalt von &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; ist ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wird &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt; zu einem &amp;quot;Zeiger auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;&amp;quot;. Dabei gehört der&amp;amp;nbsp;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; sinngemäß zum Bezeichner &amp;lt;tt&amp;gt;zeiger&amp;lt;/tt&amp;gt;, nicht zum Typ. Folgende Definition definiert also nicht zwei Pointer, sondern einen Pointer (auf &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;) sowie einen &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 int * zeiger, zahl;&lt;br /&gt;
&lt;br /&gt;
Um den Zeiger mit der Adresse von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt; zu laden, schreibt man den Adress-Operator&amp;amp;nbsp;&amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt; von &amp;lt;tt&amp;gt;zahl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 zeiger = &amp;amp;zahl; &lt;br /&gt;
Jetzt möchten Sie der Speicherstelle, deren Adresse der Zeiger enthält, einen Wert zuweisen. Dazu verwendet man den &amp;quot;Inhalts-Operators&amp;quot; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;*zeiger = 12&amp;lt;/tt&amp;gt;). &lt;br /&gt;
Genauso können Sie mit dem Inhaltsoperator Werte abfragen und an &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; (und jedes andere Unterprogramm) übergeben.&lt;br /&gt;
&lt;br /&gt;
==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:''' Datentyp Variablenname[Anzahl]&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 3 Variablen. Da der Index immer bei 0 beginnt, greift man also mit [0], [1] und [2] 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;
&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 i;&lt;br /&gt;
  int zahlen[10];  /* zahlen[0] bis zahlen[9] !!! */&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i&amp;lt;10; 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;
  printf (&amp;quot;Super!\n&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  for (i=0; i&amp;lt;10; 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;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Bemerkungen:''' &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;
{{FarbigerRahmen|&lt;br /&gt;
'''Merke:'''&lt;br /&gt;
Wenn Sie einen ungültigen Index angeben (einen, der in der Deklaration nicht enthalten war) können je nach Compiler und Einstellung undefinierbare Dinge passieren, da dadurch andere Variableninhalte oder Programmcode überschrieben wird. Im schlimmsten Fall könnte sogar der Computer/Controller abstürzen. Also achten Sie darauf, daß Sie keine ungültigen Werte als Index angeben!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Strings (Zeichenketten)===&lt;br /&gt;
Ein String ist nicht sanderes 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ötigen 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;
&amp;lt;pre&amp;gt;&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;
&amp;lt;/pre&amp;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 vier Komponenten angelege: 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 dieses Typs &amp;lt;tt&amp;gt;struct Person&amp;lt;/tt&amp;gt; anzulegen, geben Sie einfach &lt;br /&gt;
 struct Person Variablenname;&lt;br /&gt;
an. &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;), einen Punkt und danach den Bezeichner der Komponente:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  struct Person hubert, klaus;&lt;br /&gt;
&lt;br /&gt;
  hubert.alter = 32;&lt;br /&gt;
  klaus.alter = hubert.alter + 1;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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 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 Person u_person;&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_double&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;u_person&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;u_pointer&amp;lt;/tt&amp;gt;. Die Groß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.&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 chat 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.&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;
/* nun ist wert.as_long gleich 0xab345678 oder 0x123456ab (je nach Plattform) */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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;
Teilweise erlauben C-Compiler auch die Verwendung des Dollar-Zeichens &amp;lt;tt&amp;gt;'''$'''&amp;lt;/tt&amp;gt; in Variablennaben.&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;
&amp;lt;pre&amp;gt;&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;
  /* Anweisungen */&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
;Erklärung: 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;wahr&amp;quot;, ansonsten ist sie &amp;quot;unwahr&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;
==Vergleich von Variablen==&lt;br /&gt;
Sie können Variablen miteinander vergleichen. Das geschieht mit einem der folgenden Zeichen mit den normalen mathematischen Regeln: &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;
Als Ergebnis bekommen Sie einen logischen Ausdruck in Form einer int-Zahl. &lt;br /&gt;
 intVariable = zahl1 &amp;lt;= zahl2;&lt;br /&gt;
das komplette Beispiel zeigt es deutlicher:&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;= z1  /* Ein Vergleich. Die int-Variable i wird wahr, da z1 kleiner als z2 */&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Ergebnis: %d\n&amp;quot;, i);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Die Variable &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; ist ungleich 0 (&amp;quot;wahr&amp;quot;), wenn z1 kleiner oder gleich z2 ist. Ist z1 jedoch größer als z2, dann ist &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; gleich 0 (&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 dafür ein Schlüsselwort in C:&lt;br /&gt;
 const ''datentyp'' name = value;  /* 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;  /* 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;. 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 Eigenheit 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, wenn das Ergebnis bereits feststeht. Die Ausdrücke werden&lt;br /&gt;
dabei immer von links nach rechts ausgewertet.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
  (x &amp;gt; 5) || datei_auf_festplatte_gefunden(&amp;quot;hallo.txt&amp;quot;) /* gut */&lt;br /&gt;
  datei_auf_festplatte_gefunden(&amp;quot;hallo.txt&amp;quot;) || (x &amp;gt; 5) /* nicht so gut */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;datei_auf_festplatte_gefunden&amp;lt;/tt&amp;gt; ist fiktiv und steht für eine Funktion,&lt;br /&gt;
die eine aufwändige Operation durchführt.&lt;br /&gt;
Beide Zeilen ergeben &amp;lt;tt&amp;gt;wahr&amp;lt;/tt&amp;gt; wenn die Variable x einen Wert größer 5 hat oder&lt;br /&gt;
es eine Datei namens &amp;lt;tt&amp;gt;hallo.txt&amp;lt;/tt&amp;gt; auf der Festplatte gibt.&lt;br /&gt;
&lt;br /&gt;
Wo ist also der Unterschied?&amp;lt;br&amp;gt;&lt;br /&gt;
In der ersten Zeile wird geprüft, ob x größer als 5 ist und wenn das der Fall ist,&lt;br /&gt;
dann wird ''nicht mehr geprüft'', ob &amp;lt;tt&amp;gt;hallo.txt&amp;lt;/tt&amp;gt; auf der Festplatte existiert.&lt;br /&gt;
In der zweiten Zeile wird ''immer geprüft'', ob &amp;lt;tt&amp;gt;hallo.txt&amp;lt;/tt&amp;gt; auf der Festplatte&lt;br /&gt;
existiert und erst, wenn sie nicht gefunden wird, wird die Variable x ausgewertet.&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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  int x = 5;    /* x ist eine Integervariable und hat den Wert 5 */&lt;br /&gt;
&lt;br /&gt;
  /* z ist ein Zeiger auf eine Integervariable und enthält somit&lt;br /&gt;
     die Speicheradresse einer Integervariablen&lt;br /&gt;
  */&lt;br /&gt;
  int *z;       &lt;br /&gt;
&lt;br /&gt;
  /* Verwendung des Adressoperators... */&lt;br /&gt;
  z = &amp;amp;x;       /* weise z die Speicheradresse von x zu */&lt;br /&gt;
&lt;br /&gt;
  /* Verwendung der Dereferenzierung */&lt;br /&gt;
  /* erhöhe den Wert, der bei Adresse z steht um eins */&lt;br /&gt;
  *z = *z + 1;&lt;br /&gt;
&lt;br /&gt;
  /* da z auf x zeigt, hat auch x jetzt den Wert 6 */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da in C häufig Zeiger auf [[C-Tutorial#Strukturen | Strukturen]] verwendet werden, ist für den Zugriff&lt;br /&gt;
auf ein Element 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;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&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&lt;br /&gt;
auf eine gültige Speicheradresse verweist. Folgendes Codestück führt zum Absturz oder zu&lt;br /&gt;
einer Änderung '''irgendeiner''' Speicherstelle:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   int *z; /* z ist ein Zeiger auf einen Integer */&lt;br /&gt;
&lt;br /&gt;
   /* An dieser Stelle ist z immer noch keine Speicheradresse zugewiesen.&lt;br /&gt;
      z enthält irgendeine(!) Adresse&lt;br /&gt;
   */&lt;br /&gt;
&lt;br /&gt;
   /* &amp;quot;Erhöhe einen Integer irgendwo im Speicher um 1&amp;quot; -&amp;gt; CRASH */&lt;br /&gt;
   *z = *z + 1;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Viele C-Compiler (z.B. gcc) erzeugen in der Standardeinstellung für das obige Codestück ''keine Warnung''!&lt;br /&gt;
}}&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'' durch, sondern unterdrückt nur die Compilerwarnungen oder&lt;br /&gt;
-fehler, die bei einer &amp;quot;verdächtigen&amp;quot; Umwandlung passieren. Er kann also nicht benutzt werden, um einen Text in&lt;br /&gt;
eine Zahl oder umgekehrt zu wandeln:&lt;br /&gt;
&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;
&lt;br /&gt;
Ausgegeben wird weder 5 noch 6 sondern die Speicheradresse, an der der Text &amp;quot;5.6&amp;quot; beginnt. Der Cast-Operator&lt;br /&gt;
unterdrückt nur die Warnung, die auf den Fehler hinweisen will.&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;
==Zuweisungen und Operatoren mit Nebeneffekt==&lt;br /&gt;
===Bedingte Zuweisung===&lt;br /&gt;
 lvalue = (bediungung) ? if-ausdruck : else-ausdruck;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Kein ANSI-C&lt;br /&gt;
--[[Benutzer:SprinterSB|SprinterSB]] 17:15, 29. Jun 2006 (CEST)&lt;br /&gt;
==Blöcke==&lt;br /&gt;
Selbst Blöcke haben in C einen Wert, der in einer Berechnung verwendet werden kann.&lt;br /&gt;
Der Wert eines Blockes ist der Wert der letzten Anweisung des Blocks. &lt;br /&gt;
Der Block muss un runden Klammern stehen:&lt;br /&gt;
 int sum;&lt;br /&gt;
 sum = ({&lt;br /&gt;
    int i, s = 0;&lt;br /&gt;
    for (i=1; i&amp;lt;= 100; i++)&lt;br /&gt;
       s += i;&lt;br /&gt;
    s;&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel ist das Makro &amp;lt;tt&amp;gt;PSTR&amp;lt;/tt&amp;gt; von avr-gcc, &lt;br /&gt;
das einen String ins Flash legt und die Adresse zurückliefert, was nur in einer&lt;br /&gt;
Instruktion nicht machbar wäre:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define PSTR(s)                         \&lt;br /&gt;
  ({                                    \ &lt;br /&gt;
      static char __c[] PROGMEM = (s);  \&lt;br /&gt;
      __c;                              \&lt;br /&gt;
  })&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reihenfolge der Auswertung==&lt;br /&gt;
&lt;br /&gt;
=Kontrollanweisungen=&lt;br /&gt;
&lt;br /&gt;
==Boolsche Logik==&lt;br /&gt;
Boolean-Variablen können miteinander verknüpft werden. Dies geschieht mit den boolschen Operatoren &amp;amp;&amp;amp; ( logisches &amp;quot;und&amp;quot;), || (logisches &amp;quot;oder&amp;quot;) und ! (logisches &amp;quot;nicht&amp;quot;) (es gibt noch weitere, auf die hier nicht eingegangen wird). &lt;br /&gt;
&lt;br /&gt;
 b1= b2 &amp;amp;&amp;amp; b3;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der Wert von b1 ist dann 1 (TRUE), wenn b2 und (&amp;quot;AND&amp;quot;) b3 1 (TRUE) sind. Ist eine der beiden (oder auch beide) 0 (FALSE), dann ist b1 ebenfalls 0 (FALSE).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 b1= b2 || b3;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der Wert von b1 ist dann TRUE, wenn b2 oder (&amp;quot;OR&amp;quot;) b3 TRUE ist. Ist also einer (oder beide) TRUE, dann ist auch b1 TRUE, sind beide FALSE, ist auch b1 FALSE.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 b1= !b2;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der Wert von b1 ist dann TRUE, wenn der von b2 FALSE ist. Die NOT Verknüpfung &amp;quot;dreht den logischen Wert der Variablen um&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==&amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;-Anweisung==&lt;br /&gt;
Syntax: IF (Bedingung) Anweisung;&lt;br /&gt;
Mit Hilfe der IF Anweisung kann man Codeteile (Blöcke) ausführen lassen, wenn die dazugehörige Bedingung erfüllt (TRUE) ist. Im Flussdiagramm sieht eine If-Anweisung folgendermassen aus:&lt;br /&gt;
&lt;br /&gt;
[[bild:ifthenelse.png]]&lt;br /&gt;
&lt;br /&gt;
Und in C schreibt man:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if (Bedingung)        /* WENN */&lt;br /&gt;
{                     /* DANN */&lt;br /&gt;
       Anweisung1;&lt;br /&gt;
       Anweisung2;&lt;br /&gt;
       ...&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{                     /* SONST */&lt;br /&gt;
       Anweisung3;&lt;br /&gt;
       Anweisung4;&lt;br /&gt;
       ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wenn die Bedingung wahr ist wird Anweisung1 ausgeführt. Anschliessend wird aus der If-Bedingung herausgesprungen. Anweisung2 wird also nicht ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Ist die Bedingung unwahr wird gleich zu Anweisung2 gesprungen, diese ausgeführt, und anschliessend wird die If-Bedingung beendet.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen | &lt;br /&gt;
'''Achtung!'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Ein häufiger Fehler ist statt if(a == 23) etwas wie if(a = 23) zu schreiben. Hier wird allerdings nicht geprüft ob die Variable a gleich 23 ist, sondern der Variable a wird der Wert 23 zugewiesen, und das ist eine wahre Aussage. Anschliessend wird demzufolge der &amp;quot;DANN&amp;quot;-Teil ausgeführt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Die Syntax hierbei ist allerdings korrekt, der Compiler wird also keinen Fehler ausspucken. Somit ist dieser kleine Fehler sehr schwer zu finden. Abhilfe schafft die Schreibweise if(23 == a). Wenn man dort anstatt des Vergleichsoperator '==' den Zuweisungsoperator '=' verwendet spuckt der Compiler sehr wohl einen Fehler aus.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ein weiterer häufiger Fehler ist das schreiben von if(Bedingung)''';''' Richtig müsste es heissen &amp;quot;if(Bedingung)&amp;quot; Das fehlerhafte Semikolon im ersten Fall interpretiert der Compiler bereits als Anweisung. Auch hier liegt kein Syntaxfehler vor und der Compiler schweigt. Hier also ebenfalls besser zweimal hinschauen.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==&amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt;-Anweisung==&lt;br /&gt;
Syntax: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
switch(ausdruck) {&lt;br /&gt;
    case wert1:&lt;br /&gt;
        Anweisungen1...&lt;br /&gt;
    case wert2:&lt;br /&gt;
        Anweisungen2...&lt;br /&gt;
    case wert3:&lt;br /&gt;
        Anweisungen3...&lt;br /&gt;
    ...&lt;br /&gt;
    default:&lt;br /&gt;
        Anweisungen4...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der &amp;lt;tt&amp;gt;ausdruck&amp;lt;/tt&amp;gt; muss eine Ganzzahl (int) ergeben und wird dann der Reihe nach mit den Werten, die hinter&lt;br /&gt;
den &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Anweisungen angegeben sind verglichen. Bei einer Übereinstimmung werden alle Befehle ab der&lt;br /&gt;
zutreffenden Case-Anweisung ausgeführt. Stimmt der &amp;lt;tt&amp;gt;ausdruck&amp;lt;/tt&amp;gt; mit keinem der Werte hinter &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;&lt;br /&gt;
überein, so wird der &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;-Abschnitt ausgeführt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Auch die Anweisungen der folgenden &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 eines&lt;br /&gt;
&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, muss aber nach allen &amp;lt;tt&amp;gt;case&amp;lt;/tt&amp;gt;-Abschnitten angegeben werden,&lt;br /&gt;
wenn er verwendet wird.&lt;br /&gt;
&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;
===&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;-Schleife===&lt;br /&gt;
'''Syntax:''' while (Bedingung) { Anweisung; }&lt;br /&gt;
&lt;br /&gt;
Die WHILE-Schleife wird solange durchlaufen, wie die Bedingung erfüllt (TRUE) ist. Die Schleife wird also unter Umständen garnicht durchlaufen. Bei mehreren Anweisungen benötigen man einen Block! &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Zahl1=0;&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;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird die Schleife 3 mal durchlaufen. Zu Beginn des 4. Durchlaufes ist die Bedingung FALSE (Zahl1 ist dann nicht mehr kleiner, sondern gleich 3!), also wird mit dem Befehl nach der Schleife fortgesetzt.&lt;br /&gt;
===&amp;lt;tt&amp;gt;do&amp;lt;/tt&amp;gt;-&amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;-Schleife===&lt;br /&gt;
'''Syntax:''' do  { Anweisung; }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. Das ist dann sinnvoll, wenn der Vergleichswert für die Bedingung erst im Anweisungsblock gesetzt wird &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int i=2;&lt;br /&gt;
do &lt;br /&gt;
{&lt;br /&gt;
    i = i*i;   /* 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;
&amp;lt;/pre&amp;gt;&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.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;-Schleife===&lt;br /&gt;
'''Syntax:''' for (Zuweisung;Bedingung;Inkrement) { Anweisung; }&lt;br /&gt;
&lt;br /&gt;
Die FOR-Schleife ist eine spezielle WHILE-Variante für die Formulierung von Zählschleifen. Die angegebene Variable wird am Anfang auf einen Wert gesetzt. Danach wird sie nach jedem Durchlauf verändert (meist um 1 erhöht). Ist die Bedingung nicht mehr erfüllt, wird die Schleife beendet. Innerhalb des Anweisungsblockes können Sie auf die Variable zugreifen, d.h. Sie können sie auch verändern. Das ist jedoch nicht ratsam. Wollen Sie mehrere Anweisungen ausführen, benötigen Sie eine Block.&lt;br /&gt;
&lt;br /&gt;
Die gesammte Schleife wird solange durchgeführt, wie die Bedingung wahr ist (d.h. Sie brauchen garnicht die Zählvariable abfragen, Sie können hier auch jede andere Variable auswerten). Inkrement letztendlich wird nach jedem Schleifendurchlauf ausgeführt. Hier kann man z.B. den Zähler erhöhen.&lt;br /&gt;
&lt;br /&gt;
Die Theorie ist schwer, die Praxis nicht so sehr. In der Schleife wird die Summe ungerader Zahlen kleinergleich 10 berechnet. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int lauf;&lt;br /&gt;
int summe = 0;&lt;br /&gt;
&lt;br /&gt;
for (lauf = 1; lauf &amp;lt;= 10; lauf = lauf+2 ) &lt;br /&gt;
{&lt;br /&gt;
   summe = summe + lauf;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Das Äquivalent als &amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;-Schleife:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int lauf  = 1;                 /* Anfangswerte */&lt;br /&gt;
int summe = 0;&lt;br /&gt;
&lt;br /&gt;
while (lauf &amp;lt;= 10)             /* Bedingung */&lt;br /&gt;
{&lt;br /&gt;
   summe = summe + lauf;&lt;br /&gt;
   lauf += 2;                  /* Inkrement */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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 1 bis 10 hat, ist in &amp;lt;tt&amp;gt;summe&amp;lt;/tt&amp;gt; nach der Schleife die Summe der ungeraden Zahlen von 1 bis kleinergleich 10 gespeichert.&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 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 = 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;
=Ein- und Ausgabe=&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;
&lt;br /&gt;
=Allgemeines zu Unterprogrammen=&lt;br /&gt;
Stellen Sie sich vor, Sie haben einen eine Code-Folge, die mehrmals im Programm vorkommt, z.B. eine mathematische Formel. Anstatt dieses Codestück mehrmals zu schreiben (was Zeit beim Erstellen und Speicherplatz im ausführbaren Programm kostet), können Sie den Abschnitt in ein sogenanntes &amp;quot;Unterprogramm&amp;quot; schreiben. Dieses Unterprogramm können Sie dann von jeder Stelle ihre Hauptprogrammes aus aufrufen.&lt;br /&gt;
Anders als in anderen Programmiersprachen gibt es in C keine generelle Unterscheidung zwischen Funktionen und Prozeduren. Trotzdem möchte ich kurz darauf eingehen: &lt;br /&gt;
&lt;br /&gt;
==Funktionen==&lt;br /&gt;
'''Syntax:''' Rückgabe-Typ Name(Parameterliste);&lt;br /&gt;
&lt;br /&gt;
Funktionen sind Unterprogramme, die am Ende der Ausführung einen Wert zurückliefern, wie z.B. getch. Paradebeispiele für die Anwendung einer Funktion sind jedoch mathematische Formeln: &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 hoch2 (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 (void)&lt;br /&gt;
{&lt;br /&gt;
  int zahl1, 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;zahl1);&lt;br /&gt;
  &lt;br /&gt;
  ergebnis = hoch2 (zahl1);&lt;br /&gt;
  &lt;br /&gt;
  printf (&amp;quot;%d hoch 2 = %d\n&amp;quot;,zahl1, ergebnis);&lt;br /&gt;
  printf (&amp;quot;5 hoch 2 = %d\n&amp;quot;, hoch2(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;
'''Bemerkungen zum Programm:''' &lt;br /&gt;
Ein Unterprogramm kann an jeder beliebigen Stelle innerhalb eines Programmes stehen, aber nur außerhalb von Blöcken. Siehe auch Prototypen. &lt;br /&gt;
Geschachtelte-Unterprogramme sind in Standard-C nicht möglich. &lt;br /&gt;
In der Deklaration der Funktion kommt zuerst der Rückgabe-Datentyp. Jede Funktion liefert einen Wert zurück, dieser Datentyp gibt den Typ der Variablen an. Danach folgt der Name der Funktion (case-sensitiv!). Dann kommt in Klammern die Parameter-Liste. Dabei handelt es sich um eine Liste von Parametern, die jeweils durch Typ und Name angegeben werden und mittels Komma voneinander getrennt werden.&lt;br /&gt;
Im Block der Funktion können lokale Variablen definiert werden und alle Anweisungen ausgeführt werden. &lt;br /&gt;
Am Ende der Funktion muß diese ordnungsgemäß beendet werden. Dies geschieht mittels der Anweisung &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; und dem Rückgabewert. &lt;br /&gt;
Um eine Funktion aufzurufen (aus einem anderen Unterprogramm oder main), geben Sie folgendes an&lt;br /&gt;
 variable = Funktion (Parameter);&lt;br /&gt;
 Bei Variable muß es sich jedoch nicht unbedingt um eine von Ihnen deklarierte Variable handeln. Es kann z.B. auch der Parameter für ein weiteres Unterprogramm sein (wie im Beispiel, letzte Zeile). &lt;br /&gt;
Die Einrückungen der Anweisungen innerhalb der Funktion nach rechts ist nicht notwendig, sie dient jedoch der Übersicht und ist sehr empfehlenswert.&lt;br /&gt;
&lt;br /&gt;
==Prozedur==&lt;br /&gt;
'''Syntax:''' &amp;lt;tt&amp;gt;void Name (Parameterliste)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Prozedur ist nichts anderes als eine Funktion mit dem speziellen  Rückgabetyp &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;, der kennzeichnet, daß die Funktion keinen Wert zurückliefert. Sie ist daher prinzipiell gleich aufgebaut wie eine Funktion, bis auf die folgenden Unterschiede: &lt;br /&gt;
&lt;br /&gt;
Als Rückgabe-Datentyp wird &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; angegeben. &lt;br /&gt;
Einer Variablen kann daher nicht der Rückgabewert einer &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;-Funktion zugewiesen werden, da diese garkeinen Rückgabewert liefert.&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 param1)&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;Der Wert der Variablen ist: %d\n&amp;quot;, param1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
   int zahl1 = 4;&lt;br /&gt;
   &lt;br /&gt;
   ausgeben (23);&lt;br /&gt;
   ausgeben (zahl1);&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;
'''Bemerkungen zum Programm:''' &lt;br /&gt;
Durch den Befehl &amp;quot;&amp;lt;tt&amp;gt;ausgeben(23)&amp;lt;/tt&amp;gt;&amp;quot; wird die Prozedur &amp;quot;&amp;lt;tt&amp;gt;ausgeben&amp;lt;/tt&amp;gt;&amp;quot; mit dem Parameter &amp;lt;tt&amp;gt;23&amp;lt;/tt&amp;gt; aufgerufen. &amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt; hat also den Wert &amp;lt;tt&amp;gt;23&amp;lt;/tt&amp;gt;. Die einzige Anweisung innerhalb der Prozedur ist &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt;, was nun ausgeführt wird. &lt;br /&gt;
Der zweite Aufruf von &amp;lt;tt&amp;gt;ausgeben&amp;lt;/tt&amp;gt; erfolgt mit dem Parameter &amp;lt;tt&amp;gt;zahl1&amp;lt;/tt&amp;gt;, also wird &amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt; der Wert 4 zugewiesen. Dieser wird nun wieder mittels &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; ausgeben. &lt;br /&gt;
&lt;br /&gt;
Unterprogramme ohne Parameter&lt;br /&gt;
Das ist ihnen sicherlich schon aufgefallen: Viele Unterprogramme, haben statt einer Parameterliste nur &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; stehen. Das &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; bedeutet &amp;quot;die Funktion erhält keine Parameter&amp;quot;. &amp;quot;&amp;lt;tt&amp;gt;void main (void)&amp;lt;/tt&amp;gt;&amp;quot; bedeutet also: &amp;quot;Erstelle ein Unterprogramm Namens &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, das keinen Rückgabewert und keine Parameter hat&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen |&lt;br /&gt;
'''Merke:''' Auch wenn eine Funktion keine Parameter hat, müssen Sie beim Aufruf trotzdem die Klammern angeben. Beispiel für eine parameterlose Funktion &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 foo();&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;
&lt;br /&gt;
Beispiele:&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;
   /* a ist immer noch 0 */&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;
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 x übergeben. Dass dann die Prozedur &amp;lt;tt&amp;gt;erhoehe&amp;lt;/tt&amp;gt; die Kopie verändert, hat keine Auswirkung auf das Original &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; im Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void erhoehe (int *x)&lt;br /&gt;
{&lt;br /&gt;
   /* erhöhe 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;
   /* a ist jetzt 1 */&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;
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 Operator &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; auf den Wert an dieser Adresse zugreifen.&lt;br /&gt;
&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&lt;br /&gt;
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&lt;br /&gt;
den Originaldaten arbeiten und diese verändern.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;
  /* a hat jetzt folgenden Inhalt: 11, 23, 35 */&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;
&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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* 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;
  /* a hat jetzt folgenden Inhalt: 11, 23, 35 */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;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;
=Standard-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;
&lt;br /&gt;
&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;
Doch was ist, wenn Sie Parameter in Unterprogrammen verändern möchten? Ganz einfach, Sie verwenden Zeiger. Der Computer 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 scanf - da übergeben Sie ja auch die Adresse einer Variablen (&amp;quot;&amp;amp;Variable&amp;quot;). &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 = *zeiger+1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main (void)&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;
==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: &amp;quot;dir *.exe&amp;quot;, &amp;quot;copy *.* a:&amp;quot; oder &amp;quot;ls -la&amp;quot;. All diese Befehle sind aus zwei Teilen aufgebaut: Befehl und Parameter. Und genau diese Parameter können Sie mit den &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Parametern abfragen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[], char* environ[])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;&amp;lt;tt&amp;gt;argc&amp;lt;/tt&amp;gt;&amp;quot; handelt es sich um eine normale int-Variable (engl. &amp;quot;''argument count''&amp;quot;, &amp;quot;Parameter-Zähler&amp;quot;). In ihr steht die Anzahl der übergebenen Parameter. Die Parameter selbst folgen im zweiten Argument, das als Array von Strings übergeben wird. Das dritte Argument ist ein Array mit den Umgebungsvariablen. Seine Länge wird nicht explizit übergeben; nach dem letzten Element steht ein Null-String, also ein String der Länge&amp;amp;nbsp;0. In dieser Array befindet sich auch der Inhalt der Umgebungsvariablen &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt;, die den Suchpfad für ausführbare Programme enthält.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[], char * environ[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Es wurden %d Parameter angegeben&amp;quot;, argc);&lt;br /&gt;
&lt;br /&gt;
  for (i=0; i &amp;lt; argc; i++) &lt;br /&gt;
     printf (&amp;quot;Parameter %d: %s\n&amp;quot;, i, argv[i]);&lt;br /&gt;
&lt;br /&gt;
  for (i = 0; environ[i] != NULL; ++i) &lt;br /&gt;
     printf (&amp;quot;environ[%d] = %s\n&amp;quot;, i, environ[i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Erklärung: Bei der ersten Ausgabe wird ausgegeben, wie viele Parameter insgesammt angegeben wurden. Dabei gibt immer mindestens einen Parameter, nämlich &amp;lt;tt&amp;gt;argc[0]&amp;lt;/tt&amp;gt;. Dort steht der Name der aufgerufenen Datei selbst. Außerdem ist das letzte gültige Feldelement &amp;amp;ndash; wie in C üblich &amp;amp;ndash; das Element &amp;lt;tt&amp;gt;&amp;lt;tt&amp;gt;argv[argc-1]&amp;lt;/tt&amp;gt;. In der for-Schleife werden alle Parameter, inklusive ihrer Nummer, ausgegeben. Experimentieren Sie mit den Parametern, um das System zu vertehen! &lt;br /&gt;
&lt;br /&gt;
=Liste der Schlüsselworte=&lt;br /&gt;
&lt;br /&gt;
* [[#Speicherklassen|auto]]&lt;br /&gt;
* break&lt;br /&gt;
* [[#Elementare Datentypen|double]]&lt;br /&gt;
* [[#Elementare Datentypen|char]]&lt;br /&gt;
* case&lt;br /&gt;
* [[#Konstanten|const]]&lt;br /&gt;
* continue&lt;br /&gt;
* default&lt;br /&gt;
* do&lt;br /&gt;
* else&lt;br /&gt;
* enum&lt;br /&gt;
* [[#Speicherklassen|extern]]&lt;br /&gt;
* [[#Elementare Datentypen|float]]&lt;br /&gt;
* for&lt;br /&gt;
* goto&lt;br /&gt;
* if&lt;br /&gt;
* [[##Elementare Datentypen|int]]&lt;br /&gt;
* [[#Elementare Datentypen|long]]&lt;br /&gt;
* return&lt;br /&gt;
* [[#Speicherklassen|register]]&lt;br /&gt;
* [[#Elementare Datentypen|short]]&lt;br /&gt;
* signed&lt;br /&gt;
* sizeof&lt;br /&gt;
* [[#Speicherklassen|static]]&lt;br /&gt;
* [[#Strukturen|struct]]&lt;br /&gt;
* switch&lt;br /&gt;
* typedef&lt;br /&gt;
* [[#Unions|union]]&lt;br /&gt;
* unsigned&lt;br /&gt;
* [[#Elementare Datentypen|void]]&lt;br /&gt;
* volatile&lt;br /&gt;
* while&lt;br /&gt;
&lt;br /&gt;
Baustelle&lt;br /&gt;
&lt;br /&gt;
=Liste der Operatoren=&lt;br /&gt;
&lt;br /&gt;
Baustelle&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Operator || Bedeutung || Nebeneffekte&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;tt&amp;gt;&amp;amp;amp;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;+=&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-=&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;*=&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;/=&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;^=&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;=&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;|=&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;~&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;(&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Type&amp;gt;&amp;lt;/font&amp;gt;) &amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;&amp;lt;Ausdruck&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;/&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;%&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;%=&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;? : &amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;.&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;-&amp;gt;&amp;lt;/tt&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Autoren'''&lt;br /&gt;
* Plasma&lt;br /&gt;
* Bernd&lt;br /&gt;
* [[Benutzer:SprinterSB|SprinterSB]]&lt;br /&gt;
&lt;br /&gt;
'''Quellen:'''&lt;br /&gt;
* Kernighan und Ritchie - Buch&lt;br /&gt;
* Christian Wirth , C Tutorial&lt;br /&gt;
* Prof. Dr. J. Dankert Ausführungen&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
* [[Compiler]]&lt;br /&gt;
* [[WinAVR]]&lt;br /&gt;
* [[Fallstricke bei der C-Programmierung]]&lt;br /&gt;
&lt;br /&gt;
=Weblinks=&lt;br /&gt;
* [http://www.uni-bayreuth.de/departments/math/~rbaier/lectures/c_ss2002/html/html.html C-Tutorial Uni Bayreuth]&lt;br /&gt;
* [http://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>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Kategorie:Quellcode_C&amp;diff=8114</id>
		<title>Kategorie:Quellcode C</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Kategorie:Quellcode_C&amp;diff=8114"/>
				<updated>2006-07-05T09:00:56Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In dieser Kategorie finden sich dokumentierte Programmbeispiele in der Programmiersprache C. &lt;br /&gt;
Die Beispiele sind &amp;amp;ndash; sofern nicht anders angegeben &amp;amp;ndash; für den freien C/C++-Compiler [[avr-gcc]] Version 3.x. &lt;br /&gt;
&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
* Siehe auch die  [[avr-gcc#Inkompatibilität|Hinweise zu Inkompatibilitäten von avr-gcc]].&lt;br /&gt;
* Manche [[make]]file-Generatoren lieben es, unaufgefordert irgendwelche Compiler-Optionen zu aktivieren, welche die Semantik (Bedeutung) der C-Quelle ändern. Beliebt ist etwa der Schalter, &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; standardmässig auf &amp;lt;tt&amp;gt;unsigned&amp;lt;/tt&amp;gt; zu setzen, wahrscheinlich weil manche faule Entwickler selbiger Tools dadurch das Tippseln einiger Buchstaben erspart blieb. Wer seinen Compiler dergestalt verbiegt, darf nicht erstaunt sein, wenn Beispiel-Code aus dem Netz nicht funktioniert. Die Beispielcodes hier in {{SITENAME}} tragen dieser Unart in gewissem Maße Rechnung, jedoch ist niemandem &amp;amp;ndash; vor allem dem Einsteiger nicht &amp;amp;ndash; damit gedient, alle möglichen und unmöglichen Schalterstellungen aus den Quellen herauszuparametrisieren. Der geneigte Anwender entsprechender Generatoren ist daher gut damit beraten, die C-Semantik beim Standard zu belassen.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Diskussion:Codevergleich_AVR-Compiler&amp;diff=6770</id>
		<title>Diskussion:Codevergleich AVR-Compiler</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Diskussion:Codevergleich_AVR-Compiler&amp;diff=6770"/>
				<updated>2006-04-06T20:31:48Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hallo Sprinter (schreibe mal hier)&lt;br /&gt;
&lt;br /&gt;
In Formeln bin ich sehr schlecht, aber was hälst DU davon, wenn man dazu fixe Werte für die Variablen verwendet, einen Einheitlichen Prozessor (z.B. den Mega8) und einen Gleichbeleibenden Quarz.&lt;br /&gt;
Dann könnte man die Codes auch untereinander in der Ausführungszeit und dem Speicherverbrauch vergleichen..?&lt;br /&gt;
Mann müsste dann aber auch den kompletten Code aufzeigen...&lt;br /&gt;
(für C alle Libs..)--[[Benutzer:Roberto|Roberto]] 22:31, 6. Apr 2006 (CEST)&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=SMD&amp;diff=6676</id>
		<title>SMD</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=SMD&amp;diff=6676"/>
				<updated>2006-03-31T19:05:07Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Weblinks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Was sind SMD-Bauteile?==&lt;br /&gt;
[[Bild:smdbauteile.jpg|right|SMD-Bauteile auf einer Platine]]&lt;br /&gt;
Im Gegensatz zur &amp;quot;konventionellen&amp;quot; Durchsteck-Technik werden SMD-Bauteile (vom engl. &amp;quot;Surface Mounted Devices&amp;quot;) auf der Platinenoberfläche (surface) aufgebracht und verlötet, ohne die Leiterplatte zur Befestigung zusätzlich durchbohren zu müssen. Diese Technologie wird auch als SMT bezeichnet, vom englischen &amp;quot;Surface Mount Technology&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Im Zuge dieser &amp;quot;drahtlosen&amp;quot; Technologie werden die bislang im sogenannten &amp;quot;Schwallbad&amp;quot; mit den Drahtbeinen an der Platinenunterseite verlöteten &amp;quot;konventionellen&amp;quot; Steck-Bauteile mehr und mehr durch die wesentlich temperaturresistenteren SMD-Komponenten ersetzt. &lt;br /&gt;
Während letztere kurzzeitig problemlos Temperaturen von bis zu 240 Grad Celcius verkraften können, ohne Schade zu nehmen, liegt die mögliche Temperaturbelastung bei den bedrahteten Bauteilen in der Regel deutlich niedriger.&lt;br /&gt;
Zudem gelten die &amp;quot;neuen&amp;quot; SMD-Komponenten aber auch als zuverlässiger, was der Qualität der gesamten Baugruppe entscheidend zugute kommt, und sind darüberhinaus kostengünstiger und schneller zu verarbeiten.&lt;br /&gt;
Durch den Wegfall eines kompletten Arbeitsschrittes aufgrund fehlender Bohrungen bei reinen SMD-Bestückungen und kürzerer Bestückungs- und Lötzeiten enstehen nicht nur signifikante Einsparungspotentiale. Bei konsequenter Nutzung der SMD-Technologie werden zudem erheblich höhere Packungsdichten auf der Platine möglich und damit die im allgemeinen angestrebte oder sogar notwendige Miniaturisierung des Gesamtgehäuses erst möglich.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bei den Hobby-Elektronikern sind SMD-Bauteile relativ wenig verbreitet. Dies liegt vor allem daran, dass die Bauteile wirklich winzig sind und demnach die Kontaktabstände oft unter 1 mm liegen. &lt;br /&gt;
Das Löten von SMD Bausteinen ist dadurch wesentlich schwieriger als bei herkömmlichen Bauelementen. Noch schwieriger ist das Auslöten von defekten SMD Bauteilen, hier haben nur noch Profis Chancen. Dem Elektronik-Einsteiger können SMD-Bauteile daher weniger empfohlen werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:smd-dip-atmega32.png|thumb|300px|left|Grössenvergleich zwischen SMD und DIP]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Weblinks==&lt;br /&gt;
&lt;br /&gt;
* [http://de.wikipedia.org/wiki/Surface_Mounted_Device SMD und die Abmessungen im WIKI]&lt;br /&gt;
* [http://www.elv-downloads.de/downloads/journal/smd-anleitung.pdf Beschreibung von ELV]&lt;br /&gt;
&lt;br /&gt;
* [http://thomaspfeifer.net/index2.htm unter Trickkiste und AVR Projekte,vieles um SMD löten/entlöten (Revlow Ofen selbstbau u.s.w.)]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/SMD_L%F6ten SMD löten (Beschreibung von mikronkontroller.net) ]&lt;br /&gt;
* [http://stshome.de/elektronik/smd-loeten/ SMD-Löten]&lt;br /&gt;
* [http://www.bimbel.de/artikel/artikel-17.html Tips SMD Löten]&lt;br /&gt;
* [http://www-user.tu-chemnitz.de/~heha/bastelecke/Monitor%20reparieren/loeten.htm Tips zum Löten und Entlöten TU-Chemnitz]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=SMD&amp;diff=6671</id>
		<title>SMD</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=SMD&amp;diff=6671"/>
				<updated>2006-03-31T07:54:31Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Weblinks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Was sind SMD-Bauteile?==&lt;br /&gt;
[[Bild:smdbauteile.jpg|right|SMD-Bauteile auf einer Platine]]&lt;br /&gt;
Im Gegensatz zur &amp;quot;konventionellen&amp;quot; Durchsteck-Technik werden SMD-Bauteile (vom engl. &amp;quot;Surface Mounted Devices&amp;quot;) auf der Platinenoberfläche (surface) aufgebracht und verlötet, ohne die Leiterplatte zur Befestigung zusätzlich durchbohren zu müssen. Diese Technologie wird auch als SMT bezeichnet, vom englischen &amp;quot;Surface Mount Technology&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Im Zuge dieser &amp;quot;drahtlosen&amp;quot; Technologie werden die bislang im sogenannten &amp;quot;Schwallbad&amp;quot; mit den Drahtbeinen an der Platinenunterseite verlöteten &amp;quot;konventionellen&amp;quot; Steck-Bauteile mehr und mehr durch die wesentlich temperaturresistenteren SMD-Komponenten ersetzt. &lt;br /&gt;
Während letztere kurzzeitig problemlos Temperaturen von bis zu 240 Grad Celcius verkraften können, ohne Schade zu nehmen, liegt die mögliche Temperaturbelastung bei den bedrahteten Bauteilen in der Regel deutlich niedriger.&lt;br /&gt;
Zudem gelten die &amp;quot;neuen&amp;quot; SMD-Komponenten aber auch als zuverlässiger, was der Qualität der gesamten Baugruppe entscheidend zugute kommt, und sind darüberhinaus kostengünstiger und schneller zu verarbeiten.&lt;br /&gt;
Durch den Wegfall eines kompletten Arbeitsschrittes aufgrund fehlender Bohrungen bei reinen SMD-Bestückungen und kürzerer Bestückungs- und Lötzeiten enstehen nicht nur signifikante Einsparungspotentiale. Bei konsequenter Nutzung der SMD-Technologie werden zudem erheblich höhere Packungsdichten auf der Platine möglich und damit die im allgemeinen angestrebte oder sogar notwendige Miniaturisierung des Gesamtgehäuses erst möglich.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bei den Hobby-Elektronikern sind SMD-Bauteile relativ wenig verbreitet. Dies liegt vor allem daran, dass die Bauteile wirklich winzig sind und demnach die Kontaktabstände oft unter 1 mm liegen. &lt;br /&gt;
Das Löten von SMD Bausteinen ist dadurch wesentlich schwieriger als bei herkömmlichen Bauelementen. Noch schwieriger ist das Auslöten von defekten SMD Bauteilen, hier haben nur noch Profis Chancen. Dem Elektronik-Einsteiger können SMD-Bauteile daher weniger empfohlen werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:smd-dip-atmega32.png|thumb|300px|left|Grössenvergleich zwischen SMD und DIP]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Weblinks==&lt;br /&gt;
&lt;br /&gt;
* [http://de.wikipedia.org/wiki/Surface_Mounted_Device SMD im WIKI]&lt;br /&gt;
* [http://www.elv-downloads.de/downloads/journal/smd-anleitung.pdf Beschreibung von ELV]&lt;br /&gt;
&lt;br /&gt;
* [http://thomaspfeifer.net/index2.htm unter Trickkiste und AVR Projekte,vieles um SMD löten/entlöten (Revlow Ofen selbstbau u.s.w.)]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/SMD_L%F6ten SMD löten (Beschreibung von mikronkontroller.net) ]&lt;br /&gt;
* [http://stshome.de/elektronik/smd-loeten/ SMD-Löten]&lt;br /&gt;
* [http://www.bimbel.de/artikel/artikel-17.html Tips SMD Löten]&lt;br /&gt;
* [http://www-user.tu-chemnitz.de/~heha/bastelecke/Monitor%20reparieren/loeten.htm Tips zum Löten und Entlöten TU-Chemnitz]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=SMD&amp;diff=6670</id>
		<title>SMD</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=SMD&amp;diff=6670"/>
				<updated>2006-03-31T07:39:46Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Weblinks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Was sind SMD-Bauteile?==&lt;br /&gt;
[[Bild:smdbauteile.jpg|right|SMD-Bauteile auf einer Platine]]&lt;br /&gt;
Im Gegensatz zur &amp;quot;konventionellen&amp;quot; Durchsteck-Technik werden SMD-Bauteile (vom engl. &amp;quot;Surface Mounted Devices&amp;quot;) auf der Platinenoberfläche (surface) aufgebracht und verlötet, ohne die Leiterplatte zur Befestigung zusätzlich durchbohren zu müssen. Diese Technologie wird auch als SMT bezeichnet, vom englischen &amp;quot;Surface Mount Technology&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Im Zuge dieser &amp;quot;drahtlosen&amp;quot; Technologie werden die bislang im sogenannten &amp;quot;Schwallbad&amp;quot; mit den Drahtbeinen an der Platinenunterseite verlöteten &amp;quot;konventionellen&amp;quot; Steck-Bauteile mehr und mehr durch die wesentlich temperaturresistenteren SMD-Komponenten ersetzt. &lt;br /&gt;
Während letztere kurzzeitig problemlos Temperaturen von bis zu 240 Grad Celcius verkraften können, ohne Schade zu nehmen, liegt die mögliche Temperaturbelastung bei den bedrahteten Bauteilen in der Regel deutlich niedriger.&lt;br /&gt;
Zudem gelten die &amp;quot;neuen&amp;quot; SMD-Komponenten aber auch als zuverlässiger, was der Qualität der gesamten Baugruppe entscheidend zugute kommt, und sind darüberhinaus kostengünstiger und schneller zu verarbeiten.&lt;br /&gt;
Durch den Wegfall eines kompletten Arbeitsschrittes aufgrund fehlender Bohrungen bei reinen SMD-Bestückungen und kürzerer Bestückungs- und Lötzeiten enstehen nicht nur signifikante Einsparungspotentiale. Bei konsequenter Nutzung der SMD-Technologie werden zudem erheblich höhere Packungsdichten auf der Platine möglich und damit die im allgemeinen angestrebte oder sogar notwendige Miniaturisierung des Gesamtgehäuses erst möglich.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bei den Hobby-Elektronikern sind SMD-Bauteile relativ wenig verbreitet. Dies liegt vor allem daran, dass die Bauteile wirklich winzig sind und demnach die Kontaktabstände oft unter 1 mm liegen. &lt;br /&gt;
Das Löten von SMD Bausteinen ist dadurch wesentlich schwieriger als bei herkömmlichen Bauelementen. Noch schwieriger ist das Auslöten von defekten SMD Bauteilen, hier haben nur noch Profis Chancen. Dem Elektronik-Einsteiger können SMD-Bauteile daher weniger empfohlen werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:smd-dip-atmega32.png|thumb|300px|left|Grössenvergleich zwischen SMD und DIP]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Weblinks==&lt;br /&gt;
&lt;br /&gt;
* [http://de.wikipedia.org/wiki/Surface_Mounted_Device SMD im WIKI]&lt;br /&gt;
* [http://thomaspfeifer.net/index2.htm unter Trickkiste und AVR Projekte,vieles um SMD löten/entlöten (Revlow Ofen selbstbau u.s.w.)]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/SMD_L%F6ten SMD löten (Beschreibung von mikronkontroller.net) ]&lt;br /&gt;
* [http://stshome.de/elektronik/smd-loeten/ SMD-Löten]&lt;br /&gt;
* [http://www.bimbel.de/artikel/artikel-17.html Tips SMD Löten]&lt;br /&gt;
* [http://www-user.tu-chemnitz.de/~heha/bastelecke/Monitor%20reparieren/loeten.htm Tips zum Löten und Entlöten TU-Chemnitz]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=SMD&amp;diff=6669</id>
		<title>SMD</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=SMD&amp;diff=6669"/>
				<updated>2006-03-31T07:29:09Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Weblinks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Was sind SMD-Bauteile?==&lt;br /&gt;
[[Bild:smdbauteile.jpg|right|SMD-Bauteile auf einer Platine]]&lt;br /&gt;
Im Gegensatz zur &amp;quot;konventionellen&amp;quot; Durchsteck-Technik werden SMD-Bauteile (vom engl. &amp;quot;Surface Mounted Devices&amp;quot;) auf der Platinenoberfläche (surface) aufgebracht und verlötet, ohne die Leiterplatte zur Befestigung zusätzlich durchbohren zu müssen. Diese Technologie wird auch als SMT bezeichnet, vom englischen &amp;quot;Surface Mount Technology&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Im Zuge dieser &amp;quot;drahtlosen&amp;quot; Technologie werden die bislang im sogenannten &amp;quot;Schwallbad&amp;quot; mit den Drahtbeinen an der Platinenunterseite verlöteten &amp;quot;konventionellen&amp;quot; Steck-Bauteile mehr und mehr durch die wesentlich temperaturresistenteren SMD-Komponenten ersetzt. &lt;br /&gt;
Während letztere kurzzeitig problemlos Temperaturen von bis zu 240 Grad Celcius verkraften können, ohne Schade zu nehmen, liegt die mögliche Temperaturbelastung bei den bedrahteten Bauteilen in der Regel deutlich niedriger.&lt;br /&gt;
Zudem gelten die &amp;quot;neuen&amp;quot; SMD-Komponenten aber auch als zuverlässiger, was der Qualität der gesamten Baugruppe entscheidend zugute kommt, und sind darüberhinaus kostengünstiger und schneller zu verarbeiten.&lt;br /&gt;
Durch den Wegfall eines kompletten Arbeitsschrittes aufgrund fehlender Bohrungen bei reinen SMD-Bestückungen und kürzerer Bestückungs- und Lötzeiten enstehen nicht nur signifikante Einsparungspotentiale. Bei konsequenter Nutzung der SMD-Technologie werden zudem erheblich höhere Packungsdichten auf der Platine möglich und damit die im allgemeinen angestrebte oder sogar notwendige Miniaturisierung des Gesamtgehäuses erst möglich.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bei den Hobby-Elektronikern sind SMD-Bauteile relativ wenig verbreitet. Dies liegt vor allem daran, dass die Bauteile wirklich winzig sind und demnach die Kontaktabstände oft unter 1 mm liegen. &lt;br /&gt;
Das Löten von SMD Bausteinen ist dadurch wesentlich schwieriger als bei herkömmlichen Bauelementen. Noch schwieriger ist das Auslöten von defekten SMD Bauteilen, hier haben nur noch Profis Chancen. Dem Elektronik-Einsteiger können SMD-Bauteile daher weniger empfohlen werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:smd-dip-atmega32.png|thumb|300px|left|Grössenvergleich zwischen SMD und DIP]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Weblinks==&lt;br /&gt;
&lt;br /&gt;
* [http://de.wikipedia.org/wiki/Surface_Mounted_Device SMD im WIKI]&lt;br /&gt;
* [http://thomaspfeifer.net/index2.htm unter Trickkiste und AVR Projekte,vieles um SMD löten/entlöten (Revlow Ofen selbstbau u.s.w.)]&lt;br /&gt;
&lt;br /&gt;
* [http://stshome.de/elektronik/smd-loeten/ SMD-Löten]&lt;br /&gt;
* [http://www.bimbel.de/artikel/artikel-17.html Tips SMD Löten]&lt;br /&gt;
* [http://www-user.tu-chemnitz.de/~heha/bastelecke/Monitor%20reparieren/loeten.htm Tips zum Löten und Entlöten TU-Chemnitz]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=SMD&amp;diff=6668</id>
		<title>SMD</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=SMD&amp;diff=6668"/>
				<updated>2006-03-31T07:27:50Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Weblinks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Was sind SMD-Bauteile?==&lt;br /&gt;
[[Bild:smdbauteile.jpg|right|SMD-Bauteile auf einer Platine]]&lt;br /&gt;
Im Gegensatz zur &amp;quot;konventionellen&amp;quot; Durchsteck-Technik werden SMD-Bauteile (vom engl. &amp;quot;Surface Mounted Devices&amp;quot;) auf der Platinenoberfläche (surface) aufgebracht und verlötet, ohne die Leiterplatte zur Befestigung zusätzlich durchbohren zu müssen. Diese Technologie wird auch als SMT bezeichnet, vom englischen &amp;quot;Surface Mount Technology&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Im Zuge dieser &amp;quot;drahtlosen&amp;quot; Technologie werden die bislang im sogenannten &amp;quot;Schwallbad&amp;quot; mit den Drahtbeinen an der Platinenunterseite verlöteten &amp;quot;konventionellen&amp;quot; Steck-Bauteile mehr und mehr durch die wesentlich temperaturresistenteren SMD-Komponenten ersetzt. &lt;br /&gt;
Während letztere kurzzeitig problemlos Temperaturen von bis zu 240 Grad Celcius verkraften können, ohne Schade zu nehmen, liegt die mögliche Temperaturbelastung bei den bedrahteten Bauteilen in der Regel deutlich niedriger.&lt;br /&gt;
Zudem gelten die &amp;quot;neuen&amp;quot; SMD-Komponenten aber auch als zuverlässiger, was der Qualität der gesamten Baugruppe entscheidend zugute kommt, und sind darüberhinaus kostengünstiger und schneller zu verarbeiten.&lt;br /&gt;
Durch den Wegfall eines kompletten Arbeitsschrittes aufgrund fehlender Bohrungen bei reinen SMD-Bestückungen und kürzerer Bestückungs- und Lötzeiten enstehen nicht nur signifikante Einsparungspotentiale. Bei konsequenter Nutzung der SMD-Technologie werden zudem erheblich höhere Packungsdichten auf der Platine möglich und damit die im allgemeinen angestrebte oder sogar notwendige Miniaturisierung des Gesamtgehäuses erst möglich.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bei den Hobby-Elektronikern sind SMD-Bauteile relativ wenig verbreitet. Dies liegt vor allem daran, dass die Bauteile wirklich winzig sind und demnach die Kontaktabstände oft unter 1 mm liegen. &lt;br /&gt;
Das Löten von SMD Bausteinen ist dadurch wesentlich schwieriger als bei herkömmlichen Bauelementen. Noch schwieriger ist das Auslöten von defekten SMD Bauteilen, hier haben nur noch Profis Chancen. Dem Elektronik-Einsteiger können SMD-Bauteile daher weniger empfohlen werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:smd-dip-atmega32.png|thumb|300px|left|Grössenvergleich zwischen SMD und DIP]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Weblinks==&lt;br /&gt;
&lt;br /&gt;
* [http://de.wikipedia.org/wiki/Surface_Mounted_Device SMD im WIKI]&lt;br /&gt;
* [http://thomaspfeifer.net/index2.htm unter Trickkiste,vieles um SMD löten/entlöten (Revlow Ofen selbstbau u.s.w.)]&lt;br /&gt;
&lt;br /&gt;
* [http://stshome.de/elektronik/smd-loeten/ SMD-Löten]&lt;br /&gt;
* [http://www.bimbel.de/artikel/artikel-17.html Tips SMD Löten]&lt;br /&gt;
* [http://www-user.tu-chemnitz.de/~heha/bastelecke/Monitor%20reparieren/loeten.htm Tips zum Löten und Entlöten TU-Chemnitz]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=SMD&amp;diff=6667</id>
		<title>SMD</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=SMD&amp;diff=6667"/>
				<updated>2006-03-31T07:26:58Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Weblinks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Was sind SMD-Bauteile?==&lt;br /&gt;
[[Bild:smdbauteile.jpg|right|SMD-Bauteile auf einer Platine]]&lt;br /&gt;
Im Gegensatz zur &amp;quot;konventionellen&amp;quot; Durchsteck-Technik werden SMD-Bauteile (vom engl. &amp;quot;Surface Mounted Devices&amp;quot;) auf der Platinenoberfläche (surface) aufgebracht und verlötet, ohne die Leiterplatte zur Befestigung zusätzlich durchbohren zu müssen. Diese Technologie wird auch als SMT bezeichnet, vom englischen &amp;quot;Surface Mount Technology&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Im Zuge dieser &amp;quot;drahtlosen&amp;quot; Technologie werden die bislang im sogenannten &amp;quot;Schwallbad&amp;quot; mit den Drahtbeinen an der Platinenunterseite verlöteten &amp;quot;konventionellen&amp;quot; Steck-Bauteile mehr und mehr durch die wesentlich temperaturresistenteren SMD-Komponenten ersetzt. &lt;br /&gt;
Während letztere kurzzeitig problemlos Temperaturen von bis zu 240 Grad Celcius verkraften können, ohne Schade zu nehmen, liegt die mögliche Temperaturbelastung bei den bedrahteten Bauteilen in der Regel deutlich niedriger.&lt;br /&gt;
Zudem gelten die &amp;quot;neuen&amp;quot; SMD-Komponenten aber auch als zuverlässiger, was der Qualität der gesamten Baugruppe entscheidend zugute kommt, und sind darüberhinaus kostengünstiger und schneller zu verarbeiten.&lt;br /&gt;
Durch den Wegfall eines kompletten Arbeitsschrittes aufgrund fehlender Bohrungen bei reinen SMD-Bestückungen und kürzerer Bestückungs- und Lötzeiten enstehen nicht nur signifikante Einsparungspotentiale. Bei konsequenter Nutzung der SMD-Technologie werden zudem erheblich höhere Packungsdichten auf der Platine möglich und damit die im allgemeinen angestrebte oder sogar notwendige Miniaturisierung des Gesamtgehäuses erst möglich.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bei den Hobby-Elektronikern sind SMD-Bauteile relativ wenig verbreitet. Dies liegt vor allem daran, dass die Bauteile wirklich winzig sind und demnach die Kontaktabstände oft unter 1 mm liegen. &lt;br /&gt;
Das Löten von SMD Bausteinen ist dadurch wesentlich schwieriger als bei herkömmlichen Bauelementen. Noch schwieriger ist das Auslöten von defekten SMD Bauteilen, hier haben nur noch Profis Chancen. Dem Elektronik-Einsteiger können SMD-Bauteile daher weniger empfohlen werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:smd-dip-atmega32.png|thumb|300px|left|Grössenvergleich zwischen SMD und DIP]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Weblinks==&lt;br /&gt;
&lt;br /&gt;
* [http://de.wikipedia.org/wiki/Surface_Mounted_Device SMD im WIKI]&lt;br /&gt;
* [http://thomaspfeifer.net/index2.htm vieles um SMD löten/entlöten (Revlow Ofen selbstbau u.s.w.)]&lt;br /&gt;
&lt;br /&gt;
* [http://stshome.de/elektronik/smd-loeten/ SMD-Löten]&lt;br /&gt;
* [http://www.bimbel.de/artikel/artikel-17.html Tips SMD Löten]&lt;br /&gt;
* [http://www-user.tu-chemnitz.de/~heha/bastelecke/Monitor%20reparieren/loeten.htm Tips zum Löten und Entlöten TU-Chemnitz]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=SMD&amp;diff=6666</id>
		<title>SMD</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=SMD&amp;diff=6666"/>
				<updated>2006-03-31T07:25:58Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Weblinks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Was sind SMD-Bauteile?==&lt;br /&gt;
[[Bild:smdbauteile.jpg|right|SMD-Bauteile auf einer Platine]]&lt;br /&gt;
Im Gegensatz zur &amp;quot;konventionellen&amp;quot; Durchsteck-Technik werden SMD-Bauteile (vom engl. &amp;quot;Surface Mounted Devices&amp;quot;) auf der Platinenoberfläche (surface) aufgebracht und verlötet, ohne die Leiterplatte zur Befestigung zusätzlich durchbohren zu müssen. Diese Technologie wird auch als SMT bezeichnet, vom englischen &amp;quot;Surface Mount Technology&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Im Zuge dieser &amp;quot;drahtlosen&amp;quot; Technologie werden die bislang im sogenannten &amp;quot;Schwallbad&amp;quot; mit den Drahtbeinen an der Platinenunterseite verlöteten &amp;quot;konventionellen&amp;quot; Steck-Bauteile mehr und mehr durch die wesentlich temperaturresistenteren SMD-Komponenten ersetzt. &lt;br /&gt;
Während letztere kurzzeitig problemlos Temperaturen von bis zu 240 Grad Celcius verkraften können, ohne Schade zu nehmen, liegt die mögliche Temperaturbelastung bei den bedrahteten Bauteilen in der Regel deutlich niedriger.&lt;br /&gt;
Zudem gelten die &amp;quot;neuen&amp;quot; SMD-Komponenten aber auch als zuverlässiger, was der Qualität der gesamten Baugruppe entscheidend zugute kommt, und sind darüberhinaus kostengünstiger und schneller zu verarbeiten.&lt;br /&gt;
Durch den Wegfall eines kompletten Arbeitsschrittes aufgrund fehlender Bohrungen bei reinen SMD-Bestückungen und kürzerer Bestückungs- und Lötzeiten enstehen nicht nur signifikante Einsparungspotentiale. Bei konsequenter Nutzung der SMD-Technologie werden zudem erheblich höhere Packungsdichten auf der Platine möglich und damit die im allgemeinen angestrebte oder sogar notwendige Miniaturisierung des Gesamtgehäuses erst möglich.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bei den Hobby-Elektronikern sind SMD-Bauteile relativ wenig verbreitet. Dies liegt vor allem daran, dass die Bauteile wirklich winzig sind und demnach die Kontaktabstände oft unter 1 mm liegen. &lt;br /&gt;
Das Löten von SMD Bausteinen ist dadurch wesentlich schwieriger als bei herkömmlichen Bauelementen. Noch schwieriger ist das Auslöten von defekten SMD Bauteilen, hier haben nur noch Profis Chancen. Dem Elektronik-Einsteiger können SMD-Bauteile daher weniger empfohlen werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:smd-dip-atmega32.png|thumb|300px|left|Grössenvergleich zwischen SMD und DIP]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Weblinks==&lt;br /&gt;
&lt;br /&gt;
* [http://de.wikipedia.org/wiki/Surface_Mounted_Device SMD im WIKI]&lt;br /&gt;
* [http://thomaspfeifer.net/index2.htm vieles um SMD löten (Revlow u.s.w.)]&lt;br /&gt;
&lt;br /&gt;
* [http://stshome.de/elektronik/smd-loeten/ SMD-Löten]&lt;br /&gt;
* [http://www.bimbel.de/artikel/artikel-17.html Tips SMD Löten]&lt;br /&gt;
* [http://www-user.tu-chemnitz.de/~heha/bastelecke/Monitor%20reparieren/loeten.htm Tips zum Löten und Entlöten TU-Chemnitz]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=SMD&amp;diff=6665</id>
		<title>SMD</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=SMD&amp;diff=6665"/>
				<updated>2006-03-31T07:24:37Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Weblinks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Was sind SMD-Bauteile?==&lt;br /&gt;
[[Bild:smdbauteile.jpg|right|SMD-Bauteile auf einer Platine]]&lt;br /&gt;
Im Gegensatz zur &amp;quot;konventionellen&amp;quot; Durchsteck-Technik werden SMD-Bauteile (vom engl. &amp;quot;Surface Mounted Devices&amp;quot;) auf der Platinenoberfläche (surface) aufgebracht und verlötet, ohne die Leiterplatte zur Befestigung zusätzlich durchbohren zu müssen. Diese Technologie wird auch als SMT bezeichnet, vom englischen &amp;quot;Surface Mount Technology&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Im Zuge dieser &amp;quot;drahtlosen&amp;quot; Technologie werden die bislang im sogenannten &amp;quot;Schwallbad&amp;quot; mit den Drahtbeinen an der Platinenunterseite verlöteten &amp;quot;konventionellen&amp;quot; Steck-Bauteile mehr und mehr durch die wesentlich temperaturresistenteren SMD-Komponenten ersetzt. &lt;br /&gt;
Während letztere kurzzeitig problemlos Temperaturen von bis zu 240 Grad Celcius verkraften können, ohne Schade zu nehmen, liegt die mögliche Temperaturbelastung bei den bedrahteten Bauteilen in der Regel deutlich niedriger.&lt;br /&gt;
Zudem gelten die &amp;quot;neuen&amp;quot; SMD-Komponenten aber auch als zuverlässiger, was der Qualität der gesamten Baugruppe entscheidend zugute kommt, und sind darüberhinaus kostengünstiger und schneller zu verarbeiten.&lt;br /&gt;
Durch den Wegfall eines kompletten Arbeitsschrittes aufgrund fehlender Bohrungen bei reinen SMD-Bestückungen und kürzerer Bestückungs- und Lötzeiten enstehen nicht nur signifikante Einsparungspotentiale. Bei konsequenter Nutzung der SMD-Technologie werden zudem erheblich höhere Packungsdichten auf der Platine möglich und damit die im allgemeinen angestrebte oder sogar notwendige Miniaturisierung des Gesamtgehäuses erst möglich.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bei den Hobby-Elektronikern sind SMD-Bauteile relativ wenig verbreitet. Dies liegt vor allem daran, dass die Bauteile wirklich winzig sind und demnach die Kontaktabstände oft unter 1 mm liegen. &lt;br /&gt;
Das Löten von SMD Bausteinen ist dadurch wesentlich schwieriger als bei herkömmlichen Bauelementen. Noch schwieriger ist das Auslöten von defekten SMD Bauteilen, hier haben nur noch Profis Chancen. Dem Elektronik-Einsteiger können SMD-Bauteile daher weniger empfohlen werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:smd-dip-atmega32.png|thumb|300px|left|Grössenvergleich zwischen SMD und DIP]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Weblinks==&lt;br /&gt;
&lt;br /&gt;
* [http://de.wikipedia.org/wiki/Surface_Mounted_Device/ SMD im WIKI]&lt;br /&gt;
* [http://thomaspfeifer.net/index2.htm/ Vieles um SMD löten (Revlow u.s.w.)]&lt;br /&gt;
&lt;br /&gt;
* [http://stshome.de/elektronik/smd-loeten/ SMD-Löten]&lt;br /&gt;
* [http://www.bimbel.de/artikel/artikel-17.html Tips SMD Löten]&lt;br /&gt;
* [http://www-user.tu-chemnitz.de/~heha/bastelecke/Monitor%20reparieren/loeten.htm Tips zum Löten und Entlöten TU-Chemnitz]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=SMD&amp;diff=6664</id>
		<title>SMD</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=SMD&amp;diff=6664"/>
				<updated>2006-03-31T07:10:35Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Weblinks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Was sind SMD-Bauteile?==&lt;br /&gt;
[[Bild:smdbauteile.jpg|right|SMD-Bauteile auf einer Platine]]&lt;br /&gt;
Im Gegensatz zur &amp;quot;konventionellen&amp;quot; Durchsteck-Technik werden SMD-Bauteile (vom engl. &amp;quot;Surface Mounted Devices&amp;quot;) auf der Platinenoberfläche (surface) aufgebracht und verlötet, ohne die Leiterplatte zur Befestigung zusätzlich durchbohren zu müssen. Diese Technologie wird auch als SMT bezeichnet, vom englischen &amp;quot;Surface Mount Technology&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Im Zuge dieser &amp;quot;drahtlosen&amp;quot; Technologie werden die bislang im sogenannten &amp;quot;Schwallbad&amp;quot; mit den Drahtbeinen an der Platinenunterseite verlöteten &amp;quot;konventionellen&amp;quot; Steck-Bauteile mehr und mehr durch die wesentlich temperaturresistenteren SMD-Komponenten ersetzt. &lt;br /&gt;
Während letztere kurzzeitig problemlos Temperaturen von bis zu 240 Grad Celcius verkraften können, ohne Schade zu nehmen, liegt die mögliche Temperaturbelastung bei den bedrahteten Bauteilen in der Regel deutlich niedriger.&lt;br /&gt;
Zudem gelten die &amp;quot;neuen&amp;quot; SMD-Komponenten aber auch als zuverlässiger, was der Qualität der gesamten Baugruppe entscheidend zugute kommt, und sind darüberhinaus kostengünstiger und schneller zu verarbeiten.&lt;br /&gt;
Durch den Wegfall eines kompletten Arbeitsschrittes aufgrund fehlender Bohrungen bei reinen SMD-Bestückungen und kürzerer Bestückungs- und Lötzeiten enstehen nicht nur signifikante Einsparungspotentiale. Bei konsequenter Nutzung der SMD-Technologie werden zudem erheblich höhere Packungsdichten auf der Platine möglich und damit die im allgemeinen angestrebte oder sogar notwendige Miniaturisierung des Gesamtgehäuses erst möglich.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bei den Hobby-Elektronikern sind SMD-Bauteile relativ wenig verbreitet. Dies liegt vor allem daran, dass die Bauteile wirklich winzig sind und demnach die Kontaktabstände oft unter 1 mm liegen. &lt;br /&gt;
Das Löten von SMD Bausteinen ist dadurch wesentlich schwieriger als bei herkömmlichen Bauelementen. Noch schwieriger ist das Auslöten von defekten SMD Bauteilen, hier haben nur noch Profis Chancen. Dem Elektronik-Einsteiger können SMD-Bauteile daher weniger empfohlen werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:smd-dip-atmega32.png|thumb|300px|left|Grössenvergleich zwischen SMD und DIP]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Weblinks==&lt;br /&gt;
* [http://stshome.de/elektronik/smd-loeten/ SMD-Löten]&lt;br /&gt;
* [http://www.bimbel.de/artikel/artikel-17.html Tips SMD Löten]&lt;br /&gt;
* [http://www-user.tu-chemnitz.de/~heha/bastelecke/Monitor%20reparieren/loeten.htm Tips zum Löten und Entlöten TU-Chemnitz]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=SMD&amp;diff=6663</id>
		<title>SMD</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=SMD&amp;diff=6663"/>
				<updated>2006-03-31T07:09:52Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Was sind SMD-Bauteile?==&lt;br /&gt;
[[Bild:smdbauteile.jpg|right|SMD-Bauteile auf einer Platine]]&lt;br /&gt;
Im Gegensatz zur &amp;quot;konventionellen&amp;quot; Durchsteck-Technik werden SMD-Bauteile (vom engl. &amp;quot;Surface Mounted Devices&amp;quot;) auf der Platinenoberfläche (surface) aufgebracht und verlötet, ohne die Leiterplatte zur Befestigung zusätzlich durchbohren zu müssen. Diese Technologie wird auch als SMT bezeichnet, vom englischen &amp;quot;Surface Mount Technology&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Im Zuge dieser &amp;quot;drahtlosen&amp;quot; Technologie werden die bislang im sogenannten &amp;quot;Schwallbad&amp;quot; mit den Drahtbeinen an der Platinenunterseite verlöteten &amp;quot;konventionellen&amp;quot; Steck-Bauteile mehr und mehr durch die wesentlich temperaturresistenteren SMD-Komponenten ersetzt. &lt;br /&gt;
Während letztere kurzzeitig problemlos Temperaturen von bis zu 240 Grad Celcius verkraften können, ohne Schade zu nehmen, liegt die mögliche Temperaturbelastung bei den bedrahteten Bauteilen in der Regel deutlich niedriger.&lt;br /&gt;
Zudem gelten die &amp;quot;neuen&amp;quot; SMD-Komponenten aber auch als zuverlässiger, was der Qualität der gesamten Baugruppe entscheidend zugute kommt, und sind darüberhinaus kostengünstiger und schneller zu verarbeiten.&lt;br /&gt;
Durch den Wegfall eines kompletten Arbeitsschrittes aufgrund fehlender Bohrungen bei reinen SMD-Bestückungen und kürzerer Bestückungs- und Lötzeiten enstehen nicht nur signifikante Einsparungspotentiale. Bei konsequenter Nutzung der SMD-Technologie werden zudem erheblich höhere Packungsdichten auf der Platine möglich und damit die im allgemeinen angestrebte oder sogar notwendige Miniaturisierung des Gesamtgehäuses erst möglich.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bei den Hobby-Elektronikern sind SMD-Bauteile relativ wenig verbreitet. Dies liegt vor allem daran, dass die Bauteile wirklich winzig sind und demnach die Kontaktabstände oft unter 1 mm liegen. &lt;br /&gt;
Das Löten von SMD Bausteinen ist dadurch wesentlich schwieriger als bei herkömmlichen Bauelementen. Noch schwieriger ist das Auslöten von defekten SMD Bauteilen, hier haben nur noch Profis Chancen. Dem Elektronik-Einsteiger können SMD-Bauteile daher weniger empfohlen werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:smd-dip-atmega32.png|thumb|300px|left|Grössenvergleich zwischen SMD und DIP]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Weblinks==&lt;br /&gt;
* [http://stshome.de/elektronik/smd-loeten/ SMD-Löten]&lt;br /&gt;
* [http://www.bimbel.de/artikel/artikel-17.html Tips SMD Löten]&lt;br /&gt;
* [http://www-user.tu-chemnitz.de/~heha/bastelecke/Monitor%20reparieren/loeten.htm Tips zum Löten und Entlöten TU-Chemnitz]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_I2C_EEprom&amp;diff=6555</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=6555"/>
				<updated>2006-03-19T23:07:25Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* 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 schreiben&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;
&lt;br /&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öhnlich 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 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;
&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  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 Adressberreich in High und Low Adressbereich trennen.&lt;br /&gt;
(Zuerst High-Adressberreich 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;
&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 Schreiben&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 Berreich von zwei Byte und braucht daher den Berreich 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>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_I2C_EEprom&amp;diff=5780</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=5780"/>
				<updated>2006-02-02T14:14:30Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Ansteuern vom I2C EEprom's 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 schreiben&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C16 ===&lt;br /&gt;
Zum besseren Verständniss werden hier die I2C Befehle untereinander geschrieben.&lt;br /&gt;
In einem grösserem Programm, empfiehlt sich aber eine Sub-Routine zu deklarieren, die dann den Schreib/lese Vorgänge abwickelt.&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 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;
&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;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C256 ===&lt;br /&gt;
&lt;br /&gt;
EEprom  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 Adressberreich in High und Low Adressbereich trennen.&lt;br /&gt;
(Zuerst High-Adressberreich 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;
&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 Schreiben&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 Berreich von zwei Byte und braucht daher den Berreich 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;
&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>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_I2C_EEprom&amp;diff=5779</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=5779"/>
				<updated>2006-02-02T14:09:25Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Low/High Adressbereich mit Overlay leicht ansprechen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Ansteuern vom I2C EEprom's 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 schreiben&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C16 ===&lt;br /&gt;
Zum besseren Verständniss werden hier die I2C Befehle untereinander geschrieben.&lt;br /&gt;
In einem grösserem Programm, empfiehlt sich aber eine Sub-Routine zu deklarieren, die dann den Schreib/lese Vorgänge abwickelt.&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 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;
&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;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C256 ===&lt;br /&gt;
&lt;br /&gt;
EEprom  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 Adressberreich in Low und High Adressbereich trennen.&lt;br /&gt;
(Zuerst Low-Adressbereich schreiben und dann High-Adressberreich)&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 A                                'Sende Speicheradresse LOw&lt;br /&gt;
I2cwbyte 1                                'Sende Speicheradresse High&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 Low&lt;br /&gt;
I2cwbyte 1                                  'sende Speicheradresse High&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;
&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 Schreiben&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 Berreich von zwei Byte und braucht daher den Berreich 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;
&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>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Benutzer_Diskussion:Roberto&amp;diff=5751</id>
		<title>Benutzer Diskussion:Roberto</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Benutzer_Diskussion:Roberto&amp;diff=5751"/>
				<updated>2006-01-31T23:54:15Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Bascom und Counter */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
du machst feine Artikel!&lt;br /&gt;
Aber bitte nicht jede Zeile mit &amp;lt;nowiki&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;/nowiki&amp;gt; umbrechen. Der Text sollte gewöhnlich fließend eingegeben werden, nur bei Absätzen entweder Leerzeilen oder halt &amp;lt;nowiki&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;/nowiki&amp;gt; einfügen. Nur so ist sichergestellt das der Artikel in allen Auflösungen nett aussieht. &lt;br /&gt;
Wenn Du willst kannst du die Bilder mittig anzeigen lassen, ich hab es bei ersten bild im pwm Artikel mal gemacht.&lt;br /&gt;
--[[Benutzer:Frank|Frank]] 14:15, 14. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
Noch eine Bitte, bei Artikel nicht die eigene Homepage drunter schreiben, außer es gehört zum Thema (dann aber unter Weblinks). Also nur den BenutzerNamen. Persönliche Angaben wie Homepage kannst du ja auf deiner Benutzerseite angeben. Ich habs mal probehalber mal für dich gemacht.&lt;br /&gt;
&lt;br /&gt;
hier [[Benutzer:Roberto|Roberto]]&lt;br /&gt;
&lt;br /&gt;
Hallo Frank.&lt;br /&gt;
Ganz ist mir das mir den Diskusions sachen nicht klar.&lt;br /&gt;
Hoffe ich schreibe hier jetzt richtig rein ?!&lt;br /&gt;
&lt;br /&gt;
Wenn ich ohne Umbruch mache, steht ja alles in einer Wurst ?&lt;br /&gt;
Das schaut ja nach nix aus.&lt;br /&gt;
Was macht es den eigentlich, wenn ich mehr BR's verwende ??&lt;br /&gt;
--[[Benutzer:Roberto|Roberto]] 17:10, 14. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ja du schreibst hier schon richtig! Zu jedem Artikel gibts eine Diskussionsseite um Sachen zu klären. Das ist deine private Diskussionsseite!&lt;br /&gt;
Umbruch muss man weglassen da ja jeder andere Bildschirmbreiten besitzt. Natürlich kannst du bei Absätzen etc. einen Umbruch oder eine Leerzeile einfügen. Nur nicht in jeder Zeile. Am besten schaust du dir immer andere Artikel mit ÄNDERN an.&lt;br /&gt;
--[[Benutzer:Frank|Frank]] 19:55, 14. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Hallo Frank.&lt;br /&gt;
Bisschen umständlich das ganze mit den Diskussionen...&lt;br /&gt;
Da sieht man schlecht was jeder schreibt.&lt;br /&gt;
Bei eMail kann man zu jedem Kommentar anworten und man sieht trotzdem, was jeder geschrieben hat.&lt;br /&gt;
Aber egal.. Muss wohl damit leben ;-)&lt;br /&gt;
&lt;br /&gt;
Habe inzwischen alle BR gelöscht..&lt;br /&gt;
Geht eigentlich so auch , nur halt mehr in einer Wurst...&lt;br /&gt;
&lt;br /&gt;
Ein paar Fragen hätte ich noch !!&lt;br /&gt;
&lt;br /&gt;
*Hast Du meine eMail bekommen wegen dem Thema Bascom ? (wohin u.s.w.)&lt;br /&gt;
&lt;br /&gt;
*Wie kann ich meine Beiträge in den Berreich Software ablegen, oder kann das nur ein Admin. ?&lt;br /&gt;
&lt;br /&gt;
* Bei &amp;quot;Bascom interupts&amp;quot;, könntest Du bitte das &amp;quot;Interrupt&amp;quot; gross schreiben ?&lt;br /&gt;
(kann das leider nicht ändern)&lt;br /&gt;
&lt;br /&gt;
* Wie kann ich meine eigenen Bilder löschen ???&lt;br /&gt;
Habe da eines , zu grosses , hoch geladen und bei einem ist das Copyright falsch...&lt;br /&gt;
&lt;br /&gt;
* Wenn ich in zukunft eine Frage an dich habe, soll ich dann hier schreiben oder per eMAil ?&lt;br /&gt;
&lt;br /&gt;
* kann diese Diskusion dann eigentlich jeder lesen ?&lt;br /&gt;
&lt;br /&gt;
Ich glaube, einstweilen wären das alle Fragen ;-) :-)&lt;br /&gt;
--[[Benutzer:Roberto|Roberto]] 21:31, 14. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Hallo&lt;br /&gt;
&lt;br /&gt;
'''Zu deinen Fragen:'''&lt;br /&gt;
&lt;br /&gt;
* Mail hab ich keine bekommen. Musst du nochmal an webmaster... senden.&lt;br /&gt;
* Ob du Bilder löschen kannst weiss ich nicht genau, zumindets Updaten müsstest du diese können. Einfach mal draufklicken dann solltest du Menüpunkt darunter finden. oder über Bilderliste oben im Menü.&lt;br /&gt;
Zu große Bilder entweder updaten oder einfach verkleinern bei der Darstellung. Schau dazu mal in die Editierhilfe oder auch dir einfach mit ÄNDERN einige Artikel an wo kleinere Bilder zu sehen sind. Auf der Testseite ist glaub auch ein Beispiel. Wenn es ganz weg soll, kannst du einen Löschantrag einbauen. Schau dazu auch mal in die Hilfe, ist ganz leicht. Ein Mod oder ich löschen es dann. (siehe [[Hilfe:FAQ]])&lt;br /&gt;
* Fragen kannst du im Forum posten (wenns eilig ist und für andere auch interessant ist), in der Artikeldiskussion (wenns zum Artikel passt) oder ne Mail.&lt;br /&gt;
* Diskussionen kann jeder lesen, das ist bei Artikeldiskussionen ja immer Vorteilhaft&lt;br /&gt;
* Man kann nichts in einer bestimmten Kategorie ablegen. Man teilt den Artikels durch den kategorie Befehl eine Kategorie zu. Bei deinen Artikeln hab ich das unten schon mehrfach gemacht. Dadurch sollte der Artikel dann in den passenden Rubriken erscheinen. Steht aber auch in der Editierhilfe [[RN-Wissen:Editierhilfe]]&lt;br /&gt;
* Ach so, das umbenennen von Artikeln geht nicht so einfach, können eigentlich nur Moderatoren. Ich habs mal gemacht: [[Bascom Interrupts]]&lt;br /&gt;
&lt;br /&gt;
Hat man erst mal alles raus ist es eigentlich alles recht einfach. &lt;br /&gt;
&lt;br /&gt;
Gruß Frank&lt;br /&gt;
&lt;br /&gt;
== Bascom und Counter ==&lt;br /&gt;
&lt;br /&gt;
Hallo,&lt;br /&gt;
mir ist aufgefallen das der Artikel [[Bascom und Counter]] seit längerem auf&lt;br /&gt;
Status Artikelbaustelle steht. &lt;br /&gt;
Solltest du den Artikel erstmal nicht fertig machen wollen, vielleicht aus Zeitmangel, dann gib bescheid. Wir könnten ihn dann erstmal löschen (ist ja noch leer). Artikelbaustellen sollten nicht zu lange offen sein.&lt;br /&gt;
&lt;br /&gt;
Gruß&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Frank|Frank]] 12:52, 31. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hallo Frank&lt;br /&gt;
&lt;br /&gt;
Ja, ich komme ledier derzeit nicht dazu...&lt;br /&gt;
Ist vielleicht doch besser den einstweilen zu löschen..&lt;br /&gt;
&lt;br /&gt;
Was anderes..&lt;br /&gt;
Es gibt ja inzwischen schon ein paar Artikel zu Bascom (timer,Verzweigungen u.s.w..) &lt;br /&gt;
Vielleicht könnte man das irgendwo zusammenlegen... ? Unter Bascom oder so ?&lt;br /&gt;
Oder unter Software/Bascom  vielleicht ?!&lt;br /&gt;
&lt;br /&gt;
Was meinst Du dazu ?!&lt;br /&gt;
--[[Benutzer:Roberto|Roberto]] 20:47, 31. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ok, hab die Seite erst mal gelöscht. Kannst ja jederzeit wieder neu einfügen.&lt;br /&gt;
Nun zusammenfassen würde ich´s momentan eigentlich nicht. Sind ja recht unterschiedliche Themen, die könnte man sicher noch ausbauen und weiter mit Beispielen versehen. Ist eventuell für einen Artikel am Ende zu lang.&lt;br /&gt;
--[[Benutzer:Frank|Frank]] 22:42, 31. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
OK :-)&lt;br /&gt;
&lt;br /&gt;
Was ist eigentlich unter Software das &amp;quot;B cont.&amp;quot;  ??&lt;br /&gt;
&lt;br /&gt;
Da sind ein paar Artikel drinnen, die eigentlich auch zu &amp;quot;B&amp;quot; gehören.&lt;br /&gt;
(Bascom und Timer, Bascom und PWM...)&lt;br /&gt;
--[[Benutzer:Roberto|Roberto]] 00:54, 1. Feb 2006 (CET)&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Benutzer_Diskussion:Roberto&amp;diff=5738</id>
		<title>Benutzer Diskussion:Roberto</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Benutzer_Diskussion:Roberto&amp;diff=5738"/>
				<updated>2006-01-31T19:48:38Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Bascom und Counter */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
du machst feine Artikel!&lt;br /&gt;
Aber bitte nicht jede Zeile mit &amp;lt;nowiki&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;/nowiki&amp;gt; umbrechen. Der Text sollte gewöhnlich fließend eingegeben werden, nur bei Absätzen entweder Leerzeilen oder halt &amp;lt;nowiki&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;/nowiki&amp;gt; einfügen. Nur so ist sichergestellt das der Artikel in allen Auflösungen nett aussieht. &lt;br /&gt;
Wenn Du willst kannst du die Bilder mittig anzeigen lassen, ich hab es bei ersten bild im pwm Artikel mal gemacht.&lt;br /&gt;
--[[Benutzer:Frank|Frank]] 14:15, 14. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
Noch eine Bitte, bei Artikel nicht die eigene Homepage drunter schreiben, außer es gehört zum Thema (dann aber unter Weblinks). Also nur den BenutzerNamen. Persönliche Angaben wie Homepage kannst du ja auf deiner Benutzerseite angeben. Ich habs mal probehalber mal für dich gemacht.&lt;br /&gt;
&lt;br /&gt;
hier [[Benutzer:Roberto|Roberto]]&lt;br /&gt;
&lt;br /&gt;
Hallo Frank.&lt;br /&gt;
Ganz ist mir das mir den Diskusions sachen nicht klar.&lt;br /&gt;
Hoffe ich schreibe hier jetzt richtig rein ?!&lt;br /&gt;
&lt;br /&gt;
Wenn ich ohne Umbruch mache, steht ja alles in einer Wurst ?&lt;br /&gt;
Das schaut ja nach nix aus.&lt;br /&gt;
Was macht es den eigentlich, wenn ich mehr BR's verwende ??&lt;br /&gt;
--[[Benutzer:Roberto|Roberto]] 17:10, 14. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ja du schreibst hier schon richtig! Zu jedem Artikel gibts eine Diskussionsseite um Sachen zu klären. Das ist deine private Diskussionsseite!&lt;br /&gt;
Umbruch muss man weglassen da ja jeder andere Bildschirmbreiten besitzt. Natürlich kannst du bei Absätzen etc. einen Umbruch oder eine Leerzeile einfügen. Nur nicht in jeder Zeile. Am besten schaust du dir immer andere Artikel mit ÄNDERN an.&lt;br /&gt;
--[[Benutzer:Frank|Frank]] 19:55, 14. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Hallo Frank.&lt;br /&gt;
Bisschen umständlich das ganze mit den Diskussionen...&lt;br /&gt;
Da sieht man schlecht was jeder schreibt.&lt;br /&gt;
Bei eMail kann man zu jedem Kommentar anworten und man sieht trotzdem, was jeder geschrieben hat.&lt;br /&gt;
Aber egal.. Muss wohl damit leben ;-)&lt;br /&gt;
&lt;br /&gt;
Habe inzwischen alle BR gelöscht..&lt;br /&gt;
Geht eigentlich so auch , nur halt mehr in einer Wurst...&lt;br /&gt;
&lt;br /&gt;
Ein paar Fragen hätte ich noch !!&lt;br /&gt;
&lt;br /&gt;
*Hast Du meine eMail bekommen wegen dem Thema Bascom ? (wohin u.s.w.)&lt;br /&gt;
&lt;br /&gt;
*Wie kann ich meine Beiträge in den Berreich Software ablegen, oder kann das nur ein Admin. ?&lt;br /&gt;
&lt;br /&gt;
* Bei &amp;quot;Bascom interupts&amp;quot;, könntest Du bitte das &amp;quot;Interrupt&amp;quot; gross schreiben ?&lt;br /&gt;
(kann das leider nicht ändern)&lt;br /&gt;
&lt;br /&gt;
* Wie kann ich meine eigenen Bilder löschen ???&lt;br /&gt;
Habe da eines , zu grosses , hoch geladen und bei einem ist das Copyright falsch...&lt;br /&gt;
&lt;br /&gt;
* Wenn ich in zukunft eine Frage an dich habe, soll ich dann hier schreiben oder per eMAil ?&lt;br /&gt;
&lt;br /&gt;
* kann diese Diskusion dann eigentlich jeder lesen ?&lt;br /&gt;
&lt;br /&gt;
Ich glaube, einstweilen wären das alle Fragen ;-) :-)&lt;br /&gt;
--[[Benutzer:Roberto|Roberto]] 21:31, 14. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Hallo&lt;br /&gt;
&lt;br /&gt;
'''Zu deinen Fragen:'''&lt;br /&gt;
&lt;br /&gt;
* Mail hab ich keine bekommen. Musst du nochmal an webmaster... senden.&lt;br /&gt;
* Ob du Bilder löschen kannst weiss ich nicht genau, zumindets Updaten müsstest du diese können. Einfach mal draufklicken dann solltest du Menüpunkt darunter finden. oder über Bilderliste oben im Menü.&lt;br /&gt;
Zu große Bilder entweder updaten oder einfach verkleinern bei der Darstellung. Schau dazu mal in die Editierhilfe oder auch dir einfach mit ÄNDERN einige Artikel an wo kleinere Bilder zu sehen sind. Auf der Testseite ist glaub auch ein Beispiel. Wenn es ganz weg soll, kannst du einen Löschantrag einbauen. Schau dazu auch mal in die Hilfe, ist ganz leicht. Ein Mod oder ich löschen es dann. (siehe [[Hilfe:FAQ]])&lt;br /&gt;
* Fragen kannst du im Forum posten (wenns eilig ist und für andere auch interessant ist), in der Artikeldiskussion (wenns zum Artikel passt) oder ne Mail.&lt;br /&gt;
* Diskussionen kann jeder lesen, das ist bei Artikeldiskussionen ja immer Vorteilhaft&lt;br /&gt;
* Man kann nichts in einer bestimmten Kategorie ablegen. Man teilt den Artikels durch den kategorie Befehl eine Kategorie zu. Bei deinen Artikeln hab ich das unten schon mehrfach gemacht. Dadurch sollte der Artikel dann in den passenden Rubriken erscheinen. Steht aber auch in der Editierhilfe [[RN-Wissen:Editierhilfe]]&lt;br /&gt;
* Ach so, das umbenennen von Artikeln geht nicht so einfach, können eigentlich nur Moderatoren. Ich habs mal gemacht: [[Bascom Interrupts]]&lt;br /&gt;
&lt;br /&gt;
Hat man erst mal alles raus ist es eigentlich alles recht einfach. &lt;br /&gt;
&lt;br /&gt;
Gruß Frank&lt;br /&gt;
&lt;br /&gt;
== Bascom und Counter ==&lt;br /&gt;
&lt;br /&gt;
Hallo,&lt;br /&gt;
mir ist aufgefallen das der Artikel [[Bascom und Counter]] seit längerem auf&lt;br /&gt;
Status Artikelbaustelle steht. &lt;br /&gt;
Solltest du den Artikel erstmal nicht fertig machen wollen, vielleicht aus Zeitmangel, dann gib bescheid. Wir könnten ihn dann erstmal löschen (ist ja noch leer). Artikelbaustellen sollten nicht zu lange offen sein.&lt;br /&gt;
&lt;br /&gt;
Gruß&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Frank|Frank]] 12:52, 31. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hallo Frank&lt;br /&gt;
&lt;br /&gt;
Ja, ich komme ledier derzeit nicht dazu...&lt;br /&gt;
Ist vielleicht doch besser den einstweilen zu löschen..&lt;br /&gt;
&lt;br /&gt;
Was anderes..&lt;br /&gt;
Es gibt ja inzwischen schon ein paar Artikel zu Bascom (timer,Verzweigungen u.s.w..) &lt;br /&gt;
Vielleicht könnte man das irgendwo zusammenlegen... ? Unter Bascom oder so ?&lt;br /&gt;
Oder unter Software/Bascom  vielleicht ?!&lt;br /&gt;
&lt;br /&gt;
Was meinst Du dazu ?!&lt;br /&gt;
--[[Benutzer:Roberto|Roberto]] 20:47, 31. Jan 2006 (CET)&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Benutzer_Diskussion:Roberto&amp;diff=5737</id>
		<title>Benutzer Diskussion:Roberto</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Benutzer_Diskussion:Roberto&amp;diff=5737"/>
				<updated>2006-01-31T19:47:55Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi,&lt;br /&gt;
du machst feine Artikel!&lt;br /&gt;
Aber bitte nicht jede Zeile mit &amp;lt;nowiki&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;/nowiki&amp;gt; umbrechen. Der Text sollte gewöhnlich fließend eingegeben werden, nur bei Absätzen entweder Leerzeilen oder halt &amp;lt;nowiki&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;/nowiki&amp;gt; einfügen. Nur so ist sichergestellt das der Artikel in allen Auflösungen nett aussieht. &lt;br /&gt;
Wenn Du willst kannst du die Bilder mittig anzeigen lassen, ich hab es bei ersten bild im pwm Artikel mal gemacht.&lt;br /&gt;
--[[Benutzer:Frank|Frank]] 14:15, 14. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
Noch eine Bitte, bei Artikel nicht die eigene Homepage drunter schreiben, außer es gehört zum Thema (dann aber unter Weblinks). Also nur den BenutzerNamen. Persönliche Angaben wie Homepage kannst du ja auf deiner Benutzerseite angeben. Ich habs mal probehalber mal für dich gemacht.&lt;br /&gt;
&lt;br /&gt;
hier [[Benutzer:Roberto|Roberto]]&lt;br /&gt;
&lt;br /&gt;
Hallo Frank.&lt;br /&gt;
Ganz ist mir das mir den Diskusions sachen nicht klar.&lt;br /&gt;
Hoffe ich schreibe hier jetzt richtig rein ?!&lt;br /&gt;
&lt;br /&gt;
Wenn ich ohne Umbruch mache, steht ja alles in einer Wurst ?&lt;br /&gt;
Das schaut ja nach nix aus.&lt;br /&gt;
Was macht es den eigentlich, wenn ich mehr BR's verwende ??&lt;br /&gt;
--[[Benutzer:Roberto|Roberto]] 17:10, 14. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ja du schreibst hier schon richtig! Zu jedem Artikel gibts eine Diskussionsseite um Sachen zu klären. Das ist deine private Diskussionsseite!&lt;br /&gt;
Umbruch muss man weglassen da ja jeder andere Bildschirmbreiten besitzt. Natürlich kannst du bei Absätzen etc. einen Umbruch oder eine Leerzeile einfügen. Nur nicht in jeder Zeile. Am besten schaust du dir immer andere Artikel mit ÄNDERN an.&lt;br /&gt;
--[[Benutzer:Frank|Frank]] 19:55, 14. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Hallo Frank.&lt;br /&gt;
Bisschen umständlich das ganze mit den Diskussionen...&lt;br /&gt;
Da sieht man schlecht was jeder schreibt.&lt;br /&gt;
Bei eMail kann man zu jedem Kommentar anworten und man sieht trotzdem, was jeder geschrieben hat.&lt;br /&gt;
Aber egal.. Muss wohl damit leben ;-)&lt;br /&gt;
&lt;br /&gt;
Habe inzwischen alle BR gelöscht..&lt;br /&gt;
Geht eigentlich so auch , nur halt mehr in einer Wurst...&lt;br /&gt;
&lt;br /&gt;
Ein paar Fragen hätte ich noch !!&lt;br /&gt;
&lt;br /&gt;
*Hast Du meine eMail bekommen wegen dem Thema Bascom ? (wohin u.s.w.)&lt;br /&gt;
&lt;br /&gt;
*Wie kann ich meine Beiträge in den Berreich Software ablegen, oder kann das nur ein Admin. ?&lt;br /&gt;
&lt;br /&gt;
* Bei &amp;quot;Bascom interupts&amp;quot;, könntest Du bitte das &amp;quot;Interrupt&amp;quot; gross schreiben ?&lt;br /&gt;
(kann das leider nicht ändern)&lt;br /&gt;
&lt;br /&gt;
* Wie kann ich meine eigenen Bilder löschen ???&lt;br /&gt;
Habe da eines , zu grosses , hoch geladen und bei einem ist das Copyright falsch...&lt;br /&gt;
&lt;br /&gt;
* Wenn ich in zukunft eine Frage an dich habe, soll ich dann hier schreiben oder per eMAil ?&lt;br /&gt;
&lt;br /&gt;
* kann diese Diskusion dann eigentlich jeder lesen ?&lt;br /&gt;
&lt;br /&gt;
Ich glaube, einstweilen wären das alle Fragen ;-) :-)&lt;br /&gt;
--[[Benutzer:Roberto|Roberto]] 21:31, 14. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Hallo&lt;br /&gt;
&lt;br /&gt;
'''Zu deinen Fragen:'''&lt;br /&gt;
&lt;br /&gt;
* Mail hab ich keine bekommen. Musst du nochmal an webmaster... senden.&lt;br /&gt;
* Ob du Bilder löschen kannst weiss ich nicht genau, zumindets Updaten müsstest du diese können. Einfach mal draufklicken dann solltest du Menüpunkt darunter finden. oder über Bilderliste oben im Menü.&lt;br /&gt;
Zu große Bilder entweder updaten oder einfach verkleinern bei der Darstellung. Schau dazu mal in die Editierhilfe oder auch dir einfach mit ÄNDERN einige Artikel an wo kleinere Bilder zu sehen sind. Auf der Testseite ist glaub auch ein Beispiel. Wenn es ganz weg soll, kannst du einen Löschantrag einbauen. Schau dazu auch mal in die Hilfe, ist ganz leicht. Ein Mod oder ich löschen es dann. (siehe [[Hilfe:FAQ]])&lt;br /&gt;
* Fragen kannst du im Forum posten (wenns eilig ist und für andere auch interessant ist), in der Artikeldiskussion (wenns zum Artikel passt) oder ne Mail.&lt;br /&gt;
* Diskussionen kann jeder lesen, das ist bei Artikeldiskussionen ja immer Vorteilhaft&lt;br /&gt;
* Man kann nichts in einer bestimmten Kategorie ablegen. Man teilt den Artikels durch den kategorie Befehl eine Kategorie zu. Bei deinen Artikeln hab ich das unten schon mehrfach gemacht. Dadurch sollte der Artikel dann in den passenden Rubriken erscheinen. Steht aber auch in der Editierhilfe [[RN-Wissen:Editierhilfe]]&lt;br /&gt;
* Ach so, das umbenennen von Artikeln geht nicht so einfach, können eigentlich nur Moderatoren. Ich habs mal gemacht: [[Bascom Interrupts]]&lt;br /&gt;
&lt;br /&gt;
Hat man erst mal alles raus ist es eigentlich alles recht einfach. &lt;br /&gt;
&lt;br /&gt;
Gruß Frank&lt;br /&gt;
&lt;br /&gt;
== Bascom und Counter ==&lt;br /&gt;
&lt;br /&gt;
Hallo,&lt;br /&gt;
mir ist aufgefallen das der Artikel [[Bascom und Counter]] seit längerem auf&lt;br /&gt;
Status Artikelbaustelle steht. &lt;br /&gt;
Solltest du den Artikel erstmal nicht fertig machen wollen, vielleicht aus Zeitmangel, dann gib bescheid. Wir könnten ihn dann erstmal löschen (ist ja noch leer). Artikelbaustellen sollten nicht zu lange offen sein.&lt;br /&gt;
&lt;br /&gt;
Gruß&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Frank|Frank]] 12:52, 31. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hallo Frank&lt;br /&gt;
&lt;br /&gt;
Ja, ich komme ledier derzeit nicht dazu...&lt;br /&gt;
Ist vielleicht doch besser den einstweilen zu löschen..&lt;br /&gt;
&lt;br /&gt;
Was anderes..&lt;br /&gt;
Es gibt ja inzwischen schon ein paar Artikel zu Bascom (timer,Verzweigungen u.s.w..) &lt;br /&gt;
Vielleicht könnte man das irgendwo zusammenlegen... ? Unter Bascom oder so ?&lt;br /&gt;
 Oder unter Software/Bascom  vielleicht ?!&lt;br /&gt;
&lt;br /&gt;
Was meinst Du dazu ?!&lt;br /&gt;
--[[Benutzer:Roberto|Roberto]] 20:47, 31. Jan 2006 (CET)&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_Timer&amp;diff=5700</id>
		<title>Bascom und Timer</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Bascom_und_Timer&amp;diff=5700"/>
				<updated>2006-01-30T07:37:12Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Timer im 1 Sekunden Takt */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Bascom Timer (Mega8 und andere) ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Zweck ===&lt;br /&gt;
[[Timer]] sind selbständige Zähler im Prozessor. Man braucht sie dort, wo zeitkritische und genaue Aufgaben gefordert sind.&lt;br /&gt;
&lt;br /&gt;
=== Struktur: ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 Config TimerXXX = Timer, Prescale= XX    ‘Konfiguriere TimerXXX&lt;br /&gt;
 Enable TimerXXX		          ‘schalte den TimerXXX ein&lt;br /&gt;
 On  TimerXXX   SprungXXX	          ‘verzweige bei TimerXXX überlauf zu SprungXXX&lt;br /&gt;
 Enable Interrupts		          ‘generell Interrupts zulassen&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
 ....Hauptprogramm		‘Hauptprogramm&lt;br /&gt;
 Loop&lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 SprungXXX:			‘Unterprogramm von TimerXXX&lt;br /&gt;
 ....Ausführung			‘arbeitet hier etwas ab und springt mit Return &lt;br /&gt;
 Return				‚ wieder zurück, zum Hauptprogramm&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Zuerst muss man den zu verwendeten Timer mit „Config“, konfigurieren. &lt;br /&gt;
Dazu definiert man ihn als Timer (mann könnte auch einen Counter daraus machen).&lt;br /&gt;
Dazu muss man noch den Prescaler definieren. &amp;gt;Der Prescaler ist der Teiler, der die Quarzfequenz für den Timer reduziert .&lt;br /&gt;
(Sonst würde der Timer immer mit der vollen Frequenz vom Quarz zählen und das würde meistens zu schnell sein.)&lt;br /&gt;
 &lt;br /&gt;
Dann mit „Enable“ den bestimmten Timer einschalten. &lt;br /&gt;
Mit „On“ das Unterprogramm (ISR) definieren, an die der Timer springen soll,  &lt;br /&gt;
wenn dieser überläuft(ISR= Interrupt Service Routine). Dann das generelle Einschalten von Interrupts.&lt;br /&gt;
&lt;br /&gt;
Jeder Zähler hat eine bestimmte, maximale Zählweite. Zählt er über diese, fängt er wieder bei Null an zu zählen (Überlauf).&lt;br /&gt;
Wie weit ein Zähler zählen kann, ergibt sich aus seiner Struktur. Es gibt da 8-Bit Timer (Timer0 und Timer2, beim Mega8)und 16-Bit Timer (Timer1 beim Mega8).&lt;br /&gt;
8-Bit Timer zählen bis 256, 16-Bit Timer bis 65536.&lt;br /&gt;
&lt;br /&gt;
Bei einem Überlauf, unterbricht der Timer das Hauptprogramm und springt in die ISR. Die ISR wird abgearbeitet und mit Return wird wieder an &lt;br /&gt;
die Stelle zurückgesprungen, wo vorher das Hauptprogramm unterbrochen wurde. &lt;br /&gt;
&lt;br /&gt;
Man soll darauf achten, dass in der ISR immer nur kurze Anweisungen abgearbeitet &lt;br /&gt;
werden und der Hauptteil dann im Hauptprogramm bearbeitet wird. &lt;br /&gt;
Sonst kann es sein, dass man den Prozessor damit blockiert.&lt;br /&gt;
&lt;br /&gt;
=== Timer Beispiel: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 Config Timer0 = Timer, Prescale= 8     ‘Konfiguriere Timer0&lt;br /&gt;
 Enable Timer0            	        ‘schalte den Timer0 ein&lt;br /&gt;
 On  Timer0  Isr_von_Timer0	        ‘verzweige bei Timer0 überlauf zu Isr_von_Timer0&lt;br /&gt;
 Enable Interrupts	  &lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
 ....Hauptprogramm&lt;br /&gt;
 Loop&lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 Isr_von_Timer0:			‘ISR von Timer0&lt;br /&gt;
 .....Programm-Code&lt;br /&gt;
 Return&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Timer0 ist nun so eingestellt, dass die Frequenz vom Quarz, durch den Prescaler,  durch 8 geteilt wird.&amp;lt;br&amp;gt;&lt;br /&gt;
(Beim Prescaler kann man Teilungen von 1 , 8 , 64, 256, oder 1024 einstellen).&amp;lt;br&amp;gt; Diese Frequenz kommt nun zum Timer0 und der zählt nun mit dieser Frequenz bis 256.&lt;br /&gt;
Ab 256 läuft der Timer über, fängt wieder bei Null an zu zählen, und verzweigt dabei in die ISR.&lt;br /&gt;
Mit Return springt die ISR dann wieder zum Hauptprogramm zurück.&lt;br /&gt;
In der ISR könnte man z.B. eine Variable hochzählen. Diese würde dann bei einem 8Mhz Quarz, ca. 3906mal in der Sekunde um 1 hochgezählt. ( (8000000Hz/8) /256=3906.26Hz)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Timer im 1 Sekunden Takt ===&lt;br /&gt;
&lt;br /&gt;
Wenn man jetzt z.B. will, dass eine Variable nur alle Sekunden um 1 hochgezählt wird, muss man den Prescaler anpassen und auch noch die Zählweite vom Timer anpassen.&lt;br /&gt;
Die Zählweite vom Timer kann man nur insovern verändern, dass man ihn nicht von Null weg zählen lässt, sondern von einem höheren Wert.(der Überlauf ist immer der maximale Wert vom Timer)&lt;br /&gt;
&lt;br /&gt;
Da der Timer0 aber mit 8-Bit jetzt zu kurz zählt (0-256) und wir mit einem grossen Prescaler auch nicht auf 1 Sekunde kommen, nehmen wir dazu den Timer1.&lt;br /&gt;
&lt;br /&gt;
Der Timer1 ist ein 16-Bit Timer und kann  von 0-65536 zählen.&lt;br /&gt;
&lt;br /&gt;
Wenn ich jetzt einen Prescaler von 256 verwende, bekomme ich bei einem 8Mhz Quarz, eine Taktrate von 31250Hz. Das heist, dass der Zähler in einer Sekunde  von 0 bis 31250 zählt. Wenn ich jetzt will, dass der Timer nach 31250 Zählungen überläuft (weil nur beim Überlaufen springt er in die ISR und zählt somit meine Variable um 1 hoch), darf ich den Timer nicht von Null wegzählen lassen sondern von einem höheren Wert.&lt;br /&gt;
&lt;br /&gt;
Dazu muss ich die maximale mögliche Zählweite (16-Bit = 65536) von meiner gewünschten Zählweite, abziehen. Also 65536-31250 = 34286 .Der Timer muss also schon bei 34286 zu zählen anfangen und macht dann nach 1 Sekunde einen Überlauf. 34286+31250= 65536 = Überlauf&lt;br /&gt;
&lt;br /&gt;
Hier ein Beispiel mit dem Timer 1.&lt;br /&gt;
Zur Kontrolle wird eine Led im Sekundentakt aus und ein geschalten.&lt;br /&gt;
Man kann in der ISR auch eine Variable hochzählen lassen.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$regfile = &amp;quot;m8def.dat&amp;quot;                    'für Mega8 &lt;br /&gt;
$crystal = 8000000                        'für 8MHz Quarz&lt;br /&gt;
&lt;br /&gt;
Config Portd = Output                     'definiert Portd als Output&lt;br /&gt;
&lt;br /&gt;
Config Timer1 = Timer , Prescale = 256    'Konfiguriere Timer1&lt;br /&gt;
Enable Timer1                             'schalte den Timer1 ein&lt;br /&gt;
On Timer1 Isr_von_timer1                  'verzweige bei Timer1 überlauf zu   Isr_von_Timer1&lt;br /&gt;
Enable Interrupts&lt;br /&gt;
Timer1 = 34286                            'Timer1 soll schon von 34286 wegzählen&lt;br /&gt;
&lt;br /&gt;
Do&lt;br /&gt;
 '....Hauptprogramm&lt;br /&gt;
Loop&lt;br /&gt;
End&lt;br /&gt;
&lt;br /&gt;
Isr_von_timer1:                            'ISR von Timer1&lt;br /&gt;
Timer1 = 34286                             'Timer1 soll wieder von 34286 wegzählen&lt;br /&gt;
Toggle Portd.0                             'schaltet Portd.0 im Sekundentakt&lt;br /&gt;
                                           'EIN und AUS&lt;br /&gt;
'....oder z.B. incr Variable   &lt;br /&gt;
&lt;br /&gt;
Return&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Vorgabe (Timer1=34286) soll man vor dem Hauptprogramm reinsetzen und bei der ISR.&lt;br /&gt;
Wenn man die Vorgabe nicht bei der ISR reinsetzen würde (ISR = Überlauf), würde er ja wieder bei 0 statt bei 34286 anfangen zu zählen.&lt;br /&gt;
&lt;br /&gt;
Um sich das Rechnen zu ersparen könnte man statt der Anweisung: Timer1 = 34286 , auch den Befehl &amp;quot;Load&amp;quot; verwenden. &lt;br /&gt;
&lt;br /&gt;
Man gibt dann ein:  Load Timer1 , 31250 &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit Load rechnet sich der Compiler selber die Werte aus ( 65536-31250 ).Man gibt einfach nach dem Komma, die beabsichtigte Zählweite ein.&lt;br /&gt;
&lt;br /&gt;
Damit hat man nun einen Timer der alle Sekunden eine Variable hochzählt.&lt;br /&gt;
&lt;br /&gt;
Um das Zählen der Sekunden noch genauer zu machen, müsste man noch die Zeiten für Sprung in die ISR u.s.w. mit einberechen. Aber für die meisten Anwendungen reicht diese Genauigkeit vollkommen aus !  :-)&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;
* [[Timer]]&lt;br /&gt;
* [[Bascom]]&lt;br /&gt;
* [[Interrupt]]&lt;br /&gt;
&lt;br /&gt;
==Weblinks==&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/dload.php?action=file&amp;amp;file_id=169 AvrTimer Windows Berechnungstool / Bascom Codegenerator]&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>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_Timer&amp;diff=5699</id>
		<title>Bascom und Timer</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Bascom_und_Timer&amp;diff=5699"/>
				<updated>2006-01-30T07:34:00Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Timer im 1 Sekunden Takt */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Bascom Timer (Mega8 und andere) ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Zweck ===&lt;br /&gt;
[[Timer]] sind selbständige Zähler im Prozessor. Man braucht sie dort, wo zeitkritische und genaue Aufgaben gefordert sind.&lt;br /&gt;
&lt;br /&gt;
=== Struktur: ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 Config TimerXXX = Timer, Prescale= XX    ‘Konfiguriere TimerXXX&lt;br /&gt;
 Enable TimerXXX		          ‘schalte den TimerXXX ein&lt;br /&gt;
 On  TimerXXX   SprungXXX	          ‘verzweige bei TimerXXX überlauf zu SprungXXX&lt;br /&gt;
 Enable Interrupts		          ‘generell Interrupts zulassen&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
 ....Hauptprogramm		‘Hauptprogramm&lt;br /&gt;
 Loop&lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 SprungXXX:			‘Unterprogramm von TimerXXX&lt;br /&gt;
 ....Ausführung			‘arbeitet hier etwas ab und springt mit Return &lt;br /&gt;
 Return				‚ wieder zurück, zum Hauptprogramm&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Zuerst muss man den zu verwendeten Timer mit „Config“, konfigurieren. &lt;br /&gt;
Dazu definiert man ihn als Timer (mann könnte auch einen Counter daraus machen).&lt;br /&gt;
Dazu muss man noch den Prescaler definieren. &amp;gt;Der Prescaler ist der Teiler, der die Quarzfequenz für den Timer reduziert .&lt;br /&gt;
(Sonst würde der Timer immer mit der vollen Frequenz vom Quarz zählen und das würde meistens zu schnell sein.)&lt;br /&gt;
 &lt;br /&gt;
Dann mit „Enable“ den bestimmten Timer einschalten. &lt;br /&gt;
Mit „On“ das Unterprogramm (ISR) definieren, an die der Timer springen soll,  &lt;br /&gt;
wenn dieser überläuft(ISR= Interrupt Service Routine). Dann das generelle Einschalten von Interrupts.&lt;br /&gt;
&lt;br /&gt;
Jeder Zähler hat eine bestimmte, maximale Zählweite. Zählt er über diese, fängt er wieder bei Null an zu zählen (Überlauf).&lt;br /&gt;
Wie weit ein Zähler zählen kann, ergibt sich aus seiner Struktur. Es gibt da 8-Bit Timer (Timer0 und Timer2, beim Mega8)und 16-Bit Timer (Timer1 beim Mega8).&lt;br /&gt;
8-Bit Timer zählen bis 256, 16-Bit Timer bis 65536.&lt;br /&gt;
&lt;br /&gt;
Bei einem Überlauf, unterbricht der Timer das Hauptprogramm und springt in die ISR. Die ISR wird abgearbeitet und mit Return wird wieder an &lt;br /&gt;
die Stelle zurückgesprungen, wo vorher das Hauptprogramm unterbrochen wurde. &lt;br /&gt;
&lt;br /&gt;
Man soll darauf achten, dass in der ISR immer nur kurze Anweisungen abgearbeitet &lt;br /&gt;
werden und der Hauptteil dann im Hauptprogramm bearbeitet wird. &lt;br /&gt;
Sonst kann es sein, dass man den Prozessor damit blockiert.&lt;br /&gt;
&lt;br /&gt;
=== Timer Beispiel: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 Config Timer0 = Timer, Prescale= 8     ‘Konfiguriere Timer0&lt;br /&gt;
 Enable Timer0            	        ‘schalte den Timer0 ein&lt;br /&gt;
 On  Timer0  Isr_von_Timer0	        ‘verzweige bei Timer0 überlauf zu Isr_von_Timer0&lt;br /&gt;
 Enable Interrupts	  &lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
 ....Hauptprogramm&lt;br /&gt;
 Loop&lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 Isr_von_Timer0:			‘ISR von Timer0&lt;br /&gt;
 .....Programm-Code&lt;br /&gt;
 Return&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Timer0 ist nun so eingestellt, dass die Frequenz vom Quarz, durch den Prescaler,  durch 8 geteilt wird.&amp;lt;br&amp;gt;&lt;br /&gt;
(Beim Prescaler kann man Teilungen von 1 , 8 , 64, 256, oder 1024 einstellen).&amp;lt;br&amp;gt; Diese Frequenz kommt nun zum Timer0 und der zählt nun mit dieser Frequenz bis 256.&lt;br /&gt;
Ab 256 läuft der Timer über, fängt wieder bei Null an zu zählen, und verzweigt dabei in die ISR.&lt;br /&gt;
Mit Return springt die ISR dann wieder zum Hauptprogramm zurück.&lt;br /&gt;
In der ISR könnte man z.B. eine Variable hochzählen. Diese würde dann bei einem 8Mhz Quarz, ca. 3906mal in der Sekunde um 1 hochgezählt. ( (8000000Hz/8) /256=3906.26Hz)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Timer im 1 Sekunden Takt ===&lt;br /&gt;
&lt;br /&gt;
Wenn man jetzt z.B. will, dass eine Variable nur alle Sekunden um 1 hochgezählt wird, muss man den Prescaler anpassen und auch noch die Zählweite vom Timer anpassen.&lt;br /&gt;
Die Zählweite vom Timer kann man nur insovern verändern, dass man ihn nicht von Null weg zählen lässt, sondern von einem höheren Wert.(der Überlauf ist immer der maximale Wert vom Timer)&lt;br /&gt;
&lt;br /&gt;
Da der Timer0 aber mit 8-Bit jetzt zu kurz zählt (0-256) und wir mit einem grossen Prescaler auch nicht auf 1 Sekunde kommen, nehmen wir dazu den Timer1.&lt;br /&gt;
&lt;br /&gt;
Der Timer1 ist ein 16-Bit Timer und kann  von 0-65536 zählen.&lt;br /&gt;
&lt;br /&gt;
Wenn ich jetzt einen Prescaler von 256 verwende, bekomme ich bei einem 8Mhz Quarz, eine Taktrate von 31250Hz. Das heist, dass der Zähler in einer Sekunde  von 0 bis 31250 zählt. Wenn ich jetzt will, dass der Timer nach 31250 Zählungen überläuft (weil nur beim Überlaufen springt er in die ISR und zählt somit meine Variable um 1 hoch), darf ich den Timer nicht von Null wegzählen lassen sondern von einem höheren Wert.&lt;br /&gt;
&lt;br /&gt;
Dazu muss ich die maximale mögliche Zählweite (16-Bit = 65536) von meiner gewünschten Zählweite, abziehen. Also 65536-31250 = 34286 .Der Timer muss also schon bei 34286 zu zählen anfangen und macht dann nach 1 Sekunde einen Überlauf. 34286+31250= 65536 = Überlauf&lt;br /&gt;
&lt;br /&gt;
Hier ein Beispiel mit dem Timer 1.&lt;br /&gt;
Zur Kontrolle wird eine Led im Sekundentakt aus und ein geschalten.&lt;br /&gt;
Man kann in der ISR auch eine Variable hochzählen lassen.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$regfile = &amp;quot;m8def.dat&amp;quot;                    'für Mega8 &lt;br /&gt;
$crystal = 8000000                        'für 8MHz Quarz&lt;br /&gt;
&lt;br /&gt;
Config Portd = Output                     'definiert Portd als Output&lt;br /&gt;
&lt;br /&gt;
Config Timer1 = Timer , Prescale = 256    'Konfiguriere Timer1&lt;br /&gt;
Enable Timer1                             'schalte den Timer1 ein&lt;br /&gt;
On Timer1 Isr_von_timer1                  'verzweige bei Timer1 überlauf zu   Isr_von_Timer1&lt;br /&gt;
Enable Interrupts&lt;br /&gt;
Timer1 = 34286                            'Timer1 soll schon von 34286 wegzählen&lt;br /&gt;
&lt;br /&gt;
Do&lt;br /&gt;
 '....Hauptprogramm&lt;br /&gt;
Loop&lt;br /&gt;
End&lt;br /&gt;
&lt;br /&gt;
Isr_von_timer1:                            'ISR von Timer1&lt;br /&gt;
Timer1 = 34286                             'Timer1 soll wieder von 34286 wegzählen&lt;br /&gt;
Toggle Portd.3                             'schaltet Pin1 vom Portd im Sekundentakt&lt;br /&gt;
                                           'EIN und AUS&lt;br /&gt;
Return&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Vorgabe (Timer1=34286) soll man vor dem Hauptprogramm reinsetzen und bei der ISR.&lt;br /&gt;
Wenn man die Vorgabe nicht bei der ISR reinsetzen würde (ISR = Überlauf), würde er ja wieder bei 0 statt bei 34286 anfangen zu zählen.&lt;br /&gt;
&lt;br /&gt;
Um sich das Rechnen zu ersparen könnte man statt der Anweisung: Timer1 = 34286 , auch den Befehl &amp;quot;Load&amp;quot; verwenden. &lt;br /&gt;
&lt;br /&gt;
Man gibt dann ein:  Load Timer1 , 31250 &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit Load rechnet sich der Compiler selber die Werte aus ( 65536-31250 ).Man gibt einfach nach dem Komma, die beabsichtigte Zählweite ein.&lt;br /&gt;
&lt;br /&gt;
Damit hat man nun einen Timer der alle Sekunden eine Variable hochzählt.&lt;br /&gt;
&lt;br /&gt;
Um das Zählen der Sekunden noch genauer zu machen, müsste man noch die Zeiten für Sprung in die ISR u.s.w. mit einberechen. Aber für die meisten Anwendungen reicht diese Genauigkeit vollkommen aus !  :-)&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;
* [[Timer]]&lt;br /&gt;
* [[Bascom]]&lt;br /&gt;
* [[Interrupt]]&lt;br /&gt;
&lt;br /&gt;
==Weblinks==&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/dload.php?action=file&amp;amp;file_id=169 AvrTimer Windows Berechnungstool / Bascom Codegenerator]&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>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_I2C_EEprom&amp;diff=5621</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=5621"/>
				<updated>2006-01-25T23:20:10Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Autor */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Ansteuern vom I2C EEprom's mit Bascom ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Allgemein ===&lt;br /&gt;
[[I2C]]&lt;br /&gt;
&lt;br /&gt;
[http://www.eseo.de/i2c.htm ESEO-Home]&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 schreiben&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C16 ===&lt;br /&gt;
Zum besseren Verständniss werden hier die I2C Befehle untereinander geschrieben.&lt;br /&gt;
In einem grösserem Programm, empfiehlt sich aber eine Sub-Routine zu deklarieren, die dann den Schreib/lese Vorgänge abwickelt.&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 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;
&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;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C256 ===&lt;br /&gt;
&lt;br /&gt;
EEprom  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 Adressberreich in Low und High Adressbereich trennen.&lt;br /&gt;
(Zuerst Low-Adressbereich schreiben und dann High-Adressberreich)&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 A                                'Sende Speicheradresse LOw&lt;br /&gt;
I2cwbyte 1                                'Sende Speicheradresse High&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 Low&lt;br /&gt;
I2cwbyte 1                                  'sende Speicheradresse High&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;
&lt;br /&gt;
&lt;br /&gt;
=== Low/High 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 Low_adresse                              'Sende Speicheradresse  LOW&lt;br /&gt;
I2cwbyte High_adresse                             'Sende Speicheradresse High&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 Low_adresse                          'Sende Speicheradresse Low&lt;br /&gt;
I2cwbyte High_adresse                         'Sende Speicheradresse High&lt;br /&gt;
&lt;br /&gt;
I2cstart                                      'Start&lt;br /&gt;
I2cwbyte &amp;amp;HA1                                 'Sende Slavadresse +1 für Schreiben&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;
&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 Berreich von zwei Byte und braucht daher den Berreich 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;
&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;
&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>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_I2C_EEprom&amp;diff=5619</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=5619"/>
				<updated>2006-01-25T23:18:56Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Die Sache mit dem Overlay : */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Ansteuern vom I2C EEprom's mit Bascom ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Allgemein ===&lt;br /&gt;
[[I2C]]&lt;br /&gt;
&lt;br /&gt;
[http://www.eseo.de/i2c.htm ESEO-Home]&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 schreiben&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C16 ===&lt;br /&gt;
Zum besseren Verständniss werden hier die I2C Befehle untereinander geschrieben.&lt;br /&gt;
In einem grösserem Programm, empfiehlt sich aber eine Sub-Routine zu deklarieren, die dann den Schreib/lese Vorgänge abwickelt.&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 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;
&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;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C256 ===&lt;br /&gt;
&lt;br /&gt;
EEprom  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 Adressberreich in Low und High Adressbereich trennen.&lt;br /&gt;
(Zuerst Low-Adressbereich schreiben und dann High-Adressberreich)&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 A                                'Sende Speicheradresse LOw&lt;br /&gt;
I2cwbyte 1                                'Sende Speicheradresse High&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 Low&lt;br /&gt;
I2cwbyte 1                                  'sende Speicheradresse High&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;
&lt;br /&gt;
&lt;br /&gt;
=== Low/High 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 Low_adresse                              'Sende Speicheradresse  LOW&lt;br /&gt;
I2cwbyte High_adresse                             'Sende Speicheradresse High&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 Low_adresse                          'Sende Speicheradresse Low&lt;br /&gt;
I2cwbyte High_adresse                         'Sende Speicheradresse High&lt;br /&gt;
&lt;br /&gt;
I2cstart                                      'Start&lt;br /&gt;
I2cwbyte &amp;amp;HA1                                 'Sende Slavadresse +1 für Schreiben&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;
&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 Berreich von zwei Byte und braucht daher den Berreich 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;
&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;
&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;br /&gt;
&lt;br /&gt;
'''Aus dem Forum'''&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=12086&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=15433&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=10945&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/viewtopic.php?t=15661]&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_I2C_EEprom&amp;diff=5618</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=5618"/>
				<updated>2006-01-25T23:18:31Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Low/High Adressbereich mit Overlay leicht ansprechen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Ansteuern vom I2C EEprom's mit Bascom ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Allgemein ===&lt;br /&gt;
[[I2C]]&lt;br /&gt;
&lt;br /&gt;
[http://www.eseo.de/i2c.htm ESEO-Home]&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 schreiben&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C16 ===&lt;br /&gt;
Zum besseren Verständniss werden hier die I2C Befehle untereinander geschrieben.&lt;br /&gt;
In einem grösserem Programm, empfiehlt sich aber eine Sub-Routine zu deklarieren, die dann den Schreib/lese Vorgänge abwickelt.&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 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;
&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;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C256 ===&lt;br /&gt;
&lt;br /&gt;
EEprom  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 Adressberreich in Low und High Adressbereich trennen.&lt;br /&gt;
(Zuerst Low-Adressbereich schreiben und dann High-Adressberreich)&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 A                                'Sende Speicheradresse LOw&lt;br /&gt;
I2cwbyte 1                                'Sende Speicheradresse High&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 Low&lt;br /&gt;
I2cwbyte 1                                  'sende Speicheradresse High&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;
&lt;br /&gt;
&lt;br /&gt;
=== Low/High 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 Low_adresse                              'Sende Speicheradresse  LOW&lt;br /&gt;
I2cwbyte High_adresse                             'Sende Speicheradresse High&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 Low_adresse                          'Sende Speicheradresse Low&lt;br /&gt;
I2cwbyte High_adresse                         'Sende Speicheradresse High&lt;br /&gt;
&lt;br /&gt;
I2cstart                                      'Start&lt;br /&gt;
I2cwbyte &amp;amp;HA1                                 'Sende Slavadresse +1 für Schreiben&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 Berreich von zwei Byte und braucht daher den Berreich 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;
&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;
&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;br /&gt;
&lt;br /&gt;
'''Aus dem Forum'''&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=12086&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=15433&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=10945&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/viewtopic.php?t=15661]&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_I2C_EEprom&amp;diff=5617</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=5617"/>
				<updated>2006-01-25T23:18:09Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Beispiel für EEprom 24C256 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Ansteuern vom I2C EEprom's mit Bascom ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Allgemein ===&lt;br /&gt;
[[I2C]]&lt;br /&gt;
&lt;br /&gt;
[http://www.eseo.de/i2c.htm ESEO-Home]&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 schreiben&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C16 ===&lt;br /&gt;
Zum besseren Verständniss werden hier die I2C Befehle untereinander geschrieben.&lt;br /&gt;
In einem grösserem Programm, empfiehlt sich aber eine Sub-Routine zu deklarieren, die dann den Schreib/lese Vorgänge abwickelt.&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 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;
&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;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C256 ===&lt;br /&gt;
&lt;br /&gt;
EEprom  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 Adressberreich in Low und High Adressbereich trennen.&lt;br /&gt;
(Zuerst Low-Adressbereich schreiben und dann High-Adressberreich)&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 A                                'Sende Speicheradresse LOw&lt;br /&gt;
I2cwbyte 1                                'Sende Speicheradresse High&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 Low&lt;br /&gt;
I2cwbyte 1                                  'sende Speicheradresse High&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;
=== Low/High 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 Low_adresse                              'Sende Speicheradresse  LOW&lt;br /&gt;
I2cwbyte High_adresse                             'Sende Speicheradresse High&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 Low_adresse                          'Sende Speicheradresse Low&lt;br /&gt;
I2cwbyte High_adresse                         'Sende Speicheradresse High&lt;br /&gt;
&lt;br /&gt;
I2cstart                                      'Start&lt;br /&gt;
I2cwbyte &amp;amp;HA1                                 'Sende Slavadresse +1 für Schreiben&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;
&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 Berreich von zwei Byte und braucht daher den Berreich 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;
&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;
&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;br /&gt;
&lt;br /&gt;
'''Aus dem Forum'''&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=12086&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=15433&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=10945&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/viewtopic.php?t=15661]&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_I2C_EEprom&amp;diff=5616</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=5616"/>
				<updated>2006-01-25T23:17:09Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Das mit dem Overlay : */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Ansteuern vom I2C EEprom's mit Bascom ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Allgemein ===&lt;br /&gt;
[[I2C]]&lt;br /&gt;
&lt;br /&gt;
[http://www.eseo.de/i2c.htm ESEO-Home]&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 schreiben&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C16 ===&lt;br /&gt;
Zum besseren Verständniss werden hier die I2C Befehle untereinander geschrieben.&lt;br /&gt;
In einem grösserem Programm, empfiehlt sich aber eine Sub-Routine zu deklarieren, die dann den Schreib/lese Vorgänge abwickelt.&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 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;
&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  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 Adressberreich in Low und High Adressbereich trennen.&lt;br /&gt;
(Zuerst Low-Adressbereich schreiben und dann High-Adressberreich)&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 A                                'Sende Speicheradresse LOw&lt;br /&gt;
I2cwbyte 1                                'Sende Speicheradresse High&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 Low&lt;br /&gt;
I2cwbyte 1                                  'sende Speicheradresse High&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Low/High 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 Low_adresse                              'Sende Speicheradresse  LOW&lt;br /&gt;
I2cwbyte High_adresse                             'Sende Speicheradresse High&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 Low_adresse                          'Sende Speicheradresse Low&lt;br /&gt;
I2cwbyte High_adresse                         'Sende Speicheradresse High&lt;br /&gt;
&lt;br /&gt;
I2cstart                                      'Start&lt;br /&gt;
I2cwbyte &amp;amp;HA1                                 'Sende Slavadresse +1 für Schreiben&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;
&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 Berreich von zwei Byte und braucht daher den Berreich 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;
&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;
&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;br /&gt;
&lt;br /&gt;
'''Aus dem Forum'''&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=12086&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=15433&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=10945&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/viewtopic.php?t=15661]&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_I2C_EEprom&amp;diff=5615</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=5615"/>
				<updated>2006-01-25T23:16:47Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Das mit dem Overlay : */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Ansteuern vom I2C EEprom's mit Bascom ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Allgemein ===&lt;br /&gt;
[[I2C]]&lt;br /&gt;
&lt;br /&gt;
[http://www.eseo.de/i2c.htm ESEO-Home]&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 schreiben&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C16 ===&lt;br /&gt;
Zum besseren Verständniss werden hier die I2C Befehle untereinander geschrieben.&lt;br /&gt;
In einem grösserem Programm, empfiehlt sich aber eine Sub-Routine zu deklarieren, die dann den Schreib/lese Vorgänge abwickelt.&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 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;
&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  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 Adressberreich in Low und High Adressbereich trennen.&lt;br /&gt;
(Zuerst Low-Adressbereich schreiben und dann High-Adressberreich)&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 A                                'Sende Speicheradresse LOw&lt;br /&gt;
I2cwbyte 1                                'Sende Speicheradresse High&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 Low&lt;br /&gt;
I2cwbyte 1                                  'sende Speicheradresse High&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Low/High 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 Low_adresse                              'Sende Speicheradresse  LOW&lt;br /&gt;
I2cwbyte High_adresse                             'Sende Speicheradresse High&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 Low_adresse                          'Sende Speicheradresse Low&lt;br /&gt;
I2cwbyte High_adresse                         'Sende Speicheradresse High&lt;br /&gt;
&lt;br /&gt;
I2cstart                                      'Start&lt;br /&gt;
I2cwbyte &amp;amp;HA1                                 'Sende Slavadresse +1 für Schreiben&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;
&lt;br /&gt;
&lt;br /&gt;
=== Das 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 Berreich von zwei Byte und braucht daher den Berreich 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;
&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;
&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;br /&gt;
&lt;br /&gt;
'''Aus dem Forum'''&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=12086&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=15433&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=10945&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/viewtopic.php?t=15661]&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_I2C_EEprom&amp;diff=5614</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=5614"/>
				<updated>2006-01-25T23:13:43Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Ansteuern vom I2C EEprom's mit Bascom ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Allgemein ===&lt;br /&gt;
[[I2C]]&lt;br /&gt;
&lt;br /&gt;
[http://www.eseo.de/i2c.htm ESEO-Home]&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 schreiben&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C16 ===&lt;br /&gt;
Zum besseren Verständniss werden hier die I2C Befehle untereinander geschrieben.&lt;br /&gt;
In einem grösserem Programm, empfiehlt sich aber eine Sub-Routine zu deklarieren, die dann den Schreib/lese Vorgänge abwickelt.&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 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;
&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  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 Adressberreich in Low und High Adressbereich trennen.&lt;br /&gt;
(Zuerst Low-Adressbereich schreiben und dann High-Adressberreich)&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 A                                'Sende Speicheradresse LOw&lt;br /&gt;
I2cwbyte 1                                'Sende Speicheradresse High&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 Low&lt;br /&gt;
I2cwbyte 1                                  'sende Speicheradresse High&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Low/High 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 Low_adresse                              'Sende Speicheradresse  LOW&lt;br /&gt;
I2cwbyte High_adresse                             'Sende Speicheradresse High&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 Low_adresse                          'Sende Speicheradresse Low&lt;br /&gt;
I2cwbyte High_adresse                         'Sende Speicheradresse High&lt;br /&gt;
&lt;br /&gt;
I2cstart                                      'Start&lt;br /&gt;
I2cwbyte &amp;amp;HA1                                 'Sende Slavadresse +1 für Schreiben&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;
&lt;br /&gt;
&lt;br /&gt;
=== Das 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 Berreich von zwei Byte und braucht daher den Berreich 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 zu 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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
       &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Autor==&lt;br /&gt;
*  [[Benutzer:Roberto|Roberto]]&lt;br /&gt;
&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;
&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;br /&gt;
&lt;br /&gt;
'''Aus dem Forum'''&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=12086&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=15433&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=10945&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/viewtopic.php?t=15661]&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_I2C_EEprom&amp;diff=5613</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=5613"/>
				<updated>2006-01-25T22:56:51Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Ansteuern vom I2C EEprom's mit Bascom ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Allgemein ===&lt;br /&gt;
[[I2C]]&lt;br /&gt;
&lt;br /&gt;
[http://www.eseo.de/i2c.htm ESEO-Home]&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 schreiben&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C16 ===&lt;br /&gt;
Zum besseren Verständniss werden hier die I2C Befehle untereinander geschrieben.&lt;br /&gt;
In einem grösserem Programm, empfiehlt sich aber eine Sub-Routine zu deklarieren, die dann den Schreib/lese Vorgänge abwickelt.&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 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;
&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  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 Adressberreich in Low und High Adressbereich trennen.&lt;br /&gt;
(Zuerst Low-Adressbereich schreiben und dann High-Adressberreich)&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 A                                'Sende Speicheradresse LOw&lt;br /&gt;
I2cwbyte 1                                'Sende Speicheradresse High&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 Low&lt;br /&gt;
I2cwbyte 1                                  'sende Speicheradresse High&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Low/High 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 Low_adresse                              'Sende Speicheradresse  LOW&lt;br /&gt;
I2cwbyte High_adresse                             'Sende Speicheradresse High&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 Low_adresse                          'Sende Speicheradresse Low&lt;br /&gt;
I2cwbyte High_adresse                         'Sende Speicheradresse High&lt;br /&gt;
&lt;br /&gt;
I2cstart                                      'Start&lt;br /&gt;
I2cwbyte &amp;amp;HA1                                 'Sende Slavadresse +1 für Schreiben&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;
=== Das mit dem Overlay : ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Autor==&lt;br /&gt;
*  [[Benutzer:Roberto|Roberto]]&lt;br /&gt;
&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;
&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;br /&gt;
&lt;br /&gt;
'''Aus dem Forum'''&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=12086&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=15433&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=10945&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/viewtopic.php?t=15661]&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_I2C_EEprom&amp;diff=5612</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=5612"/>
				<updated>2006-01-25T22:55:30Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Low/High Adressbereich mit Overlay leicht ansprechen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Ansteuern vom I2C EEprom's mit Bascom ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Allgemein ===&lt;br /&gt;
[[I2C]]&lt;br /&gt;
&lt;br /&gt;
[http://www.eseo.de/i2c.htm ESEO-Home]&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 schreiben&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C16 ===&lt;br /&gt;
Zum besseren Verständniss werden hier die I2C Befehle untereinander geschrieben.&lt;br /&gt;
In einem grösserem Programm, empfiehlt sich aber eine Sub-Routine zu deklarieren, die dann den Schreib/lese Vorgänge abwickelt.&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 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;
&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  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 Adressberreich in Low und High Adressbereich trennen.&lt;br /&gt;
(Zuerst Low-Adressbereich schreiben und dann High-Adressberreich)&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 A                                'Sende Speicheradresse LOw&lt;br /&gt;
I2cwbyte 1                                'Sende Speicheradresse High&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 Low&lt;br /&gt;
I2cwbyte 1                                  'sende Speicheradresse High&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Low/High 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 Low_adresse                              'Sende Speicheradresse  LOW&lt;br /&gt;
I2cwbyte High_adresse                             'Sende Speicheradresse High&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 Low_adresse                          'Sende Speicheradresse Low&lt;br /&gt;
I2cwbyte High_adresse                         'Sende Speicheradresse High&lt;br /&gt;
&lt;br /&gt;
I2cstart                                      'Start&lt;br /&gt;
I2cwbyte &amp;amp;HA1                                 'Sende Slavadresse +1 für Schreiben&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;
==Autor==&lt;br /&gt;
*  [[Benutzer:Roberto|Roberto]]&lt;br /&gt;
&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;
&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;br /&gt;
&lt;br /&gt;
'''Aus dem Forum'''&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=12086&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=15433&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=10945&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/viewtopic.php?t=15661]&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_I2C_EEprom&amp;diff=5611</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=5611"/>
				<updated>2006-01-25T22:54:14Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Low/High Adressbereich mit Overlay leicht ansprechen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Ansteuern vom I2C EEprom's mit Bascom ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Allgemein ===&lt;br /&gt;
[[I2C]]&lt;br /&gt;
&lt;br /&gt;
[http://www.eseo.de/i2c.htm ESEO-Home]&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 schreiben&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C16 ===&lt;br /&gt;
Zum besseren Verständniss werden hier die I2C Befehle untereinander geschrieben.&lt;br /&gt;
In einem grösserem Programm, empfiehlt sich aber eine Sub-Routine zu deklarieren, die dann den Schreib/lese Vorgänge abwickelt.&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 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;
&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  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 Adressberreich in Low und High Adressbereich trennen.&lt;br /&gt;
(Zuerst Low-Adressbereich schreiben und dann High-Adressberreich)&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 A                                'Sende Speicheradresse LOw&lt;br /&gt;
I2cwbyte 1                                'Sende Speicheradresse High&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 Low&lt;br /&gt;
I2cwbyte 1                                  'sende Speicheradresse High&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Low/High Adressbereich mit Overlay leicht ansprechen ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 '============I2C EEprom versuch V1.05==================================&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 Low_adresse                              'Sende Speicheradresse  LOW&lt;br /&gt;
I2cwbyte High_adresse                             'Sende Speicheradresse High&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 Low_adresse                          'Sende Speicheradresse Low&lt;br /&gt;
I2cwbyte High_adresse                         'Sende Speicheradresse High&lt;br /&gt;
&lt;br /&gt;
I2cstart                                      'Start&lt;br /&gt;
I2cwbyte &amp;amp;HA1                                 'Sende Slavadresse +1 für Schreiben&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;
==Autor==&lt;br /&gt;
*  [[Benutzer:Roberto|Roberto]]&lt;br /&gt;
&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;
&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;br /&gt;
&lt;br /&gt;
'''Aus dem Forum'''&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=12086&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=15433&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=10945&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/viewtopic.php?t=15661]&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_I2C_EEprom&amp;diff=5610</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=5610"/>
				<updated>2006-01-25T22:48:00Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Ansteuern vom I2C EEprom's mit Bascom ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Allgemein ===&lt;br /&gt;
[[I2C]]&lt;br /&gt;
&lt;br /&gt;
[http://www.eseo.de/i2c.htm ESEO-Home]&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 schreiben&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C16 ===&lt;br /&gt;
Zum besseren Verständniss werden hier die I2C Befehle untereinander geschrieben.&lt;br /&gt;
In einem grösserem Programm, empfiehlt sich aber eine Sub-Routine zu deklarieren, die dann den Schreib/lese Vorgänge abwickelt.&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 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;
&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  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 Adressberreich in Low und High Adressbereich trennen.&lt;br /&gt;
(Zuerst Low-Adressbereich schreiben und dann High-Adressberreich)&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 A                                'Sende Speicheradresse LOw&lt;br /&gt;
I2cwbyte 1                                'Sende Speicheradresse High&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 Low&lt;br /&gt;
I2cwbyte 1                                  'sende Speicheradresse High&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Low/High Adressbereich mit Overlay leicht ansprechen ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 '============I2C EEprom versuch V1.05==================================&lt;br /&gt;
&lt;br /&gt;
 ' ===========Für 24C256 EEprom=====================&lt;br /&gt;
&lt;br /&gt;
 ' 8MHz Quarz&lt;br /&gt;
 ' LCD auf Port B ,&lt;br /&gt;
 '&lt;br /&gt;
&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&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'===================Hauptprogramm===============================================&lt;br /&gt;
Cls&lt;br /&gt;
Lcd &amp;quot;I2C EEprom Test&amp;quot;&lt;br /&gt;
Waitms 500&lt;br /&gt;
Cls&lt;br /&gt;
'-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Schreiben = 0&lt;br /&gt;
&lt;br /&gt;
Do&lt;br /&gt;
&lt;br /&gt;
'----schreiben----&lt;br /&gt;
For Adresse = 250 To 260&lt;br /&gt;
Incr X                                                      '1 bis Überlauf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I2cstart                                                    'Start&lt;br /&gt;
I2cwbyte &amp;amp;HA0                                               'Sende Slavadresse&lt;br /&gt;
I2cwbyte Low_adresse                                        'Sende Speicheradresse  LOW&lt;br /&gt;
I2cwbyte High_adresse                                       'Sende Speicheradresse High&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;&lt;br /&gt;
Waitms 500&lt;br /&gt;
Next Adresse&lt;br /&gt;
&lt;br /&gt;
'---lesen----&lt;br /&gt;
&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 Low_adresse                                        'Sende Speicheradresse Low&lt;br /&gt;
I2cwbyte High_adresse                                       'Sende Speicheradresse High&lt;br /&gt;
&lt;br /&gt;
I2cstart                                                    'Start&lt;br /&gt;
I2cwbyte &amp;amp;HA1                                               'Sende Slavadresse +1 für Schreiben&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;&lt;br /&gt;
Waitms 500&lt;br /&gt;
Next Adresse&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
End&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Autor==&lt;br /&gt;
*  [[Benutzer:Roberto|Roberto]]&lt;br /&gt;
&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;
&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;br /&gt;
&lt;br /&gt;
'''Aus dem Forum'''&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=12086&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=15433&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=10945&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/viewtopic.php?t=15661]&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_I2C_EEprom&amp;diff=5609</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=5609"/>
				<updated>2006-01-25T21:44:50Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Beispiel für EEprom 24C256 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Ansteuern vom I2C EEprom's mit Bascom ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Allgemein ===&lt;br /&gt;
[[I2C]]&lt;br /&gt;
&lt;br /&gt;
[http://www.eseo.de/i2c.htm ESEO-Home]&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 schreiben&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C16 ===&lt;br /&gt;
Zum besseren Verständniss werden hier die I2C Befehle untereinander geschrieben.&lt;br /&gt;
In einem grösserem Programm, empfiehlt sich aber eine Sub-Routine zu deklarieren, die dann den Schreib/lese Vorgänge abwickelt.&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 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;
&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  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 Adressberreich in Low und High Adressbereich trennen.&lt;br /&gt;
(Zuerst Low-Adressbereich schreiben und dann High-Adressberreich)&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 A                                'Sende Speicheradresse LOw&lt;br /&gt;
I2cwbyte 1                                'Sende Speicheradresse High&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 Low&lt;br /&gt;
I2cwbyte 1                                  'sende Speicheradresse High&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;
==Autor==&lt;br /&gt;
*  [[Benutzer:Roberto|Roberto]]&lt;br /&gt;
&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;
&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;br /&gt;
&lt;br /&gt;
'''Aus dem Forum'''&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=12086&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=15433&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=10945&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/viewtopic.php?t=15661]&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_I2C_EEprom&amp;diff=5608</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=5608"/>
				<updated>2006-01-25T21:40:19Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Beispiel für EEprom 24C16 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Ansteuern vom I2C EEprom's mit Bascom ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Allgemein ===&lt;br /&gt;
[[I2C]]&lt;br /&gt;
&lt;br /&gt;
[http://www.eseo.de/i2c.htm ESEO-Home]&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 schreiben&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C16 ===&lt;br /&gt;
Zum besseren Verständniss werden hier die I2C Befehle untereinander geschrieben.&lt;br /&gt;
In einem grösserem Programm, empfiehlt sich aber eine Sub-Routine zu deklarieren, die dann den Schreib/lese Vorgänge abwickelt.&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 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;
&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  24C128, 24C256 haben im Gegensatz zu den 24C16'er einen Adressraum von zwei Byte.&lt;br /&gt;
Darum muss man den Adressberreich in Low und High Adressbereich trennen.&lt;br /&gt;
(Zuerst Low-Adressbereich schreiben und dann High-Adressberreich)&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 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 A                                'Sende Speicheradresse LOw&lt;br /&gt;
I2cwbyte 1                                'Sende Speicheradresse High&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 Low&lt;br /&gt;
I2cwbyte 1                                  'sende Speicheradresse High&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;
==Autor==&lt;br /&gt;
*  [[Benutzer:Roberto|Roberto]]&lt;br /&gt;
&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;
&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;br /&gt;
&lt;br /&gt;
'''Aus dem Forum'''&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=12086&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=15433&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=10945&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/viewtopic.php?t=15661]&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_I2C_EEprom&amp;diff=5607</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=5607"/>
				<updated>2006-01-25T21:11:17Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Siehe auch */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Ansteuern vom I2C EEprom's mit Bascom ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Allgemein ===&lt;br /&gt;
[[I2C]]&lt;br /&gt;
&lt;br /&gt;
[http://www.eseo.de/i2c.htm ESEO-Home]&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 schreiben&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C16 ===&lt;br /&gt;
Zum besseren Verständniss werden hier die I2C Befehle untereinander geschrieben.&lt;br /&gt;
In einem grösserem Programm, empfiehlt sich aber eine Sub-Routine zu deklarieren, die dann den Schreib/lese Vorgänge abwickelt.&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 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;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C256 ===&lt;br /&gt;
&lt;br /&gt;
EEprom  24C128, 24C256 haben im Gegensatz zu den 24C16'er einen Adressraum von zwei Byte.&lt;br /&gt;
Darum muss man den Adressberreich in Low und High Adressbereich trennen.&lt;br /&gt;
(Zuerst Low-Adressbereich schreiben und dann High-Adressberreich)&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 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 A                                'Sende Speicheradresse LOw&lt;br /&gt;
I2cwbyte 1                                'Sende Speicheradresse High&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 Low&lt;br /&gt;
I2cwbyte 1                                  'sende Speicheradresse High&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;
==Autor==&lt;br /&gt;
*  [[Benutzer:Roberto|Roberto]]&lt;br /&gt;
&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;
&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;br /&gt;
&lt;br /&gt;
'''Aus dem Forum'''&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=12086&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=15433&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=10945&amp;amp;highlight=eeprom]&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/viewtopic.php?t=15661]&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_I2C_EEprom&amp;diff=5606</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=5606"/>
				<updated>2006-01-25T21:10:20Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Siehe auch */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Ansteuern vom I2C EEprom's mit Bascom ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Allgemein ===&lt;br /&gt;
[[I2C]]&lt;br /&gt;
&lt;br /&gt;
[http://www.eseo.de/i2c.htm ESEO-Home]&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 schreiben&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C16 ===&lt;br /&gt;
Zum besseren Verständniss werden hier die I2C Befehle untereinander geschrieben.&lt;br /&gt;
In einem grösserem Programm, empfiehlt sich aber eine Sub-Routine zu deklarieren, die dann den Schreib/lese Vorgänge abwickelt.&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 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;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C256 ===&lt;br /&gt;
&lt;br /&gt;
EEprom  24C128, 24C256 haben im Gegensatz zu den 24C16'er einen Adressraum von zwei Byte.&lt;br /&gt;
Darum muss man den Adressberreich in Low und High Adressbereich trennen.&lt;br /&gt;
(Zuerst Low-Adressbereich schreiben und dann High-Adressberreich)&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 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 A                                'Sende Speicheradresse LOw&lt;br /&gt;
I2cwbyte 1                                'Sende Speicheradresse High&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 Low&lt;br /&gt;
I2cwbyte 1                                  'sende Speicheradresse High&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;
==Autor==&lt;br /&gt;
*  [[Benutzer:Roberto|Roberto]]&lt;br /&gt;
&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;
&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;br /&gt;
&lt;br /&gt;
'''Aus dem Forum'''&lt;br /&gt;
*[[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=12086&amp;amp;highlight=eeprom]]&lt;br /&gt;
*[[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=15433&amp;amp;highlight=eeprom]]&lt;br /&gt;
*[[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=10945&amp;amp;highlight=eeprom]]&lt;br /&gt;
*[[http://www.roboternetz.de/phpBB2/viewtopic.php?t=15661]]&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_I2C_EEprom&amp;diff=5605</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=5605"/>
				<updated>2006-01-25T21:09:05Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Allgemein */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Ansteuern vom I2C EEprom's mit Bascom ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Allgemein ===&lt;br /&gt;
[[I2C]]&lt;br /&gt;
&lt;br /&gt;
[http://www.eseo.de/i2c.htm ESEO-Home]&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 schreiben&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C16 ===&lt;br /&gt;
Zum besseren Verständniss werden hier die I2C Befehle untereinander geschrieben.&lt;br /&gt;
In einem grösserem Programm, empfiehlt sich aber eine Sub-Routine zu deklarieren, die dann den Schreib/lese Vorgänge abwickelt.&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 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;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C256 ===&lt;br /&gt;
&lt;br /&gt;
EEprom  24C128, 24C256 haben im Gegensatz zu den 24C16'er einen Adressraum von zwei Byte.&lt;br /&gt;
Darum muss man den Adressberreich in Low und High Adressbereich trennen.&lt;br /&gt;
(Zuerst Low-Adressbereich schreiben und dann High-Adressberreich)&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 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 A                                'Sende Speicheradresse LOw&lt;br /&gt;
I2cwbyte 1                                'Sende Speicheradresse High&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 Low&lt;br /&gt;
I2cwbyte 1                                  'sende Speicheradresse High&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;
==Autor==&lt;br /&gt;
*  [[Benutzer:Roberto|Roberto]]&lt;br /&gt;
&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;
&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;br /&gt;
&lt;br /&gt;
'''Aus dem Forum'''&lt;br /&gt;
[[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=12086&amp;amp;highlight=eeprom]]&lt;br /&gt;
[[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=15433&amp;amp;highlight=eeprom]]&lt;br /&gt;
[[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=10945&amp;amp;highlight=eeprom]]&lt;br /&gt;
[[http://www.roboternetz.de/phpBB2/viewtopic.php?t=15661]]&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_I2C_EEprom&amp;diff=5604</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=5604"/>
				<updated>2006-01-25T21:08:36Z</updated>
		
		<summary type="html">&lt;p&gt;Roberto: /* Allgemein */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Ansteuern vom I2C EEprom's mit Bascom ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Allgemein ===&lt;br /&gt;
[[I2C]]/&amp;lt;br&amp;gt;&lt;br /&gt;
[http://www.eseo.de/i2c.htm ESEO-Home]&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 schreiben&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C16 ===&lt;br /&gt;
Zum besseren Verständniss werden hier die I2C Befehle untereinander geschrieben.&lt;br /&gt;
In einem grösserem Programm, empfiehlt sich aber eine Sub-Routine zu deklarieren, die dann den Schreib/lese Vorgänge abwickelt.&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 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;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel für EEprom 24C256 ===&lt;br /&gt;
&lt;br /&gt;
EEprom  24C128, 24C256 haben im Gegensatz zu den 24C16'er einen Adressraum von zwei Byte.&lt;br /&gt;
Darum muss man den Adressberreich in Low und High Adressbereich trennen.&lt;br /&gt;
(Zuerst Low-Adressbereich schreiben und dann High-Adressberreich)&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 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 A                                'Sende Speicheradresse LOw&lt;br /&gt;
I2cwbyte 1                                'Sende Speicheradresse High&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 Low&lt;br /&gt;
I2cwbyte 1                                  'sende Speicheradresse High&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;
==Autor==&lt;br /&gt;
*  [[Benutzer:Roberto|Roberto]]&lt;br /&gt;
&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;
&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;br /&gt;
&lt;br /&gt;
'''Aus dem Forum'''&lt;br /&gt;
[[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=12086&amp;amp;highlight=eeprom]]&lt;br /&gt;
[[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=15433&amp;amp;highlight=eeprom]]&lt;br /&gt;
[[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=10945&amp;amp;highlight=eeprom]]&lt;br /&gt;
[[http://www.roboternetz.de/phpBB2/viewtopic.php?t=15661]]&lt;/div&gt;</summary>
		<author><name>Roberto</name></author>	</entry>

	</feed>