Grundsätzliches Wissen für angehende Programmierer/-innen
Der Raspberry Pi 400 für knapp 100.- € zum Anschluss an den Fernseher (hier mit englischem Netzteil!)
- Jede Anwendung eines persönlichen Computers, jede Website, jede App ist ein Computerprogramm.
- Computerprogramme sind Listen von Anweisungen, die vom Computer der Reihe nach abgearbeitet werden.
- Diese Listen werden in ein Textprogramm eingegeben, in Bits und Bytes übersetzt und dann ausgeführt.
- Anweisungen in Programmen bestehen aus Schlüsselwörtern und Parametern, die die Anweisungen genauer spezifizieren.
- Ein Beispiel "aus dem richtigen Leben" wäre Starte das Auto, wobei Starte das Schlüsselwort und das Auto der Parameter ist.
- Ein Schlüsselwort sagt dem Computer, was zu tun ist, ein Parameter erklärt, womit etwas zu tun ist.
Besonderheiten von C
- C ist eine sehr kompakte Programmiersprache von immerhin 1968.
- Sie ist damit oft älter als ihre Programmierer. :-)
- C wird auch heute noch benutzt.
- Sehr viele große Projekte sind in C geschrieben (Windows, Linux, Office).
- Dennoch laufen sehr viele C-Programme aus alter Zeit unverändert auch heute noch.
- C ist also sehr kompatibel zu sich selbst.
- C ermöglicht es, sehr kleine und schnelle Compiler zu bauen, denn
- die Prüfung von 10.000 Klammern ({}) schafft der Compiler schnell.
- die Prüfung von 10.000 Wörtern (BEGIN...END) dauert dagegen länger.
- C ist eine Sprache, die auf sehr kleinen Computern gut ablaufen kann.
- C++ ist eine objektorientierte Version von C.
- Compiler für C++ können immer auch C.
Programmieren in C auf dem eigenen Computer
Die Entwicklungsumgebung GEANY in Aktion auf dem Raspi 400.
- Um ein Programm in einer Programmiersprache zu schreiben, braucht man ein passendes Übersetzungsprogramm für diese Sprache.
- Solche Übersetzungsprogramme übersetzen eine Programmiersprache in die universelle Sprache aller Computer (Bits und Bytes).
- Solcher Übersetzungsprogramme heißen Compiler.
- Man benötigt also für C einen C-Compiler und
- einen Editor (Textverarbeitung für Programmierer) zum Erfassen des Programms oder
- am besten alles zusammen: eine "Integrierte Entwicklungsumgebung (IDE)".
- Ich zum Beispiel benutze diese hier (Windows, MacOS).
- Auf einem Raspberry Pi kann man einfach Geany benutzen.
- Oder Sie programmieren einfach hier und jetzt online.
Funktionen
- Ein Problem wird zur Lösung in viele kleine Probleme zerlegt.
- Beispiel: "Kuchen backen" kann in "Mische Mehl, Eier...", "Heize den Backofen", "Knete den Teig" etc. aufgeteilt werden.
- Programme können in kleine Abschnitte eingeteilt werden, die einzelne Unter-Aufgaben erfüllen (Funktionen).
- Diese Funktionen haben einen festgelegten Namen, Parameter und können Werte an das Hauptprogramm zurück geben.
- Den Typ des Rückgabewertes steht vor der Funktion (hier: int = integer = ganze Zahlen).
- main ist die erste Funktion, die in jedem Programm aufgerufen wird. Hier startet also immer das Programm.
- In C-Programmen muss es immer genau eine Funktion mit dem Namen main geben.
- Von main aus werden die erwähnten Funktionen des selben Programms aufgerufen, sofern welche existieren.
- Die Hauptfunktion, das ganze Programm, gibt nach der Abarbeitung des Programms einen Wert an den Computer zurück.
- Ein einfaches Programm sieht also jetzt so aus ("//" leitet einen Kommentar ein):
int main ()
{
// Hier startet das Hauptprogramm
printf ("Zahlenraten - ich denke mir eine Zahl und Du errätst sie. \n");
}
Variable
- Variable sind benannte Speicherstellen, in denen Zwischenergebnisse gespeichert werden können.
- Variable müssen dem C-Compiler erklärt werden, damit sie verwendet werden können: sie werden deklariert.
- Da Programme linear (von oben nach unten) ablaufen, sind Variablen erst ab der Deklaration nutzbar.
- Der Compiler muss wissen, was in den Variablen stehen soll: der Variablentyp.
- Typen für Variable in C: Ganzzahlen (int), Fließkommazahlen (float), Zeichen (char)
- Eine Deklaration sieht typischerweise so aus: <Typ><Leerzeichen><Name><Semikolon>
- Beispiel:
int nGedachteZahl;
- Das "n" vor dem Namen "GedachteZahl" ist nicht notwendig. Es ist aber gute Sitte, den Typ (int, also numerisch) im Namen zu erwähnen.
- Variable können auch einen Anfangswert (Initialisierung) enthalten, der einfach dahinter geschrieben wird.
- Beispiel:
int nGedachteZahl = 24;
- Die Variable nGedachteZahl ist dem Compiler ab diesem Zeitpunkt als Ganzzahl-Speicherstelle bekannt und hat den Wert 24.
- Eine nicht initialisierte Variable hat übrigens nicht den Wert Null sondern einen unbestimmten Wert (Vorsicht!).
- In unserem Beispiel brauchen wir zwei Variable: in einer steht die gedachte Zufallszahl, in der anderen die Vermutung des Benutzers.
- Nach der Erwähnung des Datentyps kann man weitere Variablen definieren.
- Unser Programm sieht bis hierher also so aus:
int nGedachteZahl = 24; // muss erraten werden
nVermutung = 0; // sicher ist sicher
int main ()
{
// Hier startet das Hauptprogramm
printf ("Zahlenraten - ich denke mir eine Zahl und Du errätst sie. \n");
}
Ein- und Ausgabe
d Dezimalzahl
f Gleitkommazahl
c Einzelnes Zeichen
s String (Mehrere Zeichen)
- Nach der Angabe des Typs sind auch Längenangaben u. a. möglich.
- Dieselben Formatvorschriften gelten auch für Eingaben mit scanf.
Bedingungen
- Bedingungen sind WENN-DANN-Anweisungen.
- In C ist das entsprechende Schlüsselwort if.
- Der weitere Programmlauf hängt dann von Bedingungen ab:
> größer als
< kleiner als
== gleich
!= ungleich
>= größer oder gleich
<= kleiner oder gleich
! nicht
- Beispiel: Ob eine eingegebene Zahl größer oder kleiner 1 ist soll in Worten ausgegeben werden:
#include <stdio.h>
int nZahl;
int main()
{
printf ("Bitte geben Sie eine Zahl ein: ");
scanf ("%d", &nZahl);
if (nZahl > 1)
printf ("Die Zahl %d ist größer als Eins. \n", nZahl);
else
printf ("Die Zahl %d ist kleiner als Eins. \n", nZahl);
}
- Die Befehle nach else werden immer ausgeführt, wenn das Gegenteil der Bedingung erfüllt ist.
- Das Gegenteil von gleich ist dann ungleich, das Gegenteil von größer ist kleiner und umgekehrt.
- Man könnte else also mit sonst übersetzen: Wenn...Sonst.
Fallunterscheidungen
- if-Abfragen kann man beliebig wiederholen.
- Bei sehr häufigen Abfragen kann das sehr unübersichtlich werden.
- Deshalb gibt es so genannte Fallunterscheidungen, in denen ein Wert oder eine Variable mehrfach geprüft wird.
- Bei Fallunterscheidungen wird jeder Bedingung ein Programmlauf zugeordnet.
- In C sind die entsprechenden Schlüsselwörter switch und case.
- Beispiel: Eine Zahl zwischen 1 und 3 soll als Wort ausgegeben werden:
#include <stdio.h>
int iZahl;
int main ()
{
printf ("Geben Sie eine Zahl ein: ");
scanf ("%d", &iZahl);
switch (iZahl)
{
case 1: printf ("Eins \n"); break;
case 2: printf ("Zwei \n"); break;
case 3: printf ("Drei \n"); break;
default: printf ("Zahl ist nicht zwischen 1 und 3! \n");
}
}
- Beachten Sie, dass nach der Ausführung eines Falles mit break die Abfrage verlassen werden muss.
- Wenn keine Bedingung zutrifft, wird der Code hinter default ausgeführt.
- In switch können keine Variablen vom Typ char geprüft werden!
Schleifen mit Zähler
- Bei Zählerschleifen werden Schlüsselwörter eine bestimmte Anzahl oft wiederholt.
- Dabei läuft eine Variable mit, die bei jedem Durchlauf verändert wird.
- In C ist das entsprechende Schlüsselwort for.
- Das Format von for ist
for (Startwert, Ablaufbedingung, Änderungsmaßnahme);
- Die Zahlen von 1 bis 10 werden also durch folgendes Programm ausgegeben:
#include <stdio.h>
int nZaehler;
int main ()
{
for (nZaehler = 1; nZaehler < 11; nZaehler++)
{
printf ("Zahl ist %d \n", nZaehler);
}
}
- Am Anfang der Schleife wird nZaehler mit 1 belegt (der Startwert)
- Die Schleife läuft so lange nZahler kleiner als 11 ist (die Ablaufbedingung)
- Bei jedem Durchlaufen der Schleife wird nZaehler um 1 erhöht (die Änderungsmaßnahme, nZaehler = nZaehler + 1 kann man mit nZaehler++ abkürzen).
- Beim Durchlaufen der Schleife wird alles zwischen den folgenden Klammern { und } ausgeführt (hier also die Ausgabe von nZaehler).
- Die Zahlen von 1 bis 10 werden nur ausgegeben, wenn die Ablaufbedingung < 11 heißt, da am Anfang entschieden wird, ob die Schleife durchlaufen werden soll.
- for bildet also eine so genannte Kopfgesteuerte Schleife!
Kopfgesteuerte Schleifen
- Kopfgesteuerte Schleifen prüfen am Anfang der Schleife, ob die Schleife durchlaufen wird.
- Kopfgesteuerte Schleifen werden mit dem Wort while gebildet.
- Kopfgesteuerte Schleifen machen Sinn, wenn eine Schleife unter bestimmten Bedingungen keinen Sinn ergibt.
- Beispielsweise kann man eine Datei nicht auslesen, wenn am Anfang der Schleife das Ende der Datei bereits erreicht oder sie leer ist.
- Man könnte die Zahlen von 1 bis 10 auch mit einer kopfgesteuerten Schleife ausgeben:
#include <stdio.h>
int nZaehler;
int main ()
{
nZaehler = 0;
while (nZaehler < 10)
{
nZaehler++;
printf ("Zahl ist %d \n", nZaehler);
}
}
- Sie werden alle Anweisungen aus der for-Schleife hier wiederfinden!
- Aber überlegen Sie mal, warum die Werte der Variablen anders sind.
Fußgesteuerte Schleifen
- Fußgesteuerte Schleifen prüfen am Ende der Schleife, ob die Bedingung zum Beenden erreicht ist.
- Fußgesteuerte Schleifen werden mit den Schlüsselwörter do..while gebildet.
- Fußgesteuerte Schleifen machen Sinn, wenn die Bedingung innerhalb der Schleife verändert wird.
- Beispielsweise kann eine Schleife so lange laufen, bis während der Schleife ein bestimmter Wert eingegeben wird.
- Die Zahlen von 1 bis 10 mit einer fußgesteuerten Schleife:
#include <stdio.h>
int nZaehler;
int main ()
{
nZaehler = 0;
do
{
nZaehler++;
printf ("Zahl ist %d \n", nZaehler);
} while (nZaehler < 10);
}
- Beachten Sie, wo ein Semikolon gesetzt ist (und wo nicht).
Dateien
- Normalerweise kommt an dieser Stelle die Behandlung von Dateien.
- Programme können Dateien erzeugen, verwalten und löschen.
- Dateien werden heute aber "in Reinform" kaum noch benutzt.
- Daher verweise ich hier auf die Einbettung von Datenbank-Befehlen in C-Programme.
- Nutzen Sie Datenbanken wo Sie können. Dateien sind immer nur die zweitbeste Lösung!
- Sie brauchen keinen Datenbank-Server. Forschen Sie z. B. nach SQLite.
Zahlenraten
- Zum Schluss ein kleines Spiel, in dem Sie einige der erklärten Regeln betrachten können:
// (1) zahlenraten.c - Ein kleines Spiel, bei dem der Computer sich eine Zahl
// ausdenkt und Sie diese erraten müssen. 27.04.2021
// (2) Damit alle Befehle funktionieren, müssen wir sie dem C-Compiler
// bekannt machen. Denn viele Befehle kennt C nicht. Die werden dann
// aus sogenannten Standard-Bibliotheken eingelesen.
#include <stdio.h> // printf und scanf
#include <stdlib.h> // srand und rand
#include <time.h> // time
// (3) Jedes C-Programm hat einen Abschnitt (eine "Funktion") namens
// main. Hier beginnt und endet ein C-Programm immer. main muss immer
// da sein und muss immer main heißen!
int main ()
{
// (4) Wir beschreiben ("deklarieren") Speicherstellen ("Variable"), die
// wir im Programm benutzen wollen mit möglichst aussagekräftigen Namen
// und einem Buchstaben am Beginn, der die Art des Inhalts bezeichnet.
// i = int = integer = ganze Zahl, also keine Fließkommazahlen
int iGedachteZahl; // Hier wird die vom Computer gedachte Zahl gespeichert
int iVermutung; // Hier wird die vom Benutzer vermutete Zahl gespeichert
// In C kann man Variable auch gleich mit einem Startwert belegen
int iZahlMin = 0; // Minimale Größe der gedachten Zahl
int iZahlMax = 100; // Maximale Größe der gedachten Zahl
// (5) Das Programm wurde gestartet. Wir geben einen Text aus:
// \n = mit Zeilenumbruch
// \n weglassen = ohne Zeilenumbruch
printf ("Zahlenraten - Ich denke mir eine Zahl und Sie erraten diese. \n");
printf ("Ich denke mir also eine Zahl zwischen %d und %d", iZahlMin, iZahlMax);
// (6) Zufallszahl generieren: hier rufen wir die Funktionen auf, die wir
// bei (2) mit #include oben bekannt gemacht haben: srand, time und rand.
srand (time (0));
iGedachteZahl = (rand() % (iZahlMax - iZahlMin + 1)) + iZahlMin;
printf ("...fertig. \n"); // wird in der selben Zeile wie (5) ausgegeben
// (7) Eine Schleife: die Anweisungen in den Klammern nach do
// werden immer wiederholt ...
do {
printf ("Ihre Vermutung? ");
scanf ("%d", &iVermutung);
if (iVermutung > iGedachteZahl) {
printf ("Die Zahl ist kleiner! \n");
};
if (iVermutung < iGedachteZahl) {
printf ("Die Zahl ist größer! \n");
}
} while (iVermutung != iGedachteZahl);
// ... solange iVermutung ungleich iGedachteZahl ist, sonst zurück zu (7)
// (8) Hierher kommt der Computer nur, wenn iVermutung gleich iGedachteZahl ist,
// die Zahl vom Benutzer also erraten wurde
printf ("Richtig geraten!!!! Es war die %d!", iGedachteZahl);
// (9) Unser Programm ist beendet. 0 zurück geben an das Betriebssystem,
// damit es erkennt, dass das Programm fehlerfrei abgelaufen ist
return 0;
}