2016-01-06 19 views
24

Sono nuovo di C# e voglio capire come funzionano i valori. Se osservo un valore intero normale, contiene tre parti importanti: il tipo, il nome e il valore.C# suffisso dietro letterale numerico

int testInt = 3; 
| |  | 
Type Name Value 

Ma quando vedo un valore float che mi confonde un po 'a causa del suffisso F.

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

Ora ci sono due tipi di esso, e senza il suffisso F il valore sarebbe una doppia. Ma perché sta succedendo questo quando posso dichiarare la doppia variabile

double testDouble = 3.0D; 

Il double come prima parola dovrebbe essere sufficiente, non dovrebbe? Lo stesso vale per il valore decimale con il suffisso M:

decimal testDecimal = 3.0M; 

Poi si inizia davvero mi confusione quando si tratta di altri suffissi:

ulong bigOne = 2985825802805280508UL; 

ho usato ulong in un test prima e sanno che lo u è per "unsigned" e lascia il valore due volte più alto del normale. Quindi ottieni di nuovo l'U come suffisso e la lettera L letterale come dice Google. A quanto ho capito, i "valori letterali" sono tipi di valore che contengono numeri. Ma quello che non capisco è, perché funziona a lungo anche senza il suffisso?

ulong bigOne = 2985825802805280508; 

Poi ho cercato qualcosa di diverso per capire l'importanza del suffisso

byte testLong = 12312UL; 

Questo non ha funzionato perché il valore è troppo alto per byte (254) e il suffisso non lo converte a una variabile lunga

Perché la prima parola (tipo) non è sufficiente per una dichiarazione? La prima parola dovrebbe essere sufficiente per dire il tipo. La migliore pratica è quella di dare sempre un suffisso ai valori?

+3

Hai ragione, una dichiarazione di tipo è sufficiente quando c'è anche un incarico. Ecco perché la parola chiave var è stata aggiunta a C#: https://msdn.microsoft.com/en-us/library/bb383973.aspx – Max

+3

'U' è per non firmato, non non assegnato. –

+1

Anche per quanto riguarda i calcoli come 4.0/3? Dovrebbe usare la precisione singola o doppia? Questo influenza davvero il risultato. Oppure considerare 2000000000 * 3? È un overflow o solo un lungo? Non sempre si assegnano direttamente valori. – dryman

risposta

24

Stai confondendo due cose diverse qui:

float testFloat = 3.0F; 

Il float dice al compilatore che la variabile testFloat wil essere un valore in virgola mobile.Il F indica al compilatore che il letterale3.0 è un float. Il compilatore deve conoscere entrambi i pezzi prima che possa decidere se assegnare o meno il letterale alla variabile senza conversione o conversione implicita.

Ad esempio, si può fare questo:

float testFloat = 3; 

E va bene così. Perché il compilatore vedrà 3 come un intero letterale, ma sa che può assegnarlo a un float senza perdita di precisione (questa è una conversione implicita). Ma se si fa questo:

float testFloat = 3.0; 

3.0 è un letterale doppia (perché questo è il difetto senza suffisso) e non può implicitamente (vale a dire automaticamente) convertire un doppio ad un galleggiante a causa di un galleggiante ha meno precisione. In altre parole, le informazioni potrebbero essere perse. Così si sia dire al compilatore che si tratta di un float letterale:

float testFloat = 3.0f; 

o dirvi che si sta bene con qualsiasi perdita di precisione utilizzando un cast esplicito:

float testFloat = (float)3.0; 
+4

Esattamente. Se esegui 'var result = 4/3;', il compilatore deve decidere se è un numero intero o un'operazione float e ciò dipende solo da cosa c'è sul lato destro dell'operatore di assegnazione. Per impostazione predefinita, i valori interi sono considerati 'int' e i valori decimali sono considerati' double'. Quindi questo renderà 'result' un' int' di 1. Se fai '4/3.0' invece,' result' sarà un 'double' con un valore di 1.3333333. – Andrew

+0

Ora capisco meglio grazie. Non ho mai fatto una dichiarazione con un calcolo al suo interno. Pensato che il punto tra i numeri deve essere sufficiente per capire il compilatore. – user3772108

+0

Ma anche con l'esempio di calcolo. Il galleggiante all'inizio dovrebbe essere abbastanza per dire che voglio un galleggiante? Perché Byte to Long con solo un suffisso non funziona? – user3772108

2

Exists altro modo per dichiarare una variabile senza specificare il tipo prima del nome:

var myNumber = 10; 

In questo caso, il tipo di variabile sarà definito dal valore letterale.

Se si utilizza il tipo (double | float | int | ...) invece "var", il compilatore effettua una conversione del valore letterale in tipo di variabile (quando è possibile).

Quindi, penso che il suffisso sia importante quando si utilizza "var" per dichiarare le variabili e il tipo di valore letterale non è l'impostazione predefinita associata quando il suffisso non viene utilizzato;

C'è un altro motivo quando il suffisso di uso è troppo utile, come nella situazione in cui si desidera eseguire conversioni implicite nelle espressioni.

+3

Questa è una situazione in cui è rilevante la necessità di distinguere diversi valori letterali numerici tramite suffissi, ma non è la * ragione *, e non è certamente l'unica situazione di questo tipo (dopotutto, 'var' è stato aggiunto a più versioni nella lingua, ma il bisogno di suffissi è stato lì fin dall'inizio). – Servy

+0

Quindi posso dichiarare ogni variabile solo con var e il suffisso corretto? – user3772108

+1

@ user3772108 Nella maggior parte dei casi sì, ci sono alcune eccezioni che non è possibile, come definire un Func. Ma la maggior parte delle dichiarazioni può essere risolta con 'var', esempio:' var arrayOfInt = new [] {1,2,3} '. Non è possibile utilizzare l'esempio: 'Func add = (a, b) => a + b', in questo caso è necessario definire il tipo di variabile. Puoi trovare ulteriori informazioni su 'var' qui https://msdn.microsoft.com/en-us/library/bb383973.aspx –

10

Tutti le espressioni devono essere risolvibili con un tipo. Quindi l'espressione 42sempre deve avere esattamente un tipo (capita di essere un int). Non può essere un int se lo si assegna a una variabile int e a double se lo si assegna a un double. Il contesto in cui viene utilizzata un'espressione non è mai utilizzato per determinare il tipo a cui si risolve.

Ecco perché i valori letterali numerici possono avere suffissi; è un modo di definire il tipo di quell'espressione in quell'espressione.

noti che ci sono anche conversioni implicite tra molti tipi numerici, quindi se si scrive double d = 42; l'espressione 42è in realtà un intero, ma c'è un operatore di conversione implicita essendo effettuate su di essa che si convertirà in un double prima dell'assegnazione.

Qui ci sono alcune eccezioni, come lambda, a cui il tipo di espressione dipende da come sono utilizzati e dai gruppi di metodi; nel vuoto queste espressioni non hanno tipo.

+0

La tua risposta e Matt Burland mi hanno aiutato molto a capire. Grazie mille per quello. – user3772108

+0

@LucasTrzesniewski Giusto. – Servy

Problemi correlati