+#include <stdio.h>
+
+/*
+
+- Arrays
+- Zeigerarithmetik
+- Strings
+- Funktionszeiger
+
+*/
+
+
+/////////////////////////////////////////
+// Arrays
+
+// Array
+// 1. Elemente sind alle vom gleichen Typ
+// 2. Fixe Länge
+// 3. Kein "out-of-bounds" check!
+
+void arrays() {
+ int i;
+ int a[5] = { 1, 2, 3, 4, 5};
+
+ for(i=0; i < 6; i++) {
+ printf("%d", a[i]);
+ }
+
+
+}
+
+/////////////////////////////////////////
+// Zeigerarithmetik
+
+// 1. Arrayname ist eine Referenz auf das erste Element
+// 2. p sei ein Zeiger dann ist
+// p + 1 die Referenz auf den Nachfolger und
+// p - 1 die Referenz auf den Vorgänger
+
+void zeiger() {
+ int i;
+ int a[5] = { 1, 2, 3, 4, 5};
+ int* p;
+
+ p = a;
+ // entspricht
+ // p = &a[0];
+
+ printf("%d", *p); // Ausgabe erstes Element
+ p = p + 1; // Zeiger verweist auf zweites Element
+ printf("%d", *p); // Ausgabe zweites Element
+ p = p + 2;
+ printf("%d", *p); // Ausgabe viertes Element
+ p = p - 1;
+ printf("%d", *p); // Ausgabe drittes Element
+
+}
+
+
+/////////////////////////////////////////
+// Strings
+
+// 1. Eine String ist ein Array von Zeichen
+// 2. In C wird folgender Trick angewandt um die Laenge des strings zu verwalten.
+// 3. Das Ende eines strings in C wird mit einem speziellen ASCII Code gekennzeichnet.
+// Der ASCII Code 0 ("Null") wird verwendet, um das Ende des strings zu markieren.
+// Dies wird auch als "Null Terminierung" bezeichnet und diesen
+// speziellen ASCII Code nennen wir auch Null Terminator.
+
+
+int len(char s[]) {
+ int i = 0;
+
+ while(s[i] != '\0') {
+ i++;
+ }
+ return i;
+}
+
+// Variante.
+// char s[] entspricht const char*s
+// Da wir den Zeiger s inkrementieren verwenden wir char* s.
+int len2(char* s) {
+ int i = 0;
+
+ while(*s != '\0') {
+ i++;
+ s++;
+ }
+ return i;
+}
+
+
+void strings() {
+
+ char str[] = "Hello";
+
+ char str2[] = "12";
+
+ // Falls elementweise Initialisierung muss explizit der Nullterminator am Schluss stehen!
+ char str3[] = { '1', '2', '\0'};
+
+ char str4[] = { '1', '2'};
+
+
+ printf("%d", len(str));
+ printf("%d", len2(str));
+
+ printf("%d", len(str3));
+ printf("%d", len(str4));
+
+}
+
+
+/////////////////////////////////////////
+// Funktionszeiger
+
+
+// Parameter f ist ein Zeiger (Referenz) auf eine Funktion.
+// Diese Funktion erwartet einen int Wert und liefert einen int Wert zurueck.
+void mapInt(int* p, int len, int (*f)(int)) {
+ int i;
+ for(i=0; i<len; i++)
+ p[i] = (*f)(p[i]);
+}
+
+// Beachte.
+// Oft werden "shorthands" via typedef verwendet.
+
+typedef int (*intFunc)(int);
+
+void mapInt2(int* p, int len, intFunc f) {
+ int i;
+ for(i=0; i<len; i++)
+ p[i] = (*f)(p[i]);
+}
+
+// In "modernem" C koennen wir schreiben.
+void mapIn3(int* p, int len, int f(int)) {
+ int i;
+ for(i=0; i<len; i++)
+ p[i] = (*f)(p[i]);
+}
+
+
+
+int inc(int x) { return x+1; }
+int square(int x) { return x*x; }
+
+
+void funktionsZeiger() {
+ int x[5] = { 1,2,3,4,5 };
+ mapInt(x,5,&inc);
+ mapInt(x,5,&square);
+
+ printf("%d", x[1]);
+}
+
+
+int main() {
+ arrays();
+ zeiger();
+ strings();
+ funktionsZeiger();
+}