C++

Ausnahmebehandlung in C++

Ausnahmebehandlung in C++
Es gibt drei Arten von Softwarefehlern. Dies sind Syntaxfehler, Logikfehler und Laufzeitfehler.

Syntaxfehler

Ein falsch eingegebener Ausdruck, eine Anweisung oder Konstruktion ist ein Syntaxfehler a.

Betrachten Sie die folgenden zwei Aussagen:

int arr[] = 1, 2, 3; //richtig
int arr = 1, 2, 3; //Syntaxfehler, fehlt []

Sie sind Definitionen des gleichen Arrays. Das erste ist richtig. Beim zweiten fehlt [], und das ist ein Syntaxfehler. Ein Programm mit einem Syntaxfehler kann nicht kompiliert werden. Die Kompilierung schlägt mit einer Fehlermeldung fehl, die auf den Syntaxfehler hinweist. Gut ist, dass ein Syntaxfehler immer behoben werden kann, wenn der Programmierer weiß was er tut.

Logikfehler

Ein logischer Fehler ist ein Fehler, der vom Programmierer begangen wird, wenn eine falsche logische Codierung vorgenommen wird. Es kann das Ergebnis der Unkenntnis des Programmierers bezüglich der Funktionen der Programmiersprache oder eines Missverständnisses sein, was das Programm tun soll.

In dieser Situation ist das Programm erfolgreich kompiliert. Das Programm funktioniert gut, aber es liefert falsche Ergebnisse. Ein solcher Fehler kann daran liegen, dass eine Schleife 5-mal wiederholt wird, wenn sie 10-mal wiederholt wird. Es kann auch sein, dass eine Schleife unbewusst unendlich iteriert wird. Der einzige Weg, solche Fehler zu beheben, ist eine sorgfältige Programmierung und ein gründliches Testen des Programms vor der Übergabe an den Kunden.

Laufzeitfehler

Falsche oder außergewöhnliche Eingaben führen zu Laufzeitfehlern. In diesem Fall wurde das Programm erfolgreich kompiliert und funktioniert in vielen Situationen gut. In bestimmten Situationen stürzt das Programm ab (und stoppt).

Stellen Sie sich vor, dass in einem Programmcode-Segment 8 durch eine Anzahl von Nennern geteilt werden muss. Wenn also der Zähler 8 durch den Nenner 4 geteilt wird, wäre die Antwort (Quotient) 2. Wenn der Benutzer jedoch 0 als Nenner eingibt, stürzt das Programm ab. Die Division durch 0 ist in Mathematik nicht erlaubt und auch nicht im Rechnen. Division durch Null sollte bei der Programmierung verhindert werden. Ausnahmebehandlung behandelt Laufzeitfehler, wie Division durch Null. Das folgende Programm zeigt, wie das Division-durch-Null-Problem behandelt wird, ohne die Ausnahmefunktion in C++ zu verwenden:

#einschließen
Verwenden von Namespace-Std;
int main()

int-Zähler = 8;
int-Nenner = 2;
wenn (Nenner != 0 )

int Ergebnis = Zähler/Nenner;
cout << result << '\n';

sonst

cout << "Division by zero is not permitted!" << '\n';

0 zurückgeben;

Die Ausgabe ist 4. Wenn der Nenner 0 wäre, wäre die Ausgabe gewesen:

„Eine Division durch Null ist nicht erlaubt!”

Der Hauptcode hier ist ein if-else-Konstrukt. Wenn der Nenner nicht 0 ist, findet die Division statt; wenn es 0 ist, findet die Division nicht statt. Es wird eine Fehlermeldung an den Benutzer gesendet und das Programm läuft ohne Absturz weiter. Laufzeitfehler werden normalerweise behandelt, indem die Ausführung eines Codesegments vermieden und eine Fehlermeldung an den Benutzer gesendet wird.

Die Ausnahmefunktion in C++ verwendet einen try-Block für den if-Block und einen catch-Block für den else-Block, um den Fehler wie folgt zu behandeln:

#einschließen
Verwenden von Namespace-Std;
int main()

int-Zähler = 8;
int-Nenner = 2;
Versuchen

wenn (Nenner != 0 )

int Ergebnis = Zähler/Nenner;
cout << result << '\n';

sonst

werfen 0;


fangen (int err)

wenn (err == 0)
cout << "Division by zero is not permitted!" << '\n';

0 zurückgeben;

Beachten Sie, dass der try-Header kein Argument hat. Beachten Sie auch, dass der catch-Block, der wie eine Funktionsdefinition ist, einen Parameter hat. Der Parametertyp muss mit dem Operanden (Argument) des throw-Ausdrucks übereinstimmen. Der Throw-Ausdruck befindet sich im Try-Block. Es wirft ein Argument nach Wahl des Programmierers, das sich auf den Fehler bezieht, und der catch-Block fängt es ab. Auf diese Weise wird der Code im try-Block nicht ausgeführt. Dann zeigt der catch-Block die Fehlermeldung an.

Dieser Artikel erklärt die Ausnahmebehandlung in C++. Grundkenntnisse in C++ sind Voraussetzung, damit der Leser diesen Artikel verstehen kann.

Artikelinhalt:

  • Funktion, die eine Ausnahme auslöst
  • Mehr als ein Catch-Block für einen Try-Block
  • Verschachtelte Try/Catch-Blöcke
  • noException-Bezeichner
  • Die spezielle std::terminate() Funktion
  • Fazit

Funktion, die eine Ausnahme auslöst:

Eine Funktion kann auch eine Ausnahme auslösen, genau wie der Try-Block. Das Werfen erfolgt innerhalb der Definition der Funktion. Das folgende Programm veranschaulicht dies:

#einschließen
Verwenden von Namespace-Std;
void fn(const char* str)

if (islower(str[0]))
'l' werfen;

int main()

Versuchen

fn("Schmied");

fangen (char ch)

if (ch == 'l')
cout << "Person's name cannot begin in lowercase!" << '\n';

0 zurückgeben;

Beachten Sie, dass der try-Block diesmal nur den Funktionsaufruf enthält. Es ist die aufgerufene Funktion, die die Throw-Operation hat. Der catch-Block fängt die Ausnahme ab und die Ausgabe lautet:

„Der Name der Person darf nicht in Kleinbuchstaben beginnen!”

Diesmal ist der Typ, der geworfen und gefangen wird, ein Char.

Mehr als ein Catch-Block für einen Try-Block:

Es kann mehr als einen Catch-Block für einen Try-Block geben. Stellen Sie sich die Situation vor, in der eine Eingabe ein beliebiges Zeichen der Tastatur sein kann, aber keine Ziffer und kein Alphabet. In diesem Fall muss es zwei catch-Blöcke geben: einen für einen Integer, um die Ziffer zu überprüfen, und einen für ein Zeichen, um das Alphabet zu überprüfen. Der folgende Code veranschaulicht dies:

#einschließen
Verwenden von Namespace-Std;
Zeicheneingabe = '*';
int main()

Versuchen

if (isziffer(eingabe))
10 werfen;
if (Isalpha(Eingabe))
'z' werfen;

fangen (int)

cout << "Digit input is forbidden!" << '\n';

fangen (char)

cout << "Character input is forbidden!" << '\n';

0 zurückgeben;

Es gibt keine Ausgabe. Wenn der Eingabewert eine Ziffer wäre, e.G., '1', die Ausgabe wäre gewesen:

"Zifferneingabe ist verboten!"

Wenn der Eingabewert ein Alphabet wäre, z.G., 'a', die Ausgabe wäre gewesen:

"Zeicheneingabe ist verboten!"

Beachten Sie, dass es in der Parameterliste der beiden Catch-Blöcke keinen Bezeichnernamen gibt. Beachten Sie auch, dass in der Definition der beiden Catch-Blöcke die einzelnen geworfenen Argumente nicht überprüft wurden, ob ihre Werte genau sind oder nicht.

Was für einen Fang zählt, ist die Art; ein catch muss dem Typ des geworfenen Operanden entsprechen. Der jeweilige Wert des geworfenen Arguments (Operanden) kann bei Bedarf zur weiteren Überprüfung verwendet werden.

Mehr als ein Handler für denselben Typ

Es ist möglich, zwei Handler des gleichen Typs zu haben. Wenn eine Ausnahme ausgelöst wird, wird die Kontrolle an den nächsten Handler mit einem passenden Typ übergeben. Das folgende Programm veranschaulicht dies:

#einschließen
Verwenden von Namespace-Std;
Zeicheneingabe = '1';
int main()

Versuchen

if (isziffer(eingabe))
10 werfen;

fangen (int)

cout << "Digit input is forbidden!" << '\n';

fangen (int)

cout << "Not allowed at all: digit input!" << '\n';

0 zurückgeben;

Die Ausgabe ist:

"Zifferneingabe ist verboten!"

Verschachtelte try/catch-Blöcke:

try/catch-Blöcke können verschachtelt werden. Das obige Programm zur Eingabe von nicht-alphanumerischen Zeichen über die Tastatur wird hier wiederholt, jedoch mit dem alphabetischen Fehlercode verschachtelt:

#einschließen
Verwenden von Namespace-Std;
Zeicheneingabe = '*';
int main()

Versuchen

if (isziffer(eingabe))
10 werfen;
Versuchen

if (Isalpha(Eingabe))
'z' werfen;

fangen (char)

cout << "Character input is forbidden!" << '\n';


fangen (int)

cout << "Digit input is forbidden!" << '\n';

0 zurückgeben;

Der Fehler alphabetischer Try/Catch-Block ist im Try-Block des Zifferncodes verschachtelt. Die Funktionsweise dieses Programms und die vorherige Operation, aus der es kopiert wurde, sind gleich.

noException-Bezeichner

Betrachten Sie die folgende Funktion:

void fn(const char* str) noexcept

if (islower(str[0]))
'l' werfen;

Beachten Sie den Bezeichner 'noexcept' direkt nach der rechten Klammer der Funktionsparameterliste. Das bedeutet, dass die Funktion keine Ausnahme auslösen sollte. Wenn die Funktion eine Ausnahme auslöst, wie in diesem Fall, wird sie mit einer Warnmeldung kompiliert, aber nicht ausgeführt. Ein Versuch, das Programm auszuführen, ruft die spezielle Funktion std::terminate() auf, die das Programm ordnungsgemäß anhalten sollte, anstatt es buchstäblich abzustürzen.

Der Bezeichner noexcept liegt in verschiedenen Formen vor. Diese sind wie folgt:

Typ func() noaußer; : erlaubt keinen Throw-Ausdruck
Typ func() noexcept(true); : erlaubt einen Wurfausdruck
Typ func() throw(); : erlaubt keinen Throw-Ausdruck
Typ func() noexcept(false); : erlaubt einen Throw-Ausdruck, der optional ist
Typ func(); : erlaubt einen Throw-Ausdruck, der optional ist

true oder false in Klammern kann durch einen Ausdruck ersetzt werden, der zu true oder false führt.

Die spezielle std::terminate()-Funktion:

Wenn eine Ausnahme nicht behandelt werden kann, sollte sie erneut ausgelöst werden. In diesem Fall kann der geworfene Ausdruck einen Operanden haben oder nicht. Zur Laufzeit wird die spezielle Funktion std::terminate() aufgerufen, die das Programm anständig anhalten sollte, anstatt es buchstäblich abstürzen zu lassen.

Geben Sie das folgende Programm ein, kompilieren Sie es und führen Sie es aus:

#einschließen
Verwenden von Namespace-Std;
Zeicheneingabe = '1';
int main()

Versuchen

if (isziffer(eingabe))
10 werfen;

fangen (int)

werfen;

0 zurückgeben;

Nach einer erfolgreichen Kompilierung wurde das Programm ohne Ausführung beendet und die Fehlermeldung vom Computer des Autors lautet:

"terminate wird aufgerufen, nachdem eine Instanz von 'int' geworfen wurde

Abgebrochen (Core Dumped)“

Fazit:

Die Ausnahmefunktion in C++ verhindert die Ausführung eines Codesegments basierend auf einer Art von Eingabe. Das Programm wird bei Bedarf weiter ausgeführt. Das Ausnahmekonstrukt (Fehlervermeidung) besteht aus einem Try-Block und einem Catch-Block. Der try-Block enthält das interessierende Codesegment, das je nach Eingabebedingung umgangen werden kann. Der try-Block hat den Throw-Ausdruck, der einen Operanden wirft. Dieser Operand wird auch als Ausnahme bezeichnet. Wenn der Operandentyp und der Typ für den Parameter des Catch-Blocks gleich sind, wird die Ausnahme abgefangen (behandelt). Wenn die Ausnahme nicht abgefangen wird, wird das Programm beendet, aber seien Sie trotzdem auf der sicheren Seite, da das Codesegment, das das falsche Ergebnis liefern sollte, nicht ausgeführt wurde. Eine typische Ausnahmebehandlung bedeutet das Umgehen des Codesegments und das Senden einer Fehlermeldung an den Benutzer. Das Codesegment wird bei normaler Eingabe ausgeführt, aber bei falschen Eingaben umgangen.

So ändern Sie die Maus- und Touchpad-Einstellungen mit Xinput in Linux
Die meisten Linux-Distributionen werden standardmäßig mit der Bibliothek „libinput“ ausgeliefert, um Eingabeereignisse auf einem System zu verarbeiten...
Weisen Sie Ihre Maustasten mit der X-Mouse Button Control für verschiedene Software unterschiedlich zu
Vielleicht benötigen Sie ein Tool, mit dem sich die Steuerung Ihrer Maus bei jeder von Ihnen verwendeten Anwendung ändern kann. In diesem Fall können ...
Microsoft Sculpt Touch Wireless-Maus Bewertung
Ich habe vor kurzem gelesen, dass Microsoft Sculpt Touch kabellose Maus und beschloss, sie zu kaufen. Nachdem ich es eine Weile benutzt hatte, beschlo...