2010-10-10 9 views
7
main() { 
    if (-1 < (unsigned char) 1) 
    printf("less than"); 
    else   
    printf("NOT less than"); 
} 

Stampe less than. Perché, (unsigned char) 1viene convertito in(signed char) 1 e quindi: (signed) -1 < (signed) 1, pertanto l'output è less than.Promozioni dei tipi di dati durante operazioni aritmetiche: -1 <(unsinged int) 1 == false

Ma se cambio il codice qui sopra-if ((-1 < (unsigned int) 1)

allora l'uscita è NOT less than.

Quindi è ovvio che quando cambio unsigned char a unsigned int:

  • (firmato) -1 viene convertito in unsigned int [esattamente opposto sta accadendo]
  • dal -1 è memorizzato come complimento 2 di di 1; il bit-pattern è valutato come 255 (probabilmente)
  • quindi 255 < 1 valuterà su falso e altro verrà eseguito.
  • anche se si sostituisce int a = -1; al posto di '-1' stesso risultato

Domande:

  1. durante l'aritmetica firmato e non firmato ... come essere sicuri se firmato saranno convertiti in non firmato o viceversa.

  2. perché è la conversione diverso per aritmetica tra unsigned char e char: a quanto pare unsigned viene convertito firmato e unsigned int e int: a quanto pare firmato è convertitore di unsigned

PS: So che questo non è compilatore dipendente ... quindi non dire che lo è.

+0

non sono tutti letterali standard int? (char unsigned - int promozione vs int -> promozione unsigned int) – flownt

risposta

10

Le regole sono le seguenti:

6.3.1.8 conversioni aritmetiche usuali

...

Altrimenti, promozioni interi vengono eseguite su entrambi gli operandi. Poi le seguenti regole sono applicate agli operandi promossi:

  1. Se entrambi gli operandi sono dello stesso tipo, allora non è necessaria alcuna ulteriore conversione.
  2. Altrimenti, se entrambi gli operandi hanno tipi interi con segno o entrambi hanno tipi interi senza segno, l'operando con il tipo di rango di conversione intero minore viene convertito nel tipo dell'operando con grado maggiore.
  3. Altrimenti, se l'operando che ha un numero intero senza segno ha una posizione superiore o uguale al grado del tipo di un altro operando, l'operando con tipo di intero con segno viene convertito nel tipo dell'operando con tipo di intero senza segno.
  4. Altrimenti, se il tipo di operando con tipo intero con segno può rappresentare tutti i valori del tipo di operando con tipo intero senza segno, allora l'operando con tipo intero senza segno viene convertito nel tipo dell'operando con numero intero con segno genere.
  5. In caso contrario, entrambi gli operandi vengono convertiti nel tipo intero senza segno corrispondente al tipo di operando con tipo intero con segno.

Le regole quindi funzionano come segue:

  • -1 < (unsigned char) 1

First entrambi gli operandi vengono convertiti in int (perché un int può rappresentare tutti i valori di char senza segno). Quindi il confronto è fatto su questi tipi firmati. Viene quindi utilizzata la regola 1. Il confronto ha successo.

  • -1 < (unsigned int) 1

Un int non può rappresentare tutti i valori di un unsigned int modo regola 3 viene utilizzato e il numero intero con segno viene convertito in un numero intero senza segno (UINT_MAX - 1). Il confronto ora fallisce.

+1

"rank"? cosa implica? – bakra

+0

@bakra: Si può pensare ad un "ordinamento" dei tipi. Ad esempio, un long int ha un rango più alto di un char. Vedi 6.3.1.1 per la definizione ufficiale di rango. –

+1

@bakra: "rank" di un tipo integrale è definito altrove nello standard C, ma la sostanza di esso è quale tipo ha un intervallo più ampio di valori possibili, oltre a poche eccezioni. In particolare, "Il grado di un intero con segno deve essere maggiore del grado di qualsiasi tipo di intero con segno con minore precisione." e "Il grado di qualsiasi tipo intero senza segno è uguale al grado del corrispondente tipo di intero con segno, se presente." – aschepler

1

Ciò è dovuto alle promozioni intere . Entrambi gli argomenti possono essere rappresentati come int, quindi vengono convertiti in int.

ISO C 6.3.1.1, paragrafo 2:

Se un int può rappresentare tutti i valori del tipo iniziale, il valore viene convertito in un int; in caso contrario, viene convertito in un int unsigned. Queste sono chiamate promozioni intere .48) Tutti gli altri tipi sono invariati dalle promozioni intere.

Problemi correlati