Werte verarbeiten

  • Werte und Ausdrücke auf den Bildschirm ausgeben
  • Werte merken
  • Wie merkt sich ein Computer Werte?

Werte und Ausdrücke auf den Bildschirm ausgeben

Nachdem wir in der letzten Lektion eher theoretisch betrachtet haben, wie man Werte und Datentypen unterscheidet, wollen wir in dieser Lektion wieder etwas praktischer am Computer arbeiten.

Wir kennen bisher nur die Funktion printf() und wissen, wie man einfache Ausdrücke formulieren kann. Weiterhin können wir Werte und Datentypen unterscheiden.

Die Funktion printf() erlaubt uns Werte auszugeben, aber wir müssen ihr mitteilen, wie sie diese Werte interpretieren soll, schließlich sind für den Computer alles nur Zahlen. Nach unserem Kenntnisstand unterscheiden wir derzeit zwischen den Datentypen Ganzzahl (int) und Fließzahl (float, double). Unser bisheriges Beispielprogramm gab den Text „Hello proggen.org“ aus 1):

  printf( "Hello proggen.org\n" );

In diesen Text kann man Sonderzeichen einfügen, an diese Stelle werden dann Werte eingefügt. Für Integer fügt man ein %d (wie Dezimalzahl) ein, für Floats ein %f. Anschließend führt man den Wert, der eingefügt werden soll, durch ein Komma getrennt hinter dem Text auf:

#include <stdio.h>
 
int main( void )
{
  printf( "4   + 3   ist %d\n", 4+3 );
  printf( "4.0 + 3.0 ist %f\n", 4.0+3.0 );
 
  return 0; 
}

Dabei lassen sich beliebig viele Ausgaben einfügen:

  printf( "%d + %d ist %d\n", 4, 3, 4+3 );
  printf( "%f + %f ist %f\n", 4.0, 3.0, 4.0+3.0 );

Auch einzelne Buchstaben lassen sich so mit dem Sonderzeichen %c (wie Character) ausgeben:

  printf( "Der ASCII-Code %d entspricht dem Zeichen '%c'\n", 48, 48 );

Die erste 48 wird für %d eingesetzt, die dahinterstehende wird für %c eingesetzt. Bei %d wird sie als Dezimalzahl interpretiert und ausgegeben, bei %c wird die 48 stattdessen als ASCII-Zeichen interpretiert und entsprechend eine '0' ausgegeben. Das ganze funktioniert auch umgekehrt:

  printf( "Das Zeichen '%c' besitzt den ASCII-Code %d\n", 48, 48 );
  printf( "Das Zeichen '%c' besitzt den ASCII-Code %d\n", '0', '0' );

Hier wird die gleiche Zeile nun zweimal ausgegeben. Der Wert von '0' ist 48, man sieht, wie wichtig der Datentyp ist, denn er bestimmt, wie 48 interpretiert wird.

Möchte man übrigens ein Prozentzeichen einfügen, so verwendet man zwei Prozentzeichen: %%.

Werte merken

Wenn wir den Computer Aufgaben wie 4+3 lösen lassen, so lösen wir nur dieses absolute und unveränderliche Problem (eben 4+3). Computer sollen jedoch meistens Probleme lösen, die sich in einer Rechenvorschrift beschreiben lassen, einem sogenannten Algorithmus. Man möchte die Zahlen auswechseln können, um auch andere Aufgaben rechnen zu können.

Hierfür benötigen wir einen Identifikator („Identifier“) für Werte, ohne zu wissen, welchen Wert des Identifier hat - wie in der Mathematik, wo Werte durch Buchstaben gekennzeichnet werden.

s = a + b

Genauso machen wir es beim Programmieren. Die Buchstaben sind die Identifier, zusätzlich müssen wir dem Computer jedoch sagen, um welchen Datentyp es sich handelt, also wie der Identifier die Daten verarbeiten soll. Schauen wir uns an, wir man sich in C eine Zahl merkt und sie anschließend auf dem Bildschirm ausgibt.

#include <stdio.h>
 
int main( void )
{
  int   natuerlicheZahl = 4711;      // Neuen Variable bekanntgeben
                                     //   und gleich initialisieren
  float      reelleZahl;             // Variable bekanntgeben 
                                     //   ohne einen Wert zuzuweisen
 
  reelleZahl = 3.1415;               // Variable einen neuen Wert zuweisen
 
  printf( "Ich habe mir folgende Zahlen gemerkt: \n" );
  printf( "natürliche Zahl: %d\n", natuerlicheZahl ); 
  printf( "    reelle Zahl: %f\n",      reelleZahl ); 
 
  return 0; 
}

Wir sehen, dass die Definition von natuerlicheZahl fast aussieht, wie die Definition von main, lediglich die runden Klammern fehlen. Die zeigen den Unterschied zwischen natuerlicheZahl und main auf: natuerlicheZahl merkt sich einfach einen Wert entsprechend des vorangestellten Datentyps, den es auf Anfrage zurückliefert. main als Funktion muss erst seine Funktion ausführen, bevor es einen Wert zurück liefern kann.

Auf natuerlicheZahl wird stattdessen mit dem '='-Operator ein Wert zugewiesen, den der Identifier ab jetzt haben soll. Diese erstmalige Zuweisung eines Wertes nennt man Initialisierung. Die Initialisierung sorgt dafür, dass natuerlicheZahl einen definierten Wert besitzt. C selbst kümmert sich darum nämlich nicht (es weiß ja auch nicht, welcher Wert für uns sinnvoll ist) und so ist reeleZahl einen kurzen Moment bis zur Zuweisung in einem undefinierten Zustand. Wir wissen einfach nicht, welchen Wert reelle Zahl besitzt, bis wir erstmals („initial“) einen Wert zugewiesen haben.

Hier sehen wir einen kleinen Unterschied von C zur Mathematik: Während die Identifikatoren in der Mathematik einen festen, unveränderlichen Wert besitzen, der anhand der Aufgabe zu bestimmen ist, sieht man das bei vielen Programmiersprachen etwas lockerer: Hier können Identifier für einen späteren Zweck überschrieben werden oder zum Zählen verwendet werden. Der Wert von natuerlicheZahl ist also nicht konstant, sondern variabel. Daher nennt man solche veränderlichen Identifikatoren auch Variablen.

Die unnatürliche Schreibweise (ue statt ü) von natuerlicheZahl hat zwei einfache Gründe: Zunächst sind Leerzeichen innerhalb von Identifiern (also unabhängig davon, ob man eine Funktion oder eine Variable benennt) nicht erlaubt. Gleiches gilt für Umlaute (ä, ü, ö) oder dem 'scharfen S' (ß). Identifier müssen mit einem Buchstaben oder Unterstrich ('_') beginnen. Diesem ersten Zeichen dürfen weitere Buchstaben und Unterstriche folgen, sowie auch Zahlen. Es dürfen große und kleine Buchstaben verwendet werden. Der Unterstrich zu Beginn darf aber nur von den Compiler-Herstellern verwendet werden.

Gültige Identifier-Namen:

a
b
_a
zahl
index
Summand1
Summand2
ein_ganz_langer_name
einGanzLangerName

Ungültige Identifier-Namen:

1ZweiDrei              // beginnt mit einer Zahl
natürlicheZahl         // ungültiges Zeichen: ü
nicht erlaubter Name   // Leerzeichen enthalten, wird als
                       //    drei Identifikatoren verstanden.

Eine Variable oder eine Funktion steht immer für einen beliebigen Wert, entsprechend seines Datentyps. Die Variable natuerlicheZahl besitzt also immer einen Integer-Wert, wie die reelleZahl immer einen reellen Wert besitzt. Der Funktion printf() darf man Werte geben, die entsprechend des Formatstrings interpretiert wird. Dabei spielt es keine Rolle, ob dieser Wert direkt angeben wurde, durch eine Variable zurückgegeben wird oder durch einen Ausdruck entstanden ist:

#include <stdio.h>
 
int main( void )
{
  int natuerlicheZahl = 4711;
 
  /* Ausgabe als direkte Angabe, aus Variable oder Ausdruck */
  printf( "Fester Wert: %d\n", 1234 );
  printf( "Variable   : %d\n", natuerlicheZahl );
  printf( "Ausdruck   : %d\n", 17 + 4 );
 
  /* Neuzuweisen einer Variablen */
  natuerlicheZahl = 17 + 4;
 
  printf( "Variable(1): %d\n", natuerlicheZahl );
 
  /* Aufaddieren */
  natuerlicheZahl = natuerlicheZahl + 5;
 
  printf( "Variable(2): %d\n", natuerlicheZahl );
 
  return 0; 
}

Die Variable natuerlicheZahl wird im Verlauf des Programms überschrieben mit dem Wert 17+4:

  natuerlicheZahl = 17 + 4;
 
  printf( "Variable(1): %d\n", natuerlicheZahl );

Dabei wird der Ausdruck erst ausgerechnet (21) und der ausgerechnete Wert anschließend der Variablen natuerlicheZahl zugewiesen. Weder kann man mit der Variablen herausfinden, dass der Wert über einen Ausdruck entstanden ist, noch kommt man an den alten Wert 4711 jemals wieder heran. Sie steht nun einfach für den Wert 21.

Das sieht man noch deutlicher, an der Stelle, an der die Variable erneut überschrieben wird:

  natuerlicheZahl = natuerlicheZahl + 5;
 
  printf( "Variable(2): %d\n", natuerlicheZahl );

Hier wird erst der Ausdruck (natuerlicheZahl + 5) ausgewertet, wobei natuerlicheZahl den zuvor zugewiesenen Wert 21 besitzt. Der Ausdruck besitzt den Wert 21+5, also 26. Dieser Wert wird anschließend wieder natuerlicheZahl zugewiesen, also wird natuerlicheZahl nach dem Ausrechnen mit 26 überschrieben.
Übrigens: Auch natuerlicheZahl = 26 ist ein Ausdruck, die Zuweisung gibt nämlich das Ergebnis zurück, das zugewiesen wurde. Damit lassen sich zum Beispiel mehrere Variablen in einem großen Ausdruck überschreiben:

int a, b, c;
 
a = b = c = 0;

Die '='-Operation läuft von rechts nach links ab: Erst wird rechts ausgewertet (Wert 0), dann links (c =). c wird also überschrieben und das Ergebnis (also 0) zurückgegeben. Das Ergebnis von (c = 0) ist der rechte Teil von b = ….

Wichtig ist das Verständnis, dass Ausdrücke immer weiter verknüpft werden können.

Später im Tutorial werden wir auch noch Funktionen verwenden, die ja ebenfalls Werte zurückgeben können.

Ziel dieser Lektion

Du solltest nun in der Lage sein, einfache Aufgaben mit Variablen berechnen zu können und Dir das Ergebnis anzeigen zu lassen.

Definiere zwei Variablen a und b und weise ihnen Werte zu. Berechne dann die Summe von a zum Quadrat und b zum Quadrat und lass Dir das Ergebnis auf dem Bildschirm ausgeben. Beginne damit, das Ergebnis erst in einer Variablen c zwischen zu speichern und optimiere dann die Variable c aus dem Programm hinaus, in dem du die den Ausdruck, um c zu bestimmen, direkt in die printf-Anweisung überträgst.

Eine schöne Übung ist einen Budgetplaner zu schreiben. Berechne Deine monatlichen Einnahmen und monatlichen Ausgaben und ziehe Dein Gehalt davon ab. Multipliziere das Ergebnis mit 12. Addiere jährliche Einnahmen (Steuerrückzahlung, Weihnachtsgeld) und subtrahiere jährliche Kosten (Versicherung, KFZ-Steuer).

In der kommenden Lektion werden wir lernen Entscheidungen zu treffen.

1) das ist auch ein Wert eines Datentyp, aber um diesen kümmern wir uns später ausführlich