2016-01-06 5 views
24

Ich bin neu in C# und möchte verstehen, wie Werte funktionieren. Wenn ich einen normalen Integer-Wert betrachte, hat er 3 wichtige Teile: Typ, Name und Wert.C# -Suffix hinter numerischem Literal

int testInt = 3; 
| |  | 
Type Name Value 

Aber wenn ich einen Float-Wert sehen es verwirrt mich ein wenig wegen der Endung F.

float testFloat = 3.0F; 
    |  |  | | 
Type Name Value Type 

Jetzt gibt es zwei Typen drin, und ohne die F Suffix würde der Wert eine doppelt so hoch sein. Aber warum ist das passiert, wenn ich die doppelte Variable deklarieren können mit

double testDouble = 3.0D; 

Die double als das erste Wort genug sein sollte, sollte es nicht? Das gleiche gilt für den Dezimalwert mit dem Suffix M:

decimal testDecimal = 3.0M; 

Dann ist es wirklich mich beginnt verwirrend, wenn es um die anderen Suffixe kommt:

ulong bigOne = 2985825802805280508UL; 

I verwendet ulong in einem Test vor und wissen, dass Die u ist für "unsigned" und lässt den Wert doppelt so hoch wie normal sein. Dann bekommst du das U wieder als Suffix und das L für wörtlich wie Google gesagt hat. Wie ich es verstehe, sind "Literale" Werttypen, die Zahlen enthalten. Aber was ich nicht verstehe ist, warum funktioniert dieses ulong auch ohne das Suffix?

ulong bigOne = 2985825802805280508; 

Dann habe ich versucht, etwas anderes die Bedeutung des Suffix

byte testLong = 12312UL; 

Das hat nicht funktioniert, weil der Wert zu hoch ist, zu verstehen für Byte (254) und das Suffix nicht wandelt es in eine lange Variable.

Warum reicht das erste Wort (Typ) nicht für eine Deklaration? Das erste Wort sollte ausreichen, um den Typ zu bestimmen. Ist es die beste Vorgehensweise, den Werten immer ein Suffix zu geben?

+3

Sie haben Recht, eine Typdeklaration ist genug, wenn es auch eine Aufgabe gibt. Aus diesem Grund wurde das Schlüsselwort var zu C# hinzugefügt: https://msdn.microsoft.com/en-us/library/bb383973.aspx – Max

+3

'U' ist für unsigned, nicht unassigned. –

+1

Und was ist mit Berechnungen wie 4.0/3? Sollte es einzelne oder doppelte Genauigkeit verwenden? Das beeinflusst das Ergebnis wirklich. Oder überlegen 2000000000 * 3? Ist es ein Überlauf oder nur ein langer? Sie bestimmen nicht immer direkt Werte. – dryman

Antwort

24

Sie sind verwirrend zwei verschiedene Dinge hier:

float testFloat = 3.0F; 

Der float teilt dem Compiler mit, dass die Variable testFloat ein Gleitkommawert wil.Die F teilt dem Compiler mit, dass der Literal3.0 ein float ist. Der Compiler muss beide Teile kennen, bevor er entscheiden kann, ob er das Literal entweder mit keiner Konvertierung oder einer impliziten Konvertierung der Variablen zuweisen kann.

Zum Beispiel können Sie dies tun:

float testFloat = 3; 

Und das ist okay. Weil der Compiler 3 als eine literale Ganzzahl sehen wird, aber er weiß, dass er dies einem Gleitkomma ohne Genauigkeitsverlust zuweisen kann (dies ist eine implizite Umwandlung). Aber wenn Sie das tun:

float testFloat = 3.0; 

3.0 ist eine wörtliche double (denn das ist die Standardeinstellung ohne Suffix) und es kann nicht implizit (das heißt automatisch) konvertiert eine doppelte mit einem Schwimmer, weil ein Schwimmer weniger Präzision hat. Mit anderen Worten, die Information könnte verloren gehen. Also entweder Sie den Compiler sagen, dass es eine wörtliche float:

float testFloat = 3.0f; 

Oder Sie es sagen, Sie sind in Ordnung mit jedem Genauigkeitsverlust durch die Verwendung eines expliziten Besetzung:

float testFloat = (float)3.0; 
+4

Genau. Wenn Sie 'var result = 4/3;' angeben, muss der Compiler entscheiden, ob es sich um eine Integer- oder eine Float-Operation handelt, und das hängt nur davon ab, was sich auf der rechten Seite des Zuweisungsoperators befindet. Standardmäßig werden Integer-Werte als "int" und Dezimalwerte als "double" betrachtet. Also wird 'result' ein' int' von 1. Wenn Sie '4/3.0' stattdessen tun, wird' result' ein 'double' mit einem 1.3333333 Wert sein. – Andrew

+0

Jetzt verstehe ich besser danke. Ich habe nie eine Erklärung mit einer Rechnung gemacht. Dachte der Punkt zwischen den Zahlen muss genug sein, um für den Compiler zu verstehen. – user3772108

+0

Aber auch mit dem Rechenbeispiel. Der Schwimmer am Anfang sollte genug sein, um zu sagen, dass ich einen Schwimmer haben möchte? Weil Byte zu Long mit nur einem Suffix nicht funktioniert? – user3772108

2

Exists andere Art und Weise eine Variable zu deklarieren, ohne die Art vor dem Namen angeben:

var myNumber = 10; 

In diesem Fall wird der Variablentyp durch den wörtlichen Wert definiert werden.

Wenn Sie den Typ (double | float | int | ...) anstelle von "var" verwenden, führt der Compiler eine Umwandlung von Literalwert in Variablentyp durch (wenn möglich).

Also, ich denke, dass Suffix wichtig ist, wenn Sie "Var" verwenden, um Variablen zu deklarieren, und der literale Werttyp ist nicht der Standardwert zugeordnet, wenn das Suffix nicht verwendet wird;

Es gibt einen weiteren Grund, wenn die Verwendung von Suffix zu nützlich ist, wie in Situationen, in denen Sie implizite Konvertierungen in Ausdrücken vornehmen möchten.

+3

Dies ist eine Situation, in der die Notwendigkeit, verschiedene numerische Literale über Suffixe zu unterscheiden, relevant ist, aber es ist nicht der * Grund *, und es ist sicherlich nicht die einzige solche Situation (schließlich wurde 'Var' mehrere Versionen in die Sprache hinzugefügt, aber die Notwendigkeit für Suffixe ist seit dem Start dort gewesen). – Servy

+0

Also kann ich jede Variable nur mit var und dem richtigen Suffix deklarieren? – user3772108

+1

@ user3772108 In den meisten Fällen ja, gibt es einige Ausnahmen, die Sie nicht definieren können, wie ein Func definieren. Aber die meisten Deklarationen können mit 'var' gelöst werden, zum Beispiel:' var arrayOfInt = new [] {1,2,3} '. Beispiel: 'Func add = (a, b) => a + b', in diesem Fall müssen Sie den Variablentyp definieren. Sie können mehr über 'var' hier erfahren https://msdn.microsoft.com/en-us/library/bb383973.aspx –

10

Alle Ausdrücke müssen zu einem Typ auflösbar sein. Also muss der Ausdruck 42immergenau einen Typ haben (es ist zufällig ein int). Es kann kein int sein, wenn Sie es einer int Variablen und einem double zuweisen, wenn Sie es einer double zuweisen. Der Kontext, in dem ein Ausdruck verwendet wird, wird niemals verwendet, um festzustellen, um welchen Typ es sich handelt.

Aus diesem Grund können numerische Literale Suffixe haben; Es ist eine Möglichkeit, den Typ des Ausdrucks in diesem Ausdruck zu definieren.

Hinweis, dass es auch implizite Konvertierungen zwischen vielen der numerischen Typen, also wenn Sie double d = 42; schreiben den Ausdruck 42ist eigentlich eine ganze Zahl, aber es gibt eine implizite Konvertierung Operator auf sie durchgeführt wird, dass sie in eine umwandeln double vor der Zuweisung.

Hier gibt es ein paar Ausnahmen, z. B. lambdas, für die der Typ des Ausdrucks davon abhängt, wie er verwendet wird, und Methodengruppen; In einem Vakuum haben diese Ausdrücke keinen Typ.

+0

Ihre Antwort und Matt Burland hat mir sehr geholfen zu verstehen. Vielen Dank dafür. – user3772108

+0

@ LucasTrzesniewski Ganz richtig. – Servy