Heim > Backend-Entwicklung > C#.Net-Tutorial > Detaillierte Erläuterung der Auswirkungen der C++-Sprunganweisung Goto auf die Variablendefinition

Detaillierte Erläuterung der Auswirkungen der C++-Sprunganweisung Goto auf die Variablendefinition

黄舟
Freigeben: 2016-12-14 17:15:30
Original
1726 Leute haben es durchsucht

Vorwort

Die goto-Anweisung wird auch als unbedingte Übertragungsanweisung bezeichnet. Ihre Grundform ist wie folgt:

Die Anweisungsbezeichnung besteht aus einem gültigen Bezeichner und dem Symbol „; ", wobei die Benennungsregeln für Bezeichner dieselben sind wie für Variablennamen, d. h. sie bestehen aus Buchstaben, Zahlen und Unterstrichen, und das erste Zeichen muss ein Buchstabe oder Unterstrich sein. Nach der Ausführung der goto-Anweisung springt das Programm zur Anweisungsbezeichnung und führt die nachfolgenden Anweisungen aus.

Normalerweise werden goto-Anweisungen in Verbindung mit if-Bedingungsanweisungen verwendet. Obwohl die goto-Anweisung dem Programm Flexibilität verleiht, macht sie die Programmstruktur jedoch auch unklar und schwer lesbar, sodass sie verwendet werden muss rational diese Aussage.

Problem gefunden

Wir stoßen oft auf das Problem, Variablen nach goto zu definieren, aber die Kompilierung unter Linux gelingt nicht (Fehlermeldung: Crosses initialization). von). Eigentlich muss man einfach aufpassen. Nachdem ich heute die Vorgesetzten im Unternehmen gefragt habe, habe ich mir auch einige Informationen angesehen und sie aufgezeichnet, um mein Gedächtnis zu vertiefen. Ich hoffe, dass sie einigen Menschen helfen können.

Fehlerbeispielcode:

#include <iostream>
using namespace std;
  
int main()
{
 goto Exit;
 int a = 0;
Exit:
 return 0;
}
Nach dem Login kopieren

Fehlerbericht:

[root@localhost c-c++]# g++ goto_study.cpp 
goto_study.cpp: In function &#39;int main()&#39;:
goto_study.cpp:31: error: jump to label &#39;Exit&#39;
goto_study.cpp:29: error: from here
goto_study.cpp:30: error: crosses initialization of &#39;int a&#39;
Nach dem Login kopieren

Korrekt Man kann nicht sagen, dass das Schreiben

die richtige Schreibweise ist, man kann nur sagen, dass es die Schreibweise ist, die in Ordnung ist.

Geben Sie den Code direkt ein:

Schreibmethode eins:

Ändern Sie die Domäne und werden Sie eine lokale Variable:

int main()
{
 goto Exit;
 {
 int a = 0;
 }
Exit:
 return 0;
}
Nach dem Login kopieren

Schreibmethode zwei

Magische Schreibmethode:

int main()
{
 goto Exit;
 int a;
 a = 1;
Exit:
 cout << "a = " << a << endl;
 return 0;
}
Nach dem Login kopieren

Der Schlüssel ist, dass Sie immer noch darauf zugreifen können ! Ergebnis:

[root@localhost c-c++]# g++ goto_study.cpp 
[root@localhost c-c++]# ./a.out
a = 1259648
Nach dem Login kopieren

Forschung über die magische Schreibmethode von


Nachdem ich zwei Schreibmethoden gesehen habe, die sein können kompiliert und übergeben. Das Rätselhafteste ist, dass die zweite Methode kompiliert und verwendet werden kann und trotzdem verwendet werden kann? ? ?

C++-Vorschriften

Referenz [1][2] erwähnt die Vorschriften im C++-Standard: > Es ist möglich, in einen Block zu übertragen, aber nicht auf eine Weise, die Deklarationen mit Initialisierung umgeht. Ein Programm, das springt von einem Punkt, an dem keine lokale Variable mit automatischer Speicherdauer vorhanden ist Der Gültigkeitsbereich bis zu einem Punkt, an dem er sich im Gültigkeitsbereich befindet, ist falsch formatiert, es sei denn, die Variable verfügt über POD Typ (3.9) und wird ohne Initialisierer deklariert.

bedeutet: wenn der Ausführungspfad eines Programms von Punkt A im Code (eine lokale Variable x wurde nicht definiert) zu einem anderen Punkt B im Code springt (Die lokale Variable x wurde definiert und beim Definieren initialisiert), dann meldet der Compiler einen Fehler. Ein solcher Sprung kann durch die Ausführung einer goto-Anweisung oder eines Switch-Case verursacht werden. Daher ist a bei der zweiten Schreibweise vom Typ int, einem POD-Typ, und wurde nicht initialisiert, sodass die Kompilierung erfolgreich ist. Es ist jedoch offensichtlich: Wenn Sie diese Variable a verwenden, ist das Ergebnis unbekannt. Wie der Vorgänger sagte, ist es bedeutungslos, es ist besser, es nicht zu unterstützen! Wenn es nur lokal verwendet wird, kann es in geschweifte Klammern eingeschlossen werden! Einige Leute im Internet sagten auch, dass die C++-Spezifikation zwar nicht explizit feststellt, dass dies falsch ist, die Bestimmungen der Variablendomäne jedoch implizit sagen, dass dieser Ansatz nicht ratsam ist, siehe Referenz [4].

Implizite Beschreibung

Goto kann Definitionen von Variablen nicht überspringen, da diese Variablen dies tun würden existiert nach dem Sprung nicht mehr, da die Lebensdauer der Variablen an der Stelle von beginnt Definition scheint goto nicht explizit zu erwähnen Tun Sie das, aber es ist in dem, was über die Lebensdauer von Variablen gesagt wird, impliziert. Ja, Sie können dieses Flag des Compilers so setzen, dass es in eine Warnung umgewandelt wird, aber das wird nicht praktiziert! ! !

Nach der Überprüfung der Informationen besteht die Funktion der fpermissive-Markierung darin, den Syntaxfehler des Codes als Warnung zu verwenden und den Kompilierungsprozess fortzusetzen. Denken Sie also aus Sicherheitsgründen nicht darüber nach Winkel, kodiere es einfach ehrlich!


POD-Typ

Referenz [3]: Gemäß den oben genannten C++-Vorschriften kann er kompiliert und übergeben werden, solange es sich um einen POD-Typ handelt und keine Initialisierung erfolgt.

Schauen Sie sich einen Code an:


Ergebnis:

#include <iostream>
using namespace std;
class A{
public:
 // 注意:和B不同的是有构造和析构函数, 所以编译报错
 A(){}
 ~A(){}
 void testA(){
 cout << "A::test." << endl;
 }
};
class B{
public:
 void testB(){
 cout << "B::test." << endl;
 }
};
int main()
{
 goto Exit;
 // int a = 1; // windows ok.linux failed!
 //A classA; // failed:
 B classB; // success:
 classB.testB();
Exit:
 classB.testB();
 return 0;
}
Nach dem Login kopieren

Zusammenfassung:

1. Der obige Code wird sowohl unter Windows als auch unter Linux kompiliert und ausgeführt
[root@localhost c-c++]# g++ goto_study.cpp 
[root@localhost c-c++]# ./a.out
a = 1259648
B::test.
Nach dem Login kopieren

2. Der Satz A classA kann sowohl unter Windows als auch unter Linux nicht kompiliert werden! Da A über einen Konstruktor und einen Destruktor verfügt, erfüllt es die Bedingungen nicht Windows (msvc). Bitte erklären Sie! ! !

Das Folgende sind POD-Typen (lesen wir auf Englisch):

1. int, char, wchar_t, bool, float, double sind POD-Typen, diese Typen sind lang/kurz Und Dasselbe gilt für signierte/unsignierte Versionen;


2. Zeiger (einschließlich Funktionszeiger und Mitgliedszeiger) sind alle POD-Typen


3. Aufzählungstypen;

4. Die konstanten und gewöhnlichen Variablen von POD sind ebenfalls gleich.

5. Das Gleiche gilt für die POD-Typen class, struct und union. Alle Mitglieder müssen jedoch öffentlich sein, und es gibt keine Basisklasse, keinen Konstruktor, Destruktor und keine virtuelle Funktion. Auch statische Mitglieder unterliegen diesen Regeln.

Zusammenfassung

1. Es ist am besten, goto nicht zu verwenden;

2. Überspringen Sie nicht die Definition und Initialisierung von Variablen nach goto. Wenn es sich um einen POD-Typ handelt, können Sie ihn zuerst deklarieren und dann definieren. Es wird kein Kompilierungsfehler gemeldet. Es wird jedoch nicht empfohlen, es auf diese Weise zu verwenden. Sie können sehen, dass der Wert der Variablen unbekannt und gefährlich ist. 3. Wenn danach eine lokale Variable vorhanden ist goto, Sie können geschweifte Klammern verwenden. Es ist sicher, es einzuschließen, um eine lokale Domäne zu bilden.

Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels jedem beim Lernen oder Arbeiten helfen kann. Wenn Sie Fragen haben, können Sie eine Nachricht hinterlassen.


Weitere verwandte Artikel finden Sie auf der chinesischen PHP-Website (www.php.cn)!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage