Programmieren lernen Kapitel 4 Kontrollstrukturen

Tutorials zu verschiedenen Softwarenutzungen

Moderator: Moderatoren

Benutzeravatar
Jaegerfeld
Tribunus Angusticlavius
Tribunus Angusticlavius
Beiträge: 3571
Registriert: 10. November 2010 21:15
Wohnort: AudiCity
:
Pfeiler der Community Gewinner Userwahl

Programmieren lernen Kapitel 4 Kontrollstrukturen

Beitragvon Jaegerfeld » 4. Dezember 2010 19:18

Kapitel 4
Kontrollstrukturen


Nachdem wir jetzt schön addieren können, fehlen unserem kleinen Taschenrechner natürlich noch die anderen drei Grundrechenarten.

Wir wollen uns im Anschluss ein kleines Menü schreiben, mit dessen Hilfe wir beim Programmstart wählen können was wir machen wollen.

Legt ein neues Projekt an und schreibt folgendes:

Code: Alles auswählen

namespace Taschenrechner
{
  class Program
  {
    static void Main(string[] args)
    {
      Console.WriteLine("1 - Addition \n2 - Subtraktion \n3 - Multiplikation \n4 - Division");
      string inputString = Console.ReadLine();
 
      System.Threading.Thread.Sleep(10000);
    }
  }
}

Das sollte uns folgenden Bildschirm bescheren:

Bild

In Zeile 7 bieten wir dem User vier Möglichkeiten an, er soll sich eine aussuchen.
Das \n ist eine sogenannte Escape-Sequenz. Die modernen Rechner verstehen immer noch die Befehler der alten elektronischen Schreibmaschinen und \n bedeutet einfach "new Line", also : neue Zeile, was dem betätigen der Taste RETURN entspricht.
Wollen wir dem Rechner also sagen, dass er 'ne neue Zeile beginnen soll reicht es im String die Zeichen folge \n zu schreiben.
Das bringt uns auch zu einer Einschränkung: Escape-Symbole werden immer mit \ eingeleitet, wir dürfen also kein \ im normalen Text verwenden. Wollen wir trotzdem \ schreiben, müssen wir einfach zwei \ machen. \\ wird also hiermit zu \.
In Zeile 8 warten wir dann auf die Eingabe des Users und schreiben das in den string "inputString".
Jetzt wäre es gut, eine Möglichkeit zu haben den Code an dieser Stelle zu verzweigen.
Die einfachste und gleichzeitig am häufigsten genutze ist die Verwendung einer IF Abfrage.
If ist englisch und bedeutet nichts anderes als WENN.
Nehmen wir also mal an, wir hätten eine Variable a vom Typ int.
Wenn wir jetzt

Code: Alles auswählen

if ( a == 1) {     // Tue irgendwas }

schreiben, wertet der Rechner die variable a aus, und wenn sie den Wert 1 hat, macht er alles was in den gschweiften Klammern steht.
Wenn nicht, dann setzt er einfach nach der schließenden Klammern seine Arbeit fort ohne das was dazwischen steht zu beachten.
Wir können das beliebig inneinander verschachteln, so etwas ist also möglich;

Code: Alles auswählen

if(a ==1 )
{
  if(b==2)
  {
    if (c==3)
    {
      // usw. bis zum jüngsten Gericht
    }
  }
}

SCHÖN ist das aber nicht, es gibt viel bessere Möglichkeiten so was zu tun.
Wer ihr euch jetzt fragt was das // und das == bedeuten, will ich mal kurz ein paar Worte dazu verlieren.
Das // markiert einen Kommentar, ähnlich dem # in HOI2.
Alles was nach einem // steht ist NICHT Teil des Codes, der Compiler ignoriert das einfach. Ihr solltet euren Code immer schön kommentieren, denn nichts ist peinlicher als nach ein paar Wochen seinen eigenen Code nicht mehr zu verstehen.
Macht euch also Notizen.
Will man einen Kommentar über mehrere Zeilen schreiben, so reicht es (statt in jeder Zeile am Anfang //) bei Beginn /* und am Ende */ zu schreiben. Im weiteren Verlauf dieser Tutorials werden wir noch mehr Möglichkeiten kennenlernen. Heutzutage kann man sich anze Dokumentationen erstellen lassen, wenn man nur seine Kommentare richtig setzt. Sehr nützlich bei Projekten die etwas größer sind als 3 Dateien.
Das == ist etwas völlig anderes, es ist ein Vergleichsoperator und bedeutet einfach "IST GENAU GLEICH".
Im Gegensatz zu unserer sehr schwammigen Umgangssprache unterscheidet ein Rechner zwischen "IST" und "IST GLEICH".
Ein = wird verwendet wenn ich etwas einen Wert zuweisen will.


bedeutet also: a hat jetzt den Wert b, oder einfach: a IST b. Ab jetzt meine ich eigentlich b wenn ich a sage, beide sind identisch.


bedeutet aber: FRAGE: IST a GLEICH b ?
es wird also a mit b verglichen und als Ergebnis gibt uns der Rechner die Antwort true oder false zurück.
Zwei vollkommen verschiedene Vorgänge also, wir benötigen beide ständig, gewöhnt euch also daran ab jetzt exakt das zu schreiben was ihr meint.
Es gibts noch mehr Vergleichsoperatoren, ihr kennt die aus der Schule:
a < b a ist kleiner als b ; 4 < 6 würde true ergebn, 6 < 4 false
a > b a ist größer als b ; 4 > 6 gibt false, 6 > 4 true
darüber hinaus gibt es noch
a != b
! bezeichnet eine Negation, also eine Umkehrung der Bedeutung.
a != b bedeutet nichts anderes als : a IST UNGLEICH b. 4 != 5 ist true, 4 != 4 false.
Das ! kann auch alleine vor Variablen stehen, es geht also so etwas: !true.
Das gibt was?.............



false, was sonst?
Wenn ! alleine steht dreht es die Bedeutung des folgenden Wertes. Was jetzt eine Invertierung im konkreten Fall genau ist, ist dann definitionssache. Bei den Wahrheitswerten TRUE und FALSE ist es aber wohl klar.
Hört sich jetzt unglaublich doof an, aber manchmal ist es sehr viel einfacher und kürzer das Gegenteil von dem zu schreiben was man meint und dann einfach ! davor zu stellen. (Wer mal Wahrscheinlichkeitstheorie in der Schule hatte kennt sicher Komplementärereignisse und wie nützlich sie manchmal sind)
Mit unserem neuen Wissen bewaffnet schreiben wir uns ein paar Methoden, die unsere Rechenoperationen ausführen:

Code: Alles auswählen

static double addition(double a, double b)
{
  return a + b;
}
static double substraktion(double a, double b)
{
  return a - b;
}
static double multiplikation(double a, double b)
{
  return a * b;
}
static double division(double a, double b)
{
  return a / b;
}

Das static vor den Rückgabewerten braucht euch momentan nicht weiter zu interessieren, es ist notwendig und damit Basta.
Ich erkläre das später.
Jetzt können wir unsere Verzweigung einbauen:

Code: Alles auswählen

if (inputString.Equals("1") )
{
  Console.WriteLine("Addition");
  Console.WriteLine("Bitte ersten Operand eingeben: ");
  string a = Console.ReadLine();
  Console.WriteLine("Bitte zweiten Operand eingeben: ");
  string b = Console.ReadLine();
  double c = addition(Convert.ToDouble(a), Convert.ToDouble(b));
  Console.WriteLine(a + "+" + b + " = " + c);
}

Wenn wir das jetzt für alle vier Möglichkeiten wiederholen ist unser kleiner Taschenrechner schon fast fertig.
Im ganzen sieht das bei mir jetzt so aus:

Code: Alles auswählen

namespace Taschenrechner
{
  class Program
  {
    static void Main(string[] args)
    {
    Console.WriteLine("1 - Addition \n2 - Subtraktion \n3 - Multiplikation \n4 - Division");
    string inputString = Console.ReadLine();
    if (inputString.Equals("1") )
    {
      Console.WriteLine("Addition");
      Console.WriteLine("Bitte ersten Operand eingeben: ");
      string a = Console.ReadLine();
      Console.WriteLine("Bitte zweiten Operand eingeben: ");
      string b = Console.ReadLine();
      double c = addition(Convert.ToDouble(a), Convert.ToDouble(b));
      Console.WriteLine(a + "+" + b + " = " + c);
    }
    if (inputString.Equals("2"))
    {
      Console.WriteLine("Substraktion");
      Console.WriteLine("Bitte ersten Operand eingeben: ");
      string a = Console.ReadLine();
      Console.WriteLine("Bitte zweiten Operand eingeben: ");
      string b = Console.ReadLine();
      double c = substraktion(Convert.ToDouble(a), Convert.ToDouble(b));
      Console.WriteLine(a + "-" + b + " = " + c);
    }
    if (inputString.Equals("3"))
    {
      Console.WriteLine("Multiplikation");
      Console.WriteLine("Bitte ersten Operand eingeben: ");
      string a = Console.ReadLine();
      Console.WriteLine("Bitte zweiten Operand eingeben: ");
      string b = Console.ReadLine();
      double c = multiplikation(Convert.ToDouble(a), Convert.ToDouble(b));
      Console.WriteLine(a + "*" + b + " = " + c);
    }
    if (inputString.Equals("1"))
    {
      Console.WriteLine("Division");
      Console.WriteLine("Bitte ersten Operand eingeben: ");
      string a = Console.ReadLine();
      Console.WriteLine("Bitte zweiten Operand eingeben: ");
      string b = Console.ReadLine();
      double c = division(Convert.ToDouble(a), Convert.ToDouble(b));
      Console.WriteLine(a + "/" + b + " = " + c);
    }
 
    System.Threading.Thread.Sleep(10000);
  }
 
  static double addition(double a, double b)
  {
    return a + b;
  }
  static double substraktion(double a, double b)
  {
    return a - b;
  }
  static double multiplikation(double a, double b)
  {
    return a * b;
  }
  static double division(double a, double b)
  {
    return a / b;
  }
 
  }
}

Dummerweise reagiert er gar nicht, wenn jemand bei der Menüauswahl eine falsche Zahl eintippt.
Das wollen wir jetzt abfangen und damit auch gleich ein neues Befehlswort einführen.
ELSE ist wiederum englisch und bedeutet SONST.
wenn wir also

Code: Alles auswählen

if(a==1)
{
  // Anweisung A
}
else
{
  // Anweisung B

schreiben, sagen wir dem Rechner folgendes:
Wenn a gleich 1 ist, dann mach die Anweisung A, in allen anderen Fällen (auf Deutsch: sonst) die Anweisung B.
Dies lässt sich auch wieder beliebig ineinander verschachteln.
Nutzen wir das also und ergänzen die main - Methode um die folgende Anweisung:

Code: Alles auswählen

else
{
  Console.WriteLine("ungültige Menüauswahl - Programm wird beendet!");
}

Jetzt ist diese Fehlerquelle behoben.
Trotzdem bleiben noch eine Menge Benutzerfehler die wir momentan nicht berücksichtigen:
  • Was passiert wenn ein User einen BUCHSTABEN als Operand eingibt ?
  • Was passiert, wenn ein Benutzer durch 0 teilt ( NUR Chuck Norris darf das)?
Macht euch mal darüber Gedanken, ihr habt eigentlich alle Mittel zur Hand um das abzufangen.
Es gibt noch eine weitere, viel elegantere Möglichkeit im Code zu verzweigen.
Wer komplexe Verzweigungen benötigt und keine Lust auf if Kaskaden hat, soll sich mal mit switch - case auseinandersetzen.
Ich werde die später einmal erklären.
Im nächsten Kapitel werden wir uns die SCHLEIFEN mal genauer ansehen. Damit erhalten wir die Möglichkeit bestimmte Codebereiche mehrmals aufzurufen.
Wenn wir das eingebaut haben schafft der Taschenrechner auch endlich mehr als eine Berechnung pro Programmstart.
Danach sind wir mit den Basics durch und widmen uns einer grafischen Oberfläche.
Ziel ist es etwas zu erschaffen, das optisch dem in Windows eingebauten Rechner ähnelt.

P.S.: Bevor ich es vergesse: ein BUG ist auch noch drinn. Wenn man eine Berechnung gemacht hat und der zweite Operand eine 1,2,3oder 4 war, verhält sich das Programm seltsam.
Denkt mal darüber nach und behebt den fehler. Es ist eigentlich ganz einfach, das Wissen dazu habt ihr schon.
„Ich schätze mal, das kann jeder Online-Community passieren. Irgendwann stellen die höflichen und vernünftigen Leute fest, dass sie sich in dieser Gruppe nicht mehr aufhalten wollen. Also verschwinden die. Und diejenigen die übrig bleiben, erfahren nur noch die Leute die genau so wie sie drauf sind.“

=== David Gaider, Bioware ===