2013-03-06 27 views
6

Questa stampe codice B2promozione Integer - quali sono i passi

short a=-5; 
unsigned short b=-5u; 
if(a==b) 
    printf("A1"); 
else 
    printf("B2"); 

ho letto sulla promozione intero, ma non è ancora chiaro per me, come funziona nell'esempio qui? Qualcuno può postare accuratamente i passaggi seguiti dal compilatore per ampliare/troncare i valori?

+0

quale compilatore stai usando? –

+0

[questo] (http://en.cppreference.com/w/cpp/language/implicit_cast) potrebbe essere utile. – juanchopanza

+0

La promozione di interi ha luogo solo nell'espressione 'a == b' - è tutto quello che stai chiedendo? –

risposta

8

Camminiamo attraverso il tuo codice:

short a = -5; 

a = -5, che si inserisce in una breve. Fin qui tutto bene.

unsigned short b = -5u; 

mezzi -5u applicare il - operatore unario al 5u costante. 5u è (unsigned int) 5 e lo unario - non fa promozione, quindi si finisce con 4294967291 che è 2^32-5. (Aggiornamento: ho sbagliato questo bit nella mia risposta originale, vedere uno script di prova che mostra questa versione è corretta qui http://codepad.org/hjooaQFW)

Ora quando lo si inserisce in b, viene troncato a un corto senza segno (2 byte, di solito) , quindi b = 65531, che è 2^16-5.

if(a == b) 

In questa riga, aeb sono entrambi promossi in pollici in modo che il confronto possa avvenire correttamente. Se fossero promossi in cortometraggi, b sarebbe potenzialmente avvolgente. Se fossero promossi a cortometraggi non firmati, si sarebbero potenzialmente avvolti.

Quindi è come dire if((int) a == (int) b). E a = -5, quindi (int) a = -5, e b = 65531, quindi (int) b = 65531, perché le inte sono più grandi dei cortometraggi.

+0

Non direi che "-5u" non ha senso - è ben definito dallo standard. –

+3

Um, '-5u' è perfettamente ragionevole. Si applica '-' alla costante intera' 5u'. –

+0

Hai raggiunto un punto a cui sono interessato: quindi PRIMA -5 viene memorizzato nella variabile 'a' breve ... il suo valore costante viene trattato come un numero intero, giusto? Sono profondamente interessato a questo punto –

3
a == b 

a e b sono entrambi promossi al int nell'espressione sopra.

unsigned short b=-5u; 

In questa dichiarazione -5U viene convertito unsigned short dai mezzi di conversione interi (C99, 6.3.1.3p2 applica qui) e diventa un valore elevato.

(C99, 6.3.1.3p2) "Altrimenti, se il nuovo tipo è senza segno, il valore viene convertito ripetutamente aggiungendo o sottraendo un valore superiore al massimo che può essere rappresentato nel nuovo tipo fino al valore è nella gamma del nuovo tipo. "

b valore è quindi (unsigned short) ((unsigned int) USHRT_MAX + 1 -5) che è (unsigned short) 65531 se USHRT_MAX è (unsigned short) 65535.

Quindi quello che hai è:

(short) -5 == (unsigned short) 65531

che equivale dopo la promozione intero di entrambi gli operandi a:

-5 == 65531

che è equivalente a 0.

+0

re "Su un sistema a complemento a due", beh, è ​​così a prescindere dalla rappresentazione di interi con segno, perché lo standard santo richiede che sia binario, e poiché 5 è molto più piccolo rispetto all'intervallo minimo richiesto, e poiché il lo standard richiede che l'aritmetica senza segno sia il modulo 2^n dove n è il numero di bit di rappresentazione. Quindi, per esempio, 'unsigned' a 32 bit e' unsigned short' a 16 bit 'l'espressione '-5u' in sé produce il valore 2^32-5, e quindi quel valore modulo 2^16 è necessariamente 2^16- 5. di nuovo, indipendentemente dalla rappresentazione intera con segno. –

+0

@ Cheersandhth.-Alf Accetto, ho rimosso questa frase poco prima del tuo commento. Ho iniziato con * su un sistema a complemento a due * perché inizialmente volevo aggiungere informazioni sul (no) cambiamento di rappresentazione. – ouah

0

short ad unsigned short è una conversione (avendo così rango conversione)

short ad int è una promozione (avendo così rango promozione)

promozioni sono preferite rispetto alle conversioni causa della graduatoria. Le promozioni si verificano durante l'aritmetica e altre operazioni. Le conversioni si verificano quando si memorizza semplicemente un tipo integrale all'interno di un altro. Le operazioni aritmetiche possono causare conversioni e promozioni, al fine di costringere i tipi insieme. Per un altro esempio:

unsigned int u = 2; 
int i = 2; 
u + i; 

i viene convertito (non promossi) per unsigned.

Il valore viene convertito in un valore superiore perché si avvolge a causa di essere unsigned. Quindi, vengono promossi a int. Quindi a != b per questo motivo.