Quelle est l'importance 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 dont je devrais m'inquiéter en l'incluant?
Les 2 déclarations doivent-elles toujours être ensemble, ou la première est-elle suffisante, c'est-à-dire ignorée cin.tie(NULL)
?
De plus, est-il permis d'utiliser des commandes C et C ++ simultanées si sa valeur a été définie sur false
?
https://www.codechef.com/viewsolution/7316085
Le code ci-dessus fonctionnait bien, jusqu'à ce que je l'utilise scanf/printf
dans un programme C ++ avec la valeur comme true
. Dans ce cas, il a donné un défaut de segmentation. Quelle pourrait en être l'explication possible?
Réponses:
Les deux appels ont des significations différentes qui n'ont rien à voir avec la performance; le fait qu'il accélère le temps d'exécution n'est (ou pourrait être ) qu'un effet secondaire. Vous devez comprendre ce que chacun d'eux fait et ne pas les inclure aveuglément dans chaque programme car ils ressemblent à une optimisation.
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 les E / S de style C et C ++ et d'obtenir des résultats raisonnables et attendus. Si vous désactivez la synchronisation, les flux C ++ sont autorisés à avoir leurs propres tampons indépendants, ce qui fait du mélange d'E / S de style C et C ++ une aventure.
Gardez également à l'esprit que les flux C ++ synchronisés sont thread-safe (la sortie de différents threads peut s'entrelacer, mais vous n'obtenez aucune course de données).
Cette délie
cin
decout
. Les flux liés garantissent qu'un flux est automatiquement vidé avant chaque opération d'E / S sur l'autre flux.Par défaut,
cin
est lié àcout
pour assurer une interaction utilisateur sensible. Par exemple:Si
cin
etcout
sont liés, vous pouvez vous attendre à ce que la sortie soit vidée (c'est-à-dire visible sur la console) avant que le programme ne demande l'entrée de l'utilisateur. Si vous détachez les flux, le programme peut bloquer l'attente que l'utilisateur entre son nom, mais le message "Entrer le nom" n'est pas encore visible (car ilcout
est mis en mémoire tampon par défaut, la sortie est purgée / affichée sur la console uniquement à la demande ou lorsque le la mémoire tampon est pleine).Donc, si vous détachez
cin
decout
, vous devez vous assurer de vidercout
manuellement chaque fois que vous souhaitez afficher quelque chose avant d'attendre une entréecin
.En conclusion, sachez ce que chacun d'eux fait, comprenez les conséquences, puis décidez si vous voulez vraiment ou avez besoin de l' effet secondaire possible de l'amélioration de la vitesse.
la source
cout
est mis en mémoire tampon pour une raison, si vous le videz trop souvent, lorsque vous n'en avez pas réellement besoin, vous risquez de voir un impact négatif sur les performances.scanf()
, désactiver complètement la mise en mémoire tampon, soit passer à la mise en mémoire tampon de ligne (qui devrait vider après une nouvelle ligne ou lorsque l'entrée est lue depuisstdin
- voir linux.die.net/man/3/setlinebuf ).Il s'agit de synchroniser les E / S du monde C et C ++. Si vous synchronisez, vous avez la garantie que les commandes de tous les E / S correspondent exactement à ce que vous attendez. En général, le problème est la mise en mémoire tampon des E / S qui cause le problème, la synchronisation permet aux deux mondes de partager les mêmes tampons. Par exemple
cout << "Hello"; printf("World"); cout << "Ciao";
; sans synchronisation, vous ne saurez jamais si vous obtiendrezHelloCiaoWorld
ouHelloWorldCiao
ouWorldHelloCiao
...tie
vous permet d'avoir la garantie que les canaux d'E / S dans le monde C ++ sont liés les uns aux autres, ce qui signifie par exemple que chaque sortie a été vidée 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 voulez 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 ce cas, il est nécessaire de synchroniser les deux.
la source
cout <<
ne peuvent pas changer l'ordre, ceCiaoHelloWorld
n'est donc pas possible pour votre exemple de cas. La synchronisation concerne strictement différentes méthodes de mise en mémoire tampon.L'utilisation
ios_base::sync_with_stdio(false);
est suffisante pour découpler les fluxC
etC++
. Vous pouvez trouver une discussion à ce sujet dans les IOStreams et les paramètres régionaux C ++ standard , par Langer et Kreft. Ils notent que la façon dont cela fonctionne est définie par l'implémentation.le
cin.tie(NULL)
appel semble demander un découplage entre les activités surcin
etcout
. 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 pas de spéculation ici.la source
C'est juste des trucs communs pour faire du cin accélérer le travail de l'entrée .
Pour une explication rapide: la première ligne désactive la synchronisation de la mémoire tampon entre le flux cin et les outils stdio de style C (comme scanf ou gets) - donc cin fonctionne plus rapidement, mais vous ne pouvez pas l'utiliser simultanément avec stdio outils .
La deuxième ligne délie cin de cout - par défaut, le tampon cout se vide chaque fois que vous lisez quelque chose depuis cin . Et cela peut être lent lorsque vous lisez à plusieurs reprises quelque chose de petit, puis écrivez quelque chose de petit plusieurs fois. Ainsi, la ligne désactive cette synchronisation (en liant littéralement cin à null au lieu de cout ).
la source