ios_base :: sync_with_stdio(false);の意味 cin.tie(NULL);


145

含めることの意味は何ですか

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

C ++プログラムでは?

私のテストでは実行時間が短縮されましたが、これを含めることで心配する必要があるテストケースはありますか?

2つのステートメントは常に一緒にする必要がありcin.tie(NULL)ますか、それとも最初のステートメントで十分ですか、つまり無視しますか?

また、CおよびC ++コマンドを同時に使用することは、その値が設定されている場合に許可されfalseますか?

https://www.codechef.com/viewsolution/7316085

上記のコードはscanf/printf、値がのC ++プログラムで使用するまでは問題なく機能しましたtrue。この場合、セグメンテーション違反が発生しました。これについて考えられる説明は何でしょうか?


実際にfalseで使用しました。あなたのコードはそう言う???
スラジュジャイン2017

回答:


231

2つの呼び出しの意味は異なりますが、パフォーマンスとは関係ありません。実行時間を短縮するという事実は、副作用です(あるいはそうかもしれません)。それらは最適化のように見えるので、それぞれの機能を理解し、盲目的にそれらをすべてのプログラムに含める必要はありません。

ios_base::sync_with_stdio(false);

これにより、CおよびC ++標準ストリーム間の同期が無効になります。デフォルトでは、すべての標準ストリームが同期されます。これにより、実際には、CスタイルとC ++スタイルのI / Oを混在させ、適切で期待どおりの結果を得ることができます。同期を無効にすると、C ++ストリームは独自の独立したバッファーを持つことができるため、CとC ++スタイルのI / Oを混在させることができます。

また、同期されたC ++ストリームはスレッドセーフです(異なるスレッドからの出力はインターリーブされる可能性がありますが、データの競合は発生しません)。

cin.tie(NULL);

これcincoutます。タイドストリームは、1つのストリームが他のストリームの各I / O操作の前に自動的にフラッシュされることを保証します。

デフォルトでcincout、ユーザーが適切に操作できるように関連付けられています。例えば:

std::cout << "Enter name:";
std::cin >> name;

cincoutが関連付けられている場合、プログラムがユーザーからの入力を要求する前に、出力がフラッシュされる(つまり、コンソールに表示される)ことが期待できます。ストリームの結合を解除すると、プログラムはユーザーが名前を入力するのを待つのをブロックする可能性がありますが、「名前を入力してください」というメッセージはまだ表示されていません(coutされデフォルトでバッファされる、出力はオンデマンドでのみ、またはバッファがいっぱいです)。

したがって、cinから解放する場合はcout、でcout入力を期待する前に、何かを表示するたびに手動でフラッシュする必要がありますcin

結論として、それらのそれぞれが何を知って、結果を理解し、次にあなたが本当にしたいか、必要かどうかを判断可能な速度向上の副作用を。


「cinへの入力を予期する前に何かを表示するたびに、coutを手動でフラッシュする必要があります」と言う場合、「... << std :: flush」または「... < <std :: endl "から" std :: cout << ... "で始まるすべての行の終わりまでですよね?
アラン

4
はい、それはそれと同じくらい簡単ですが、「すべての行の終わり」の部分に注意してください。coutが理由でバッファリングされているため、あまりに頻繁にフラッシュすると、実際にそれを必要としないときに、パフォーマンスが低下する場合があります。
Ionut

@Ionut Cのscanf、printfのtie()機能に相当するものはありますか?
iajnr

1
@iajnrいいえ、直接ではありません。Cでは、前scanf()に手動でフラッシュするか、バッファリングを完全に無効にするか、行バッファリングに切り替えることができます(改行後または入力が読み取られたときにフラッシュする必要があります-linux.die.net/man/3/setlinebufをstdin参照)。
Ionut

1
leetcodeでは、ランタイムが大幅に改善されます。これらの競合するWebサイトは、入力テストに対して特別なことをするかもしれません。
P0W

17

これは、CおよびC ++の世界からIOを同期するためのものです。同期すると、すべてのIOの順序が期待どおりであることを保証できます。一般に、問題は、問題を引き起こすIOのバッファリングであり、同期すると、両方の世界で同じバッファーを共有できます。例えばcout << "Hello"; printf("World"); cout << "Ciao";; 同期がなければ、HelloCiaoWorldor HelloWorldCiaoまたはorを取得するかどうかは決してわかりませんWorldHelloCiao...

tieC ++ワールドのIOチャネルが相互に関連付けられていることを保証できます。これは、たとえば、入力が発生する前にすべての出力がフラッシュされていることを意味します(約cout << "What's your name ?"; cin >> name;)。

CまたはC ++ IOはいつでも混在させることができますが、妥当な動作が必要な場合は、両方の環境を同期させる必要があります。Cでプログラムする場合はC stdioを使用し、C ++でプログラムする場合はストリームを使用する場合、一般にこれらを混在させることはお勧めしません。ただし、既存のCライブラリをC ++コードに混在させることもできます。その場合は、両方を同期する必要があります。


3
同期化がなくても、への異なる呼び出しはcout <<順序を変更できないCiaoHelloWorldため、例のケースでは不可能です。同期化は、厳密にはさまざまなバッファリング方法に関するものです。
ミッコランタライネン、

3

およびストリームios_base::sync_with_stdio(false);を分離するにはC、を使用するだけで十分C++です。これについての議論は、Standard C ++ IOStreams and Localesにあります。LangerとKreftによる。彼らはこれがどのように機能するかは実装定義であると述べています。

cin.tie(NULL)呼び出しは、上の活動の間にデカップリングを要求しているようだcincout。他の最適化でこれを使用するとクラッシュが発生する理由を説明できません。述べたように、あなたが提供したリンクは悪いので、ここでは推測はありません。


0

シンを作るための一般的なものです入力をより高速に動作さ。

簡単に説明すると、最初の行では、cinストリームとCスタイルのstdioツール(scanfやgetなど)の間のバッファー同期がオフになっているため、cinはより高速に動作しますがstdioツールと同時に使用することはできません。

二行目のuntiesはCINからCOUT -デフォルトではcoutのバッファを使用すると、から何か読みたびにフラッシュCINを。そして、小さなものを繰り返し読んだ後、小さなものを何度も書くと、遅くなるかもしれません。したがって、この行はこの同期をオフにします(文字列cincoutではなくnullに結び付けることによって)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.