2011-07-09 8 views
6

Digamos que tengo los siguientes escenarios:¿Cuáles son las reglas generales para comparar diferentes tipos de datos en C?

int i = 10; 
short s = 5; 

if (s == i){ 
    do stuff... 
} else if (s < i) { 
    do stuff... 
} 

Cuando C hace la comparación no es convertir el tipo de datos más pequeño, en este caso corto a int o se convierte el tipo de datos a la derecha al tipo de datos ¿a la izquierda? En este caso int to short?

+3

En C, la regla general es * por favor no hagas eso *. Pero el 'corto 'se promocionaría a un' int' en su ejemplo. –

Respuesta

8

Esto se rige por las conversiones aritméticas habituales. Para casos simples, la regla general es que el tipo con "menos" precisión se convierte para que coincida con el tipo con "más" precisión, pero se vuelve algo complejo una vez que comienzas a mezclar signed y unsigned.

En C99, esto se describe en la Sección 6.3.1.8, que incluyo aquí para su conveniencia:

  • En primer lugar, si el tipo de bienes correspondiente de alguno de los operandos es long double, el otro operando se convierte, sin cambio de tipo de dominio, a un tipo cuyo tipo real correspondiente es long double.

  • De lo contrario, si el tipo de bienes correspondiente de cualquiera de los operandos es double, el otro operando se convierte, sin cambio de dominio tipo, a un tipo cuyo correspondiente tipo real es double.

  • De lo contrario, si el tipo de bienes correspondiente de cualquiera de los operandos es float, el otro operando se convierte, sin cambio de dominio tipo, a un tipo cuyo correspondiente tipo real es float.

  • De lo contrario, las promociones enteras se realizan en ambos operandos. Entonces las siguientes reglas se aplican a la operandos promovidas:

    • Si ambos operandos tienen el mismo tipo, a continuación, ninguna conversión adicional es necesario.
    • lo contrario, si los dos operandos han firmado tipos de enteros o ambos tienen tipos de enteros sin signo, el operando con el tipo de menor número entero rango de conversión se convierte en el tipo del operando con mayor rango.
    • De lo contrario, si el operando que tiene tipo entero sin signo tiene rango mayor o igual que el rango del tipo del otro operando, entonces el operando con el tipo entero con signo se convertida al tipo del operando con tipo entero sin signo.
    • De lo contrario, si el tipo del operando con el tipo entero con signo puede representar todos los valores del tipo del operando con unsigned tipo número entero , a continuación, el operando con unsigned tipo entero se convierte en del tipo de el operando con tipo entero firmado.
    • De lo contrario, ambos operandos se convierten al entero sin signo tipo correspondiente al tipo del operando con tipo de entero con signo.

He destacado la parte que se aplica a su caso particular.

El concepto escala de conversión entera se define en la sección 6.3.1.1, y básicamente describe lo que cabría esperar (los tipos con menos precisión tienen un rango inferior que los tipos con más precisión).

5

De Type Conversions:

El conjunto de conversiones implícitas en la página 44, aunque de manera informal indicó, es exactamente el conjunto de recordar por ahora. Son fáciles de recordar si se observa que, como dicen los autores, the `lower' type is promoted to the `higher' type,'' where the fin '' de los tipos es

char < short int < int < long int < float < double < long double 

Esa regla es fácil de recordar - "menor a mayor" -, pero Con respecto firmados y tipos de enteros sin signo no ayuda mucho, los explican muy bien en la publicación de Oli. Pero es fácil de recordar y te ayuda en la mayoría de los casos.

+0

¿Cómo encaja 'unsigned' allí? es '-1' menor que' 2U'? – pmg

+0

Tienes razón, es solo parte de la historia completa. Tomaré esto en cuenta. – emboss

+0

+1: los signos realmente deberían ser '<=' y, en C99, hay 'largo largo int' para agregar a la confusión :) – pmg

2

Como regla general, C no comparará dos valores si no son del mismo tipo y nunca convertirá implícitamente una variable a un tipo con menos precisión. En el código de ejemplo, la short es promovido a un int, que es equivalente a la escritura:

int i = 10; 
short s = 5; 

if ((int)s == i){ 
    do stuff... 
} else if ((int)s < i) { 
    do stuff... 
} 

esto va a hacer exactamente lo que esperas, pero el mismo no es cierto en comparación firmado/sin signo.

1

Los tipos de datos son una abstracción de géneros .. en lo que respecta a la computadora no hay int o short. Hay memoria y hay datos.

Cuando dices int x, le estás diciendo a una computadora "dame suficientes bytes para almacenar un int", cuando dices short y, estás diciendo ... lo adivinaste.

short, como era de esperar toma menos bytes que int y por lo tanto puede (y a menudo lo hace) contener datos en los bytes adyacentes. Al comparar datos de diferentes tipos, el problema es "¿los bits adyacentes causarán resultados sesgados o no?"

Siempre que compare dos tipos de datos diferentes, realmente compara los bits almacenados en dos ubicaciones diferentes. El número máximo de bits individuales almacenados para representar los datos debe ser del mismo tamaño para que funcione una comparación

Casting para ayudar con esto.

Cuestiones relacionadas