web-dev-qa-db-fra.com

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

Quelle est la signification d'inclure

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

dans les programmes C++?

Dans mes tests, cela accélère le temps d'exécution, mais y a-t-il un cas de test qui devrait m'inquiéter en incluant cela?

Les 2 instructions doivent-elles toujours être ensemble, ou la première est-elle suffisante, c'est-à-dire en ignorant cin.tie(NULL)?

De même, est-il permis d'utiliser des commandes simultanées C et C++ si sa valeur a été définie sur false?

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

Le code ci-dessus a bien fonctionné, jusqu'à ce que j'utilise scanf/printf dans un programme C++ avec la valeur true. Dans ce cas, il a donné une faute de segmentation. Quelle pourrait être l'explication possible pour cela?

100
Kshitij Kohli

Les deux appels ont des significations différentes qui n'ont rien à voir avec la performance; le fait que accélère le temps d'exécution est (ou pourrait être ) juste un effet secondaire. Vous devez comprendre ce que chacun d'eux fait et ne pas les inclure aveuglément dans tous les programmes car ils ressemblent à une optimisation.

ios_base::sync_with_stdio(false);

Cela désactive la synchronisation entre les flux standard C et C++. Par défaut, tous les flux standard sont synchronisés, ce qui vous permet en pratique de mélanger des E/S de style C et C++ et d'obtenir des résultats sensibles et attendus. Si vous désactivez la synchronisation, les flux C++ sont autorisés à disposer de leurs propres mémoires tampons indépendantes, ce qui fait du mélange d'entrées/sorties de style C et C++ une aventure.

N'oubliez pas non plus que les flux C++ synchronisés sont sécurisés pour les threads (les sorties de différents threads peuvent s'entrelacer, mais vous n'obtenez aucune course de données).

cin.tie(NULL);

Ceci dégage cin de cout. Les flux liés s'assurent qu'un flux est vidé automatiquement avant chaque opération d'E/S sur l'autre flux.

Par défaut, cin est lié à cout pour assurer une interaction utilisateur judicieuse. Par exemple:

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

Si cin et cout sont liés, vous pouvez vous attendre à ce que le résultat soit vidé (c'est-à-dire visible sur la console) avant que le programme ne demande à l'utilisateur de le saisir. Si vous détachez les flux, le programme peut attendre que l'utilisateur entre son nom, mais le message "Entrer le nom" n'est pas encore visible (car cout est mis en mémoire tampon par défaut, la sortie est vidée/affichée uniquement sur la console. sur demande ou lorsque la mémoire tampon est pleine).

Donc, si vous dégagez cin de cout, vous devez vous assurer de vider manuellement cout chaque fois que vous souhaitez afficher quelque chose avant d'attendre une entrée sur cin.

En conclusion, sachez ce que chacun d’entre eux fait, comprenez les conséquences et décidez ensuite si vous voulez ou avez réellement besoin de l’effet secondaire possible de l’amélioration de la vitesse.

163
Ionut

Ceci permet de synchroniser les E/S du monde C et C++. Si vous synchronisez, vous avez alors la garantie que les ordres de tous les IO correspondent exactement à vos attentes. En général, le problème est la mise en mémoire tampon des E/S qui la cause, la synchronisation permettant aux deux mondes de partager les mêmes mémoires tampons. Par exemple, cout << "Hello"; printf("World"); cout << "Ciao";; sans synchronisation, vous ne saurez jamais si vous obtiendrez HelloCiaoWorld ou HelloWorldCiao ou CiaoHelloWorld...

tie vous donne la garantie que les canaux d'E/S dans le monde C++ sont liés l'un par rapport à l'autre, ce qui signifie par exemple que toutes les sorties ont été vidées avant que les entrées ne se produisent (pensez à cout << "What's your name ?"; cin >> name;).

Vous pouvez toujours mélanger des E/S C ou C++, mais si vous souhaitez un comportement raisonnable, vous devez synchroniser les deux mondes. Attention, en général, il n'est pas recommandé de les mélanger, si vous programmez en C, utilisez C stdio et si vous programmez en C++, utilisez des flux. Mais vous voudrez peut-être mélanger les bibliothèques C existantes dans du code C++ et, dans un tel cas, il sera nécessaire de les synchroniser.

10

Utiliser ios_base::sync_with_stdio(false); suffit à découpler les flux C et C++. Vous pouvez trouver une discussion à ce sujet dans Standard IOStreams and Locales , de Langer et Kreft. Ils notent que la façon dont cela fonctionne est définie par l'implémentation.

L'appel cin.tie(NULL) semble demander un découplage entre les activités sur cin et cout. Je ne peux pas expliquer pourquoi l'utilisation de ceci avec l'autre optimisation devrait provoquer un crash. Comme indiqué, le lien que vous avez fourni est mauvais, donc aucune spéculation ici.

2
Don Wakefield