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


146

포함의 의미는 무엇입니까

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

C ++ 프로그램에서?

내 테스트에서 실행 시간이 빨라지지만 이것을 포함하여 걱정해야 할 테스트 사례가 있습니까?

2 개의 진술은 항상 함께 있어야합니까, 아니면 첫 번째로 충분 cin.tie(NULL)합니까 , 즉 무시 하는가?

또한 값이 false? 로 설정된 경우 C 및 C ++ 명령을 동시에 사용할 수 있습니까?

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

위의 코드는 scanf/printfC ++ 프로그램에서 값을로 사용할 때까지 정상적으로 작동했습니다 true. 이 경우 분할 오류가 발생했습니다. 이에 대한 가능한 설명은 무엇입니까?


실제로는 false로 사용했습니다. 귀하의 코드는 그렇게 말합니까 ???
Suraj Jain

답변:


231

두 통화는 성능과 관련이없는 다른 의미를 갖습니다. 사실 은 실행 시간을 속도는 (또는 수 있습니다 단지 부작용). 각각의 기능을 이해하고 최적화 된 것처럼 보이기 때문에 모든 프로그램에 맹목적으로 포함해서는 안됩니다.

ios_base::sync_with_stdio(false);

C 및 C ++ 표준 스트림 간의 동기화를 비활성화합니다. 기본적으로 모든 표준 스트림이 동기화되므로 실제로 C 및 C ++ 스타일 I / O를 혼합하고 합리적인 결과를 얻을 수 있습니다. 동기화를 비활성화하면 C ++ 스트림에 자체 독립 버퍼가있어 C 및 C ++ 스타일 I / O를 혼합하는 것이 어려워집니다.

또한 동기화 된 C ++ 스트림은 스레드로부터 안전합니다 (다른 스레드의 출력이 인터리브 될 수 있지만 데이터 경쟁이 발생하지 않음).

cin.tie(NULL);

이것은 cin에서 연결 cout됩니다. 묶인 스트림은 한 스트림이 다른 스트림에서 각 I / O 작업 전에 자동으로 플러시되도록합니다.

기본적 으로 합리적인 사용자 상호 작용을 보장하기 위해 cin연결되어 cout있습니다. 예를 들면 다음과 같습니다.

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

cincout묶여 있으면 프로그램이 사용자에게 입력을 요청하기 전에 출력이 플러시 (예 : 콘솔에 표시) 될 수 있습니다. 스트림을 풀면 프로그램은 사용자가 자신의 이름을 입력하기를 기다리는 것을 차단할 수 있지만 "이름 입력"메시지는 아직 보이지 않습니다 ( cout기본적으로 버퍼링 되므로 출력은 요청시 또는 콘솔에서 플러시 / 표시됩니다). 버퍼가 가득 찼습니다).

그래서 당신은 풀고 경우 cin에서 cout, 당신은 확인해야 플러시 cout수동에 입력을 기대하기 전에 뭔가를 표시 할 때마다 cin.

결론적으로, 각각의 기능을 이해하고 결과를 이해 한 다음 속도 개선 의 가능한 부작용을 원하는지 여부를 결정하십시오 .


"cin에 입력을 기대하기 전에 무언가를 표시 할 때마다 cout을 수동으로 플러시해야합니다"라고 말하면 "... << std :: flush"또는 "... < "std :: endl" "std :: cout << ..."로 시작하는 모든 줄의 끝?
Alan

4
네, 그렇게 간단하지만 "모든 줄의 끝"부분에주의하십시오. cout너무 자주 플러시하면 실제로 필요하지 않을 때 성능이 저하 될 수 있습니다.
Ionut

@Ionut C의 scanf, printf에 tie () 기능과 동등한 것이 있습니까?
iajnr

1
@iajnr 아니오, 직접 아닙니다. C에서는 전에 수동으로 플러시 scanf()하거나 버퍼링을 완전히 비활성화하거나 라인 버퍼링으로 전환 할 수 있습니다 (라인 개행 후 또는 입력을 읽을 때 linux.die.net/man/3/setlinebufstdin 참조 ).
Ionut

1
leetcode에서는 런타임을 대폭 개선합니다. 이러한 경쟁 웹 사이트는 입력 테스트에 특별한 기능을 수행 할 수 있습니다.
P0W

18

이것은 C 및 C ++ 세계의 IO를 동기화하는 것입니다. 동기화하면 모든 IO의 순서가 정확히 원하는 것입니다. 일반적으로 문제는 문제를 일으키는 IO 버퍼링으로, 두 세계가 동일한 버퍼를 공유하도록 동기화하는 것입니다. 예를 들어 cout << "Hello"; printf("World"); cout << "Ciao";; 동기화하지 않으면 얻을 수 HelloCiaoWorld있는지 HelloWorldCiao또는 알지 못할 것입니다 WorldHelloCiao...

tieC ++ 세계의 IO 채널이 서로 연결 되어 있음을 보증 할 수 있습니다. 예를 들어 입력이 발생하기 전에 모든 출력이 플러시되었음을 나타 cout << "What's your name ?"; cin >> name;냅니다 (생각합니다 ).

항상 C 또는 C ++ IO를 혼합 할 수 있지만 합리적인 동작을 원하면 두 세계를 동기화해야합니다. 일반적으로 C로 프로그래밍하면 C stdio를 사용하고 C ++로 프로그래밍하면 스트림을 사용하는 경우 혼합하지 않는 것이 좋습니다. 그러나 기존 C 라이브러리를 C ++ 코드에 혼합하고 싶을 경우 이러한 두 라이브러리를 동기화해야합니다.


4
동기화가 없어도 다른 호출로 cout <<순서를 변경할 수 없으므로 CiaoHelloWorld사례에 따라 불가능합니다. 동기화는 다른 버퍼링 방법에 관한 것입니다.
Mikko Rantalainen

3

와 스트림 ios_base::sync_with_stdio(false);을 분리하는 데 사용하면 충분합니다 . Langer와 Kreft의 Standard C ++ IOStreams and Locales 에서 이에 대한 토론을 찾을 수 있습니다 . 그들은 이것이 작동하는 방식이 구현 정의되어 있음을 주목합니다.CC++

cin.tie(NULL)대한 활동을에서 cin와 (과) 의 분리를 요청하는 것 같습니다 cout. 다른 최적화와 함께 사용하면 충돌이 발생하는 이유를 설명 할 수 없습니다. 언급 한 바와 같이, 제공 한 링크가 잘못되었으므로 여기에 추측이 없습니다.


0

cin 입력이 더 빨리 작동 하는 것은 일반적인 일입니다 .

빠른 설명 : 첫 번째 줄은 cin 스트림과 C 스타일 stdio 도구 (scanf 또는 gets 등) 간의 버퍼 동기화를 해제 하므로 cin 이 더 빨리 작동하지만 stdio 도구 와 동시에 사용할 수는 없습니다 .

두 번째 줄 은 cout 에서 cin 습니다. 기본적으로 cout 버퍼는 cin 에서 무언가를 읽을 때마다 플러시됩니다 . 작은 것을 반복해서 읽은 후 여러 번 작은 것을 쓰면 속도가 느려질 수 있습니다. 따라서 라인은이 동기화를 끕니다 (문자 그대로 cout 대신 cinnull로 묶음 ).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.