C++ Flusssteuerung

C++C++Beginner
Jetzt üben

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einführung

In diesem Lab werden Sie die Steuerungsflussanweisungen in C++ lernen. Sie werden lernen, wie if-else-Anweisungen, Switch-Anweisungen, while-Schleifen, do-while-Schleifen und for-Schleifen verwendet werden.

Inhaltsvorschau

Es gibt drei grundlegende Steuerungsflusskonstrukte - sequentiell, bedingt (oder entscheidend) und schleifenbasiert (oder iterativ). Die sequentielle Struktur: Der Ausführungsprozess erfolgt Zeile für Zeile von oben nach unten. Die bedingte Struktur verwendet die if-else-Anweisung, um zu überprüfen, ob eine Anweisung eine bestimmte Bedingung erfüllt, und trifft dann eine Entscheidung. Die Schleifenstruktur wird verwendet, um einige logische Operationen wiederholt auszuführen.

image desc

Sequentieller Steuerungsfluss

Ein Programm ist eine Folge von Anweisungen. Der sequentielle Fluss ist der häufigste und einfachste, bei dem die Programmanweisungen in der Reihenfolge ausgeführt werden, in der sie geschrieben sind - von oben nach unten in sequentieller Weise.

Bedingter Steuerungsfluss

Es gibt verschiedene Arten von Bedingungen, if-then, if-then-else, geschachtelte-if (if-elseif-elseif-...-else), switch-case und bedingte Ausdruck.

#include <iostream>
using namespace std;

int main(){

	int mark;

	cout<<"Eingabe einer Zahl [0-100]: ";
	cin>>mark;
    // if
    if (mark >= 50) {
       cout << "Glückwunsch!" << endl;
       cout << "Behalte es aufrecht!" << endl;
    }

    cout<<"Eingabe einer Zahl [0-100]: ";
	cin>>mark;
    // if-else
    if (mark >= 50) {
       cout << "Glückwunsch!" << endl;
       cout << "Behalte es aufrecht!" << endl;
    } else {
       cout << "Versuche es noch einmal!" << endl;
    }

	cout<<"Eingabe einer Zahl [0-100]: ";
	cin>>mark;
    // geschachtelte-if
    if (mark >= 80) {
       cout << "A" << endl;
    } else if (mark >= 70) {
       cout << "B" << endl;
    } else if (mark >= 60) {
       cout << "C" << endl;
    } else if (mark >= 50) {
       cout << "D" << endl;
    } else {
       cout << "F" << endl;
    }

    // switch-case
    char oper;
    int num1 = 1, num2 = 2, result = 0;
    cout<<"Eingabe eines Zeichens [+ - / *]: ";
    cin>> oper;
    switch (oper) {
       case '+':
          result = num1 + num2;
          break;
       case '-':
          result = num1 - num2;
          break;
       case '*':
          result = num1 * num2;
          break;
       case '/':
          result = num1 / num2;
          break;
       default:
          cout << "Unbekannter Operator" << endl;
    }
    cout<<num1<<oper<<num2<<"="<<result;
    return 0;
}

Ausgabe:

Eingabe einer Zahl [0-100]: 50
Glückwunsch!
Behalte es aufrecht!
Eingabe einer Zahl [0-100]: 40
Versuche es noch einmal!
Eingabe einer Zahl [0-100]: 85
A
Eingabe eines Zeichens [+ - / *]: +
1+2=3
image desc

Bedingter Operator: Ein bedingter Operator ist ein ternärer (3-Operand) Operator, in der Form booleanExpr? trueExpr : falseExpr. Je nach booleanExpr wertet er aus und gibt den Wert von trueExpr oder falseExpr zurück.

// gibt entweder "PASS" oder "FAIL" zurück und gibt es an cout aus
cout << (mark >= 50)? "PASS" : "FAIL" << endl;

max = (a > b)? a : b;   // RHS gibt a oder b zurück
abs = (a > 0)? a : -a;  // RHS gibt a oder -a zurück

Klammern: Sie können die Klammern { } weglassen, wenn es nur eine Anweisung innerhalb des Blocks gibt. Beispielsweise:

if (mark >= 50)
   cout << "PASS" << endl;   // Nur eine Anweisung, kann { } weggelassen werden, wird aber nicht empfohlen
else {                       // mehr als eine Anweisung, braucht { }
   cout << "FAIL" << endl;
   cout << "Versuche es noch einmal!" << endl;
}

Wir empfehlen jedoch, die Klammern beizubehalten, auch wenn es nur eine Anweisung im Block gibt, um die Lesbarkeit Ihres Programms zu verbessern.

Schleifensteuerungsfluss

Es gibt wiederum verschiedene Arten von Schleifen: for-Schleife, while-do und do-while.

// for-Schleife
int sum = 0;
for (int number = 1; number <= 100; ++number) {
   sum += number;
}

// while-do
int sum = 0, number = 1;
while (number <= 100) {
   sum += number;
   ++number;
}

// do-while
int sum = 0, number = 1;
do {
   sum += number;
   ++number;
} while (number <= 100);

Fordern Sie den Benutzer nach einem Obergrenzwert auf. Summieren Sie die ganzen Zahlen von 1 bis zu einem angegebenen Obergrenzwert und berechnen Sie deren Durchschnitt.

/*
 * Summiere von 1 bis zu einem angegebenen Obergrenzwert und berechne ihren Durchschnitt.
 */
#include <iostream>
using namespace std;

int main() {
   int sum = 0;     // Speichert die kumulative Summe
   int upperbound;
   cout << "Geben Sie den Obergrenzwert ein: ";
   cin >> upperbound;

   // Summiere von 1 bis zum Obergrenzwert
   for (int number = 1; number <= upperbound; ++number) {
      sum += number;
   }
   cout << "Summe ist " << sum << endl;
   cout << "Durchschnitt ist " << (double)sum / upperbound << endl;

   // Summiere nur die ungeraden Zahlen
   int count = 0;     // Anzahl der ungeraden Zahlen
   sum = 0;           // Setze die Summe zurück
   for (int number=1; number <= upperbound; number=number+2) {
      ++count;
      sum += number;
   }
   cout << "Summe der ungeraden Zahlen ist " << sum << endl;
   cout << "Durchschnitt ist " << (double)sum / count << endl;
}

Ausgabe:

Geben Sie den Obergrenzwert ein: 15
Summe ist 120
Durchschnitt ist 8
Summe der ungeraden Zahlen ist 64
Durchschnitt ist 8
image desc

Unterbrechen des Schleifenflusses - "break" und "continue"

Die break-Anweisung bricht aus und verlässt die aktuelle (innerste) Schleife.

Die continue-Anweisung bricht die aktuelle Iteration ab und springt zur nächsten Iteration der aktuellen (innersten) Schleife.

break und continue sind schlechte Strukturen, da sie schwer zu lesen und zu verstehen sind. Verwenden Sie sie nur, wenn es absolut notwendig ist. Sie können immer das gleiche Programm schreiben, ohne break und continue zu verwenden.

Das folgende Programm listet die Nicht-Primzahlen zwischen 2 und einem Obergrenzwert.

/*
 *  Liste Nicht-Primzahlen von 1 bis zu einem Obergrenzwert.
 */
#include <iostream>
#include <cmath>
using namespace std;

int main() {
   int upperbound;
   cout << "Geben Sie den Obergrenzwert ein: ";
   cin >> upperbound;
   for (int number = 2; number <= upperbound; ++number) {
      // Keine Primzahl, wenn es einen Faktor zwischen 2 und sqrt(number) gibt
      int maxFactor = (int)sqrt(number);
      for (int factor = 2; factor <= maxFactor; ++factor) {
         if (number % factor == 0) {   // Faktor?
            cout << number << " ";
            break;   // Ein Faktor gefunden, keine weiteren Faktoren suchen
         }
      }
   }
   cout << endl;
   return 0;
}

Ausgabe:

Geben Sie den Obergrenzwert ein: 20
4 6 8 9 10 12 14 15 16 18 20
image desc

Schreiben wir das obige Programm um, um alle Primzahlen aufzulisten. Ein boolean-Flag namens isPrime wird verwendet, um anzuzeigen, ob die aktuelle number eine Primzahl ist. Es wird dann verwendet, um das Drucken zu steuern.

/*
 *  Liste Primzahlen von 1 bis zu einem Obergrenzwert.
 */
#include <iostream>
#include <cmath>
using namespace std;

int main() {
   int upperbound;
   cout << "Geben Sie den Obergrenzwert ein: ";
   cin >> upperbound;
   for (int number = 2; number <= upperbound; ++number) {
      // Keine Primzahl, wenn es einen Faktor zwischen 2 und sqrt(number) gibt
      int maxFactor = (int)sqrt(number);
      bool isPrime = true;  // boolean-Flag, um anzuzeigen, ob number eine Primzahl ist
      for (int factor = 2; factor <= maxFactor; ++factor) {
         if (number % factor == 0) {   // Faktor?
            isPrime = false;   // number ist keine Primzahl
            break;   // Ein Faktor gefunden, keine weiteren Faktoren suchen
         }
      }
      if (isPrime) cout << number << " ";
   }
   cout << endl;
   return 0;
}

Ausgabe:

Geben Sie den Obergrenzwert ein: 100
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
image desc

Untersuchen Sie das folgende Programm, das break und continue verwendet.

/* Eine mysteriöse Reihe */
#include <iostream>
using namespace std;

int main() {
   int number = 1;
   while (true) {
      ++number;
      if ((number % 3) == 0) continue;
      if (number == 53) break;
      if ((number % 2) == 0) {
         number += 3;
      } else {
         number -= 3;
      }
      cout << number << " ";
   }
   cout << endl;
   return 0;
}

Ausgabe:

5 4 2 7 11 10 8 13 17 16 14 19 23 22 20 25 29 28 26 31 35 34 32 37 41 40 38 43 47 46 44 49 53 52
image desc

Beenden des Programms

Es gibt mehrere Möglichkeiten, wie Sie Ihr Programm beenden können, bevor Sie das Ende der Programmanweisungen erreichen.

exit(): Sie können die Funktion exit(int exitCode) aufrufen, in <cstdlib> (portiert aus C's "stdlib.h"), um das Programm zu beenden und die Kontrolle an das Betriebssystem zurückzugeben. Konventionell gibt ein Rückgabecode von Null an eine normale Beendigung an; während ein nicht-nulles exitCode (-1) eine ungewöhnliche Beendigung anzeigt. Beispielsweise:

abort(): Der Header <cstdlib> bietet auch eine Funktion namens abort(), die verwendet werden kann, um das Programm ungewöhnlich zu beenden.

if (errorCount > 10) {
   cout << "zu viele Fehler" << endl;
   exit(-1);  // Beende das Programm
              // ODER abort();
}

Geschachtelte Schleifen

Das folgende Diagramm veranschaulicht eine geschachtelte for-Schleife, d.h., eine innere for-Schleife innerhalb einer äußeren for-Schleife.

image desc
/*
 *  Drucke das Dreiecksmuster.
 */
#include <iostream>
using namespace std;

int main() {
   int size = 8;
   for (int row = 1; row <= size; ++row) {     // Äußere Schleife, um alle Zeilen zu drucken
      for (int col = 1; col <= size-row+1; ++col) {  // Innere Schleife, um alle Spalten jeder Zeile zu drucken
         cout << "## ";
      }
      cout << endl;   // Eine Zeile ist beendet, bringe den Cursor zur nächsten Zeile
   }

   return 0;
}

Ausgabe:

## ## ## ## ## ## ## #
## ## ## ## ## ## #
## ## ## ## ## #
## ## ## ## #
## ## ## #
## ## #
## #
#
image desc

Das folgende Konstrukt wird häufig verwendet:

while (true) { ...... }

Es scheint eine endlose Schleife (oder unendliche Schleife) zu sein, wird aber normalerweise über eine break- oder return-Anweisung innerhalb des Schleifenkörpers beendet. Dieser Art von Code ist schwer zu lesen - vermeiden Sie es, wenn möglich, indem Sie die Bedingung umschreiben.

Zusammenfassung

Wir haben in diesem Abschnitt drei Steuerstrukturen eingeführt. Sie sind sehr nützlich. Sie können sie miteinander kombinieren. Seien Sie bei der Schleife vorsichtig und überprüfen Sie die Endbedingung, um eine endlose Schleife zu vermeiden.