Ich verwende überall nicht signierte Ints und bin mir nicht sicher, ob ich sollte. Dies kann von Datenbankprimärschlüssel-ID-Spalten bis zu Zählern usw. reichen. Wenn eine Zahl niemals negativ sein sollte, verwende ich immer ein vorzeichenloses int.
Ich bemerke jedoch aus dem Code eines anderen, dass dies anscheinend niemand anderes tut. Gibt es etwas Entscheidendes, das ich übersehen habe?
Edit: Seit dieser Frage ist mir auch aufgefallen, dass es in C üblich ist, negative Werte für Fehler zurückzugeben, anstatt wie in C ++ Ausnahmen auszulösen.
c++
c
programming-practices
wting
quelle
quelle
for(unsigned int n = 10; n >= 0; n --)
(Endlosschleifen)Antworten:
Wenn bei Berechnungen sowohl vorzeichenbehaftete als auch nicht vorzeichenbehaftete Typen sowie unterschiedliche Größen berücksichtigt werden, können die Regeln für die Typheraufstufung komplex sein und zu unerwartetem Verhalten führen .
Ich glaube, dies ist der Hauptgrund, warum Java Int-Typen ohne Vorzeichen ausgelassen hat.
quelle
int
die eine solche Schwierigkeit darstellen würden, stellen jedoch keine solche Schwierigkeit dar (da Berechnungen zu fördern sindint
); Ich kann nichts Gutes über das Fehlen eines Typs ohne Vorzeichen sagen.Ich denke, dass Michael einen gültigen Punkt hat, aber IMO der Grund, warum jeder int die ganze Zeit (besonders in
for (int i = 0; i < max, i++
) verwendet, ist, dass wir es so gelernt haben. Wenn jedes einzelne Beispiel in einem Buch über das Erlernen des Programmierensint
in einerfor
Schleife verwendet wird, werden sehr wenige diese Praxis jemals in Frage stellen.Der andere Grund ist, dass
int
25% kürzer sind alsuint
, und wir sind alle faul ... ;-)quelle
++
beim Inkrementieren Postfix verwendet , obwohl sein spezielles Verhalten selten benötigt wird und sogar zu sinnlosem Umblättern von Kopien führen kann, wenn der Schleifenindex ein Iterator oder ein anderer nicht grundlegender Typ ist (oder der Compiler wirklich dicht ist). .Das Codieren von Bereichsinformationen in Typen ist eine gute Sache. Es erzwingt die Verwendung angemessener Zahlen zur Kompilierungszeit.
Viele Architekturen scheinen spezielle Anweisungen für den Umgang mit
int
->float
Konvertierungen zu haben. Die Konvertierung vonunsigned
kann langsamer sein (ein kleines bisschen) .quelle
Das Mischen von signierten und nicht signierten Typen kann Sie in eine Welt der Schmerzen versetzen. Und Sie können nicht alle vorzeichenlosen Typen verwenden, da Sie auf Dinge stoßen, die entweder einen gültigen Bereich haben, der negative Zahlen enthält, oder einen Wert benötigen, um einen Fehler anzuzeigen, und -1 ist am natürlichsten. Das Nettoergebnis ist also, dass viele Programmierer alle vorzeichenbehafteten Ganzzahltypen verwenden.
quelle
Bei mir dreht sich viel um Kommunikation. Indem Sie explizit ein vorzeichenloses int verwenden, teilen Sie mir mit, dass vorzeichenbehaftete Werte keine gültigen Werte sind. Auf diese Weise kann ich beim Lesen des Codes zusätzlich zum Variablennamen einige Informationen hinzufügen. Im Idealfall würde mir ein nicht anonymer Typ mehr sagen, aber er gibt mir mehr Informationen, als wenn Sie überall Ints verwendet hätten.
Leider sind sich nicht alle bewusst, was ihr Code kommuniziert, und das ist wahrscheinlich der Grund, warum Sie überall Ints sehen, obwohl die Werte zumindest nicht mit Vorzeichen versehen sind.
quelle
Ich verwende
unsigned int
in C ++ hauptsächlich für Array-Indizes und für jeden Zähler, der mit 0 beginnt. Ich denke, es ist gut, explizit zu sagen, dass diese Variable nicht negativ sein kann.quelle
Dies sollte beachtet werden, wenn es sich um eine Ganzzahl handelt, die sich tatsächlich den Grenzwerten eines signierten Int. Nähert oder diese überschreitet. Da das positive Maximum einer 32-Bit-Ganzzahl 2.147.483.647 ist, sollten Sie ein vorzeichenloses int verwenden, wenn Sie wissen, dass es a) niemals negativ ist und b) möglicherweise 2.147.483.648 erreicht. In den meisten Fällen, einschließlich Datenbankschlüsseln und Zählern, werde ich mich diesen Zahlen nicht einmal nähern, sodass ich mich nicht darum kümmern muss, ob das Vorzeichenbit für einen numerischen Wert oder zum Anzeigen des Vorzeichens verwendet wird.
Ich würde sagen: Verwenden Sie int, es sei denn, Sie wissen, dass Sie ein nicht signiertes int benötigen.
quelle
Es ist ein Kompromiss zwischen Einfachheit und Zuverlässigkeit. Je mehr Fehler beim Kompilieren gefunden werden, desto zuverlässiger ist die Software. Unterschiedliche Personen und Organisationen befassen sich in diesem Spektrum mit unterschiedlichen Aspekten.
Wenn Sie jemals eine hochzuverlässige Programmierung in Ada durchführen, verwenden Sie sogar unterschiedliche Typen für Variablen wie Entfernung in Fuß oder Entfernung in Metern. Der Compiler kennzeichnet diese, wenn Sie versehentlich eine andere zuweisen. Das ist perfekt zum Programmieren einer Lenkwaffe, aber übertrieben (Wortspiel beabsichtigt), wenn Sie ein Webformular validieren. In beiden Fällen muss nichts falsch sein, solange es den Anforderungen entspricht.
quelle
Ich bin geneigt, Joel Ethertons Argumentation zuzustimmen, komme aber zu dem gegenteiligen Schluss. So wie ich es sehe, auch wenn Sie wissen , dass die Zahlen wahrscheinlich nicht immer die Grenzen eines signierten Art zu nähern, wenn Sie wissen , dass negative Zahlen nicht passieren wird , dann gibt es sehr wenig Grund , die signierte Variante eines Typs zu verwenden.
Aus dem gleichen Grund habe ich in einigen ausgewählten Fällen
BIGINT
(64-Bit-Ganzzahl) und nichtINTEGER
(32-Bit-Ganzzahl) in SQL Server-Tabellen verwendet. Die Wahrscheinlichkeit, dass die Daten innerhalb eines angemessenen Zeitraums die 32-Bit-Grenze erreichen, ist gering. Sollte dies jedoch der Fall sein, können die Konsequenzen in einigen Situationen verheerend sein. Achten Sie nur darauf, dass Sie die Typen zwischen den Sprachen richtig zuordnen, sonst werden Sie in der nächsten Zeit eine interessante Verrücktheit erleben ...Das heißt, für einige Dinge, wie z. B. Werte von Datenbankprimärschlüsseln, die signiert oder nicht signiert sind, spielt es keine Rolle, denn es sei denn, Sie reparieren fehlerhafte Daten oder ähnliches manuell, so dass Sie sich nie direkt mit dem Wert befassen. Es ist ein Identifikator, nichts weiter. In diesen Fällen ist die Konsistenz wahrscheinlich wichtiger als die genaue Wahl der Signatur. Andernfalls haben Sie einige Fremdschlüsselspalten, die signiert sind, und andere, die nicht signiert sind, ohne erkennbares Muster - oder wieder diese interessante Verrücktheit.
quelle
Ich würde empfehlen, dass man außerhalb platzbeschränkter Datenspeicher- und Datenaustauschkontexte generell signierte Typen verwenden sollte. In den meisten Fällen, in denen eine 32-Bit-Ganzzahl mit Vorzeichen zu klein wäre, aber ein 32-Bit-Wert ohne Vorzeichen für heute ausreicht, wird es nicht lange dauern, bis der 32-Bit-Wert ohne Vorzeichen auch nicht groß genug ist.
Die primären Zeiten, in denen man vorzeichenlose Typen verwenden sollte, sind, wenn man entweder mehrere Werte zu einem größeren zusammensetzt (z. B. vier Bytes in eine 32-Bit-Zahl umwandelt) oder größere Werte in kleinere zerlegt (z. B. eine 32-Bit-Zahl als vier Bytes speichert) ) oder wenn man eine Menge hat, von der erwartet wird, dass sie periodisch "überschlägt", und man sich damit befassen muss (man denke an einen Haushaltszähler; die meisten von ihnen haben genügend Ziffern, um sicherzustellen, dass sie möglicherweise nicht zwischen den Ablesungen überschlagen wenn sie dreimal im Jahr gelesen werden, aber nicht ausreichen, um sicherzustellen, dass sie sich nicht innerhalb der Nutzungsdauer des Messgeräts überschlagen). Unsignierte Typen haben oft genug Verrücktheit, dass sie nur in Fällen verwendet werden sollten, in denen ihre Semantik notwendig ist.
quelle
size_t
nicht signiert undptrdiff_t
signiert ist.Ich verwende unsignierte Ints, um meinen Code und seine Absichten klarer zu machen. Zum Schutz vor unerwarteten impliziten Konvertierungen beim Rechnen mit vorzeichenbehafteten und vorzeichenlosen Typen verwende ich eine vorzeichenlose Kurzform (normalerweise 2 Byte) für meine vorzeichenlosen Variablen. Dies ist aus mehreren Gründen effektiv:
Das allgemeine Prinzip ist, dass der Typ Ihrer vorzeichenlosen Variablen einen niedrigeren Rang haben sollte als der Typ der vorzeichenbehafteten Variablen, um die Heraufstufung zum vorzeichenbehafteten Typ sicherzustellen. Dann haben Sie kein unerwartetes Überlaufverhalten. Natürlich können Sie dies nicht immer sicherstellen, aber (meistens) ist es möglich, dies sicherzustellen.
Zum Beispiel hatte ich kürzlich eine for-Schleife, die ungefähr so aussah:
Das Literal '2' ist vom Typ int. Wenn i ein vorzeichenloses int anstelle eines vorzeichenlosen short wäre, würde in dem Unterausdruck (i-2) 2 zu einem vorzeichenlosen int heraufgestuft (da vorzeichenloses int eine höhere Priorität als vorzeichenloses int hat). Wenn i = 0 ist, ist der Unterausdruck gleich (0u-2u) = ein massiver Wert aufgrund eines Überlaufs. Dieselbe Idee mit i = 1. Da i jedoch ein Short ohne Vorzeichen ist, wird es auf den gleichen Typ wie Literal '2' hochgestuft, das mit int signiert ist, und alles funktioniert einwandfrei.
Für zusätzliche Sicherheit: In dem seltenen Fall, dass die Architektur, auf der Sie implementieren, int auf 2 Byte erhöht, werden möglicherweise beide Operanden im arithmetischen Ausdruck in unsigned int hochgestuft, wenn die unsigned short-Variable nicht passt in das vorzeichenbehaftete 2-Byte-int, dessen letzterer einen Maximalwert von 32.767 <65.535 hat. ( Weitere Informationen finden Sie unter https://stackoverflow.com/questions/17832815/c-implicit-conversion-signed-unsigned .) Um sich davor zu schützen, können Sie Ihrem Programm einfach einen static_assert wie folgt hinzufügen:
und es wird nicht auf Architekturen kompiliert, bei denen int 2 Bytes beträgt.
quelle