Warum wird die Verwendung von cin, cout oder% I64d gegenüber% lld in C ++ bevorzugt?

8

Warum viele Online-Juroren raten: "Verwenden Sie nicht den% lld-Spezifizierer, um 64-Bit-Ganzzahlen in C ++ zu lesen oder zu schreiben. Es wird bevorzugt, den cin, cout-Stream oder den% I64d-Spezifizierer zu verwenden." ?

    
rishabh 30.03.2013, 11:30
quelle

2 Antworten

8

Ich glaube, die Antwort bezieht sich auf %lld bedeutet long long decimal , was nicht garantiert ist, dass es 64-bit ist. Es könnte beispielsweise 128 Bit auf einigen Systemen sein. (Obwohl, wenn die Variable long long und nicht, sagen wir, uint64_t ist, dann erwarte ich %lld ist das richtige zu verwenden - oder es würde umgekehrt falsch gehen)

Leider ist das Design von printf und scanf und deren Geschwister so, dass die Compiler-Implementierung und das Format übereinstimmen müssen.

Offensichtlich sind cout und cin in dem Sinne sicher, dass der Compiler die richtige Ausgabe und Eingabe in sich selbst wählt.

Es kann auch etwas damit zu tun haben, welche Compiler die "Online-Judges" benutzen - ich glaube, Microsoft Compiler unterstützten irgendwann 64-Bit-Integer, aber nicht long long , und hatten somit nicht %lld , aber %l64d .

    
Mats Petersson 30.03.2013, 11:43
quelle
4

Die Operatoren << und >> in cin und cout haben Versionen für jeden Integer und Gleitkommatyp. Wenn Sie cin und cout verwenden, tun Sie einfach cin >> integer_variable oder cout << integer_variable und Sie sind fertig, cin und cout werden herausfinden, was zu tun ist.

Wenn Sie irgendeine Art von printf() verwenden, müssen Sie sehr vorsichtig sein, was Sie daran übergeben. Wenn Sie eine int übergeben, müssen Sie auch die Typspezifikation "%d" übergeben, für unsigned int ist es "%u" , für long ist es "%ld" , für unsigned long long ist es "%llu" , für size_t es ist "%zu" und so weiter. Wenn Sie einen Typspezifizierer übergeben, der nicht mit dem Typ Ihrer Ganzzahl übereinstimmt, rufen Sie undefiniertes Verhalten auf. Infolgedessen kann Ihr Programm falsche Zahlen drucken oder sich selbst korrumpieren oder hängen oder abstürzen oder sich auf eine andere mysteriöse Weise schlecht benehmen.

Jetzt hat der C ++ 11-Sprachenstandard (und C99) mindestens einen Integer-Typ, der 64-Bit oder länger ist, long long (und sein vorzeichenloses Gegenstück, unsigned long long ). Wenn Sie es verwenden, müssen Sie beachten, dass es länger als 64 Bits sein kann. Wenn Ihr Compiler einen anderen Typ bereitstellt, __int64 oder int64_t (plus die unsignierte Version desselben), also genau 64-Bit, sollten Sie ihre Typspezifizierer nicht mischen und abgleichen, da dies oft fälschlicherweise geschieht. Sie sollten weiterhin "%lld" und "%llu" für long long und unsigned long long verwenden und was auch immer für __int64 (vielleicht "%I64d" ) und für int64_t ( PRId64 macro) geeignet ist.

Im Grunde sollten Sie entweder printf()-like functions vermeiden oder sehr vorsichtig damit sein.

    
Alexey Frunze 30.03.2013 11:58
quelle

Tags und Links