
Kshitij Kohli
Welche Bedeutung hat das Einschließen
ios_base::sync_with_stdio(false);
cin.tie(NULL);
in C++-Programmen?
In meinen Tests beschleunigt es die Ausführungszeit, aber gibt es einen Testfall, um den ich mir Sorgen machen sollte, wenn ich diesen einbeziehe?
Müssen die 2 Aussagen immer zusammen stehen, oder reicht die erste aus, dh ignorieren cin.tie(NULL)
?
Außerdem ist es zulässig, C- und C++-Befehle gleichzeitig zu verwenden, wenn der Wert auf gesetzt wurde false
?
https://www.codechef.com/viewsolution/7316085
Der obige Code hat gut funktioniert, bis ich ihn verwendet habe scanf/printf
in einem C++-Programm mit dem Wert as true
. In diesem Fall gab es einen Segmentierungsfehler. Was könnte die mögliche Erklärung dafür sein?

Ionut
Die beiden Aufrufe haben unterschiedliche Bedeutungen, die nichts mit Leistung zu tun haben; die Tatsache, dass es beschleunigt die Ausführungszeit ist oder könnte sein) nur ein Nebeneffekt. Sie sollten verstehen, was jeder von ihnen tut, und sie nicht blind in jedes Programm aufnehmen, weil sie wie eine Optimierung aussehen.
ios_base::sync_with_stdio(false);
Dadurch wird die Synchronisierung zwischen den C- und C++-Standardstreams deaktiviert. Standardmäßig werden alle Standardstreams synchronisiert, was es Ihnen in der Praxis ermöglicht, E/A im C- und C++-Stil zu mischen und vernünftige und erwartete Ergebnisse zu erzielen. Wenn Sie die Synchronisation deaktivieren, dürfen C++-Streams ihre eigenen unabhängigen Puffer haben, was das Mischen von I/O im C- und C++-Stil zu einem Abenteuer macht.
Denken Sie auch daran, dass synchronisierte C++-Streams Thread-sicher sind (Ausgaben von verschiedenen Threads können sich verschachteln, aber Sie erhalten keine Datenrennen).
cin.tie(NULL);
Das löst cin
von cout
. Gebundene Streams stellen sicher, dass ein Stream automatisch vor jeder E/A-Operation auf dem anderen Stream geleert wird.
Standardmäßig cin
gebunden ist cout
um eine sinnvolle Benutzerinteraktion zu gewährleisten. Zum Beispiel:
std::cout << "Enter name:";
std::cin >> name;
Wenn cin
und cout
gebunden sind, können Sie davon ausgehen, dass die Ausgabe geleert (dh auf der Konsole sichtbar) wird, bevor das Programm den Benutzer zur Eingabe auffordert. Wenn Sie die Streams lösen, blockiert das Programm möglicherweise das Warten darauf, dass der Benutzer seinen Namen eingibt, aber die Meldung “Name eingeben” ist noch nicht sichtbar (weil cout
wird standardmäßig gepuffert, die Ausgabe wird nur bei Bedarf oder wenn der Puffer voll ist auf der Konsole geleert/angezeigt).
Also, wenn Sie sich lösen cin
von cout
müssen Sie unbedingt spülen cout
jedes Mal manuell, wenn Sie etwas anzeigen möchten, bevor Sie eine Eingabe erwarten cin
.
Abschließend wissen Sie, was jeder von ihnen tut, verstehen Sie die Konsequenzen und entscheiden Sie dann, ob Sie das wirklich wollen oder brauchen möglich Nebeneffekt der Geschwindigkeitsverbesserung.

Jean-Baptiste Yunes
Dies dient zum Synchronisieren von IOs aus der C- und C++-Welt. Wenn Sie synchronisieren, haben Sie die Garantie, dass die Bestellungen aller IOs genau Ihren Erwartungen entsprechen. Im Allgemeinen ist das Problem das Puffern von IOs, das das Problem verursacht. Durch die Synchronisierung können beide Welten dieselben Puffer gemeinsam nutzen. Zum Beispiel cout << "Hello"; printf("World"); cout << "Ciao";
; ohne Synchronisation werden Sie nie wissen, ob Sie es bekommen HelloCiaoWorld
oder HelloWorldCiao
oder WorldHelloCiao
…
tie
gibt Ihnen die Garantie, dass IOs-Kanäle in der C++-Welt sind gebunden miteinander, was zum Beispiel bedeutet, dass jeder Ausgang gespült wurde, bevor Eingaben erfolgen (denken Sie an cout << "What's your name ?"; cin >> name;
).
Sie können C- oder C++-IOs immer mischen, aber wenn Sie ein vernünftiges Verhalten wünschen, müssen Sie beide Welten synchronisieren. Beachten Sie, dass es im Allgemeinen nicht empfohlen wird, sie zu mischen, wenn Sie in C programmieren, verwenden Sie C stdio, und wenn Sie in C++ programmieren, verwenden Sie Streams. Möglicherweise möchten Sie jedoch vorhandene C-Bibliotheken in C++-Code mischen, und in einem solchen Fall müssen Sie beide synchronisieren.
Es ist nur übliches Zeug zum Herstellen cin Eingabe schneller arbeiten.
Zur schnellen Erklärung: Die erste Zeile schaltet die Puffersynchronisation zwischen den cin Stream und C-Stil Studio Tools (wie scanf oder gets) — so cin arbeitet schneller, aber Sie können es nicht gleichzeitig mit verwenden Studio Werkzeuge.
Die zweite Zeile löst sich cin von cout — standardmäßig die cout Puffer löscht jedes Mal, wenn Sie etwas lesen cin. Und das kann langsam sein, wenn Sie wiederholt etwas Kleines lesen und dann viele Male etwas Kleines schreiben. Die Leitung schaltet also diese Synchronisation aus (indem sie buchstäblich bindet cin zu Null anstatt cout).
Verwenden ios_base::sync_with_stdio(false);
reicht aus um die zu entkoppeln C
und C++
Ströme. Eine Diskussion dazu finden Sie in Standard C++ IOStreams and Locales von Langer und Kreft. Sie stellen fest, dass die Funktionsweise von der Implementierung bestimmt wird.
Die cin.tie(NULL)
Anruf scheint eine Entkopplung zwischen den Aktivitäten an zu verlangen cin
und cout
. Ich kann nicht erklären, warum die Verwendung dieser mit der anderen Optimierung einen Absturz verursachen sollte. Wie bereits erwähnt, ist der von Ihnen angegebene Link schlecht, daher hier keine Spekulationen.

Ashish Yadav
Es gibt viele tolle Antworten. Ich möchte nur eine kleine Anmerkung zur Entkopplung des Streams hinzufügen.
cin.tie(NULL);
Beim Entkoppeln des Streams mit der CodeChef-Plattform ist ein Problem aufgetreten. Als ich meinen Code übermittelte, lautete die Antwort der Plattform „Falsche Antwort“, aber nachdem ich den Stream eingebunden und die Übermittlung getestet hatte. Es funktionierte.
Wenn also jemand den Stream lösen möchte, muss der Ausgabestream geleert werden.
9881300cookie-checkBedeutung von ios_base::sync_with_stdio(false); cin.tie(NULL);yes
Sie haben das tatsächlich mit false verwendet. Dein Code sagt das???
– Suraj Jain
7. Februar 2017 um 18:22 Uhr