Bedeutung von ios_base::sync_with_stdio(false); cin.tie(NULL);

Lesezeit: 3 Minuten

Bedeutung von ios basesync with stdiofalse cintieNULL
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?

  • Sie haben das tatsächlich mit false verwendet. Dein Code sagt das???

    – Suraj Jain

    7. Februar 2017 um 18:22 Uhr

Bedeutung von ios basesync with stdiofalse cintieNULL
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 coutmü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.

  • Wenn Sie sagen “Sie müssen sicherstellen, dass Sie cout jedes Mal manuell leeren, wenn Sie etwas anzeigen möchten, bevor Sie eine Eingabe auf cin erwarten”, kann das so einfach sein wie das Anhängen von “… << std::flush" oder "... < < std::endl" bis zum Ende jeder Zeile, die mit "std::cout << ..." beginnt, richtig?

    – Alan

    15. Juni 2018 um 22:20 Uhr

  • Ja, so einfach ist das, aber seien Sie vorsichtig mit dem Teil “am Ende jeder Zeile”. cout wird aus einem bestimmten Grund gepuffert, wenn Sie es zu oft leeren, wenn Sie es nicht wirklich brauchen, sehen Sie möglicherweise einen Leistungseinbruch.

    – Ionut

    16. Juni 2018 um 7:48 Uhr

  • @Ionut gibt es etwas, das der tie () -Funktionalität in C für scanf, printf entspricht?

    – iajnr

    18. Juli 2018 um 13:47 Uhr

  • @iajnr Nein, nicht direkt. In C können Sie entweder vorher manuell spülen scanf()deaktivieren Sie die Pufferung vollständig oder wechseln Sie zur Zeilenpufferung (die nach dem Zeilenumbruch oder beim Lesen von Eingaben geleert werden sollte stdin – sehen linux.die.net/man/3/setlinebuf ).

    – Ionut

    18. Juli 2018 um 13:59 Uhr

  • Bei leetcode verbessert es die Laufzeit erheblich, vielleicht machen diese konkurrierenden Websites etwas Besonderes für Eingabetests.

    – P0W

    25. Dezember 2019 um 10:05 Uhr

1646920208 289 Bedeutung von ios basesync with stdiofalse cintieNULL
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.

  • Auch ohne Synchronisation können unterschiedliche Aufrufe erfolgen cout << kann die Reihenfolge also nicht ändern CiaoHelloWorld ist für Ihren Beispielfall nicht möglich. Bei der Synchronisierung geht es ausschließlich um verschiedene Puffermethoden.

    – Mikko Rantalainen

    7. Oktober 2019 um 18:33 Uhr

  • Ich weiß nicht einmal, ob es wahr ist, aber ich habe wegen der Erklärung positiv gestimmt

    – Davud Safarov

    25. September 2020 um 18:17 Uhr

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.

1646920209 290 Bedeutung von ios basesync with stdiofalse cintieNULL
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.

988130cookie-checkBedeutung von ios_base::sync_with_stdio(false); cin.tie(NULL);

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy