ios_base :: sync_with_stdio的意义(假); cin.tie(NULL);

时间:2015-07-01 13:12:21

标签: c++ c

包含

的意义何在?
ios_base::sync_with_stdio(false);
cin.tie(NULL);

在C ++程序中?

在我的测试中,它加快了执行时间,但有一个测试用例,我应该担心包含这个吗?

这两个陈述是否必须在一起,或者第一个是否足够,即忽略cin.tie(NULL)

此外,如果其值已设置为false,是否可以同时使用C和C ++命令?

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

上面的代码运行正常,直到我在C ++程序中使用scanf/printf,其值为true。在这种情况下,它给出了分段错误。可能的解释是什么?

5 个答案:

答案 0 :(得分:144)

这两个电话具有与表现无关的不同含义; 它加快执行时间的事实是(或可能)只是副作用。你应该明白他们每个人做了什么,而不是盲目地将它们包含在每个程序中,因为它们看起来像是一种优化。

C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin

这将禁用C和C ++标准流之间的同步。默认情况下,所有标准流都是同步的,这实际上允许您混合使用C和C ++样式的I / O并获得合理的预期结果。如果禁用同步,则允许C ++流拥有自己的独立缓冲区,这使得混合C和C ++风格的I / O成为冒险。

还要记住,同步C ++流是线程安全的(不同线程的输出可能会交错,但是你没有数据争用)。

ios_base::sync_with_stdio(false);

cin.tie(NULL); 解开cin。绑定的流确保在另一个流上的每个I / O操作之前自动刷新一个流。

默认情况下,coutcin绑定,以确保合理的用户互动。例如:

cout

如果绑定std::cout << "Enter name:"; std::cin >> name; cin,则可以在程序提示用户输入之前刷新输出(即在控制台上可见)。如果解开流,程序可能会阻止等待用户输入其名称,但“输入名称”消息尚未显示(因为cout默认是缓冲的,输出仅在控制台上刷新/显示按需或缓冲区已满时。

因此,如果您从cout解开cin,则必须确保每次想要显示某些内容时手动刷新cout,然后才能在cout上进行输入。

总之,了解他们每个人做了什么,了解后果,然后决定你是否真的想要或需要可能的速度提升的副作用。

答案 1 :(得分:8)

这是为了同步来自C和C ++世界的IO。如果您进行同步,那么您可以保证所有IO的订单正是您所期望的。一般来说,问题是导致问题的IO的缓冲,同步让两个世界共享相同的缓冲区。例如cout << "Hello"; printf("World"); cout << "Ciao";;如果没有同步,您永远不会知道您是否会HelloCiaoWorldHelloWorldCiaoCiaoHelloWorld ...

tie让您保证C ++世界中的IO通道彼此绑定,这意味着例如在输入发生之前已刷新每个输出(想想{ {1}})。

您可以随时混合C或C ++ IO,但如果您想要一些合理的行为,则必须同步两个世界。请注意,一般不建议将它们混合使用,如果使用C编程使用C stdio,并且使用C ++编程使用流。但是您可能希望将现有的C库混合到C ++代码中,在这种情况下需要同步它们。

答案 2 :(得分:2)

使用ios_base::sync_with_stdio(false);足以解除CC++个流。你可以在Standard C++ IOStreams and Locales中通过Langer和Kreft找到对此的讨论。他们注意到这是如何工作的是实现定义。

cin.tie(NULL)来电似乎要求cincout上的活动脱钩。我无法解释为什么在其他优化中使用它会导致崩溃。如上所述,您提供的链接很糟糕,所以没有猜测。

答案 3 :(得分:2)

这是使 cin 输入工作更快的常见内容。

为便于快速解释:第一行关闭了 cin 流和C风格的 stdio 工具(如scanf或gets)之间的缓冲区同步-所以 cin 的运行速度更快,但您不能与 stdio 工具同时使用它。

第二行从 cout 断开 cin 的链接-默认情况下,每次您从 cin < / strong>。当您反复读一些小文章然后多次写一些小文章时,这可能会很慢。因此,该行关闭了此同步(通过将 cin 绑定为 null 而不是 cout )。

答案 4 :(得分:1)

很多答案。我只想添加关于解流的小注释。

cin.tie(NULL);

在使用 CodeChef 平台解耦流时,我遇到了一个问题。当我提交我的代码时,平台响应是“错误答案”,但在绑定流并测试了提交之后。它起作用了。

因此,如果有人想取消流的束缚,则必须刷新输出流。

编辑:我对所有平台都不熟悉,但这就是我的经验。