• Empleos
  • Sobre nosotros
  • profesionales
    • Inicio
    • Empleos
    • Cursos y retos
    • Preguntas
    • Profesores
  • empresas
    • Inicio
    • Publicar vacante
    • Nuestro proceso
    • Precios
    • Pruebas Online
    • Nómina
    • Blog
    • Comercial
    • Calculadora de salario

0

449
Vistas
¿La variable de enumeración C (gnu11) no se puede comparar con int?

Esto me parece realmente extraño, y nunca he visto ninguna discusión al respecto en los recursos sobre las enumeraciones de C. La variable a es de tipo enum Direction y puede ser -1, pero a<0 será falso. ¿Qué me estoy perdiendo de las enumeraciones?

 #include <stdio.h> enum Direction {N,W,S,E}; int main() { enum Direction a = N; printf("a is %d\n", a); a--; printf("now a is %d\n", a); printf("but (a<0) is %d\n\n", (a<0)); int b = N; printf("b is %d\n", b); b--; printf("now b is %d\n", b); printf("and (b<0) is %d\n", (b<0)); return 0; }

la salida es

 a is 0 now a is -1 but (a<0) is 0 b is 0 now b is -1 and (b<0) is 1
about 3 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

El tipo subyacente de una enumeración es un tipo entero definido por la implementación que puede representar todos los elementos de la enumeración. Aquí, podría ser char , int , unsigned int (posiblemente otros).

Aparentemente, su implementación eligió usar unsigned int ; es consistente con la comparación con 0 (no puede ser negativo), y solo lo tiene impreso como -1 porque en complemento 2, -1 tiene la misma representación que "el más grande sin signo del mismo ancho" (que es el valor tiene, porque 0 menos 1 sin firmar se ajustará al valor más grande).

Solo se imprime como -1 debido al formato %d de printf, que lo vuelve a convertir a firmado. Pero debido a que no está firmado, debería haber usado %u .

Cuando lo convierte en un entero con signo creando un int var, tiene un int real, por lo que se comporta correctamente (impreso como -1 por el formato %d de printf).

about 3 years ago · Santiago Trujillo Denunciar

0

Depende del tipo de entero seleccionado por el compilador para que sea compatible con el tipo de enumeración. El compilador puede seleccionar un tipo de entero sin signo.

En esta declaración

 printf("now a is %d\n", a);

está utilizando el especificador de conversión %d diseñado para tipos de enteros con signo, aunque la enumeración puede ser compatible con un tipo de entero sin signo y si utiliza el especificador de conversión %u obtendrá otro resultado.

Si, por ejemplo, declara que una constante de enumeración tiene un valor negativo, el compilador seleccionará un tipo de entero con signo como compatible con la enumeración.

Aquí hay dos programas demostrativos que muestran la diferencia.

 #include <stdio.h> int main( void ) { enum Direction {N,W,S,E}; enum Direction a = N; --a; printf( "a < 0 is %d\n", a < 0 ); }

La salida de este programa es

 a < 0 is 0

El compilador seleccionó un tipo de entero sin signo como el tipo de entero compatible.

 #include <stdio.h> int main( void ) { enum Direction {N = -1, W,S,E}; enum Direction a = W; // W is equal to 0 --a; printf( "a < 0 is %d\n", a < 0 ); }

La salida de este programa es

 a < 0 is 1

porque el compilador seleccionó un tipo de entero con signo como el tipo de entero compatible.

Formar el Estándar C (6.7.2.2 Especificadores de enumeración)

4 Cada tipo enumerado debe ser compatible con char, un tipo entero con signo o un tipo entero sin signo . La elección del tipo está definida por la implementación, 128) pero debe ser capaz de representar los valores de todos los miembros de la enumeración. T

Es decir, hay una diferencia entre un tipo de enumeración y una constante de enumeración. Las constantes de enumeración siempre tienen el tipo int . Pero los tipos de enumeración son compatibles con los tipos enteros (con o sin signo) seleccionados por el compilador.

Compare las dos llamadas de printf en este programa de demostración.

 #include <stdio.h> int main( void ) { enum Direction {N,W,S,E}; enum Direction a = N; printf( "a - 1 < 0 is %d\n", a - 1 < 0 ); printf( "N - 1 < 0 is %d\n", N - 1 < 0 ); }

donde esta la salida del programa

 a - 1 < 0 is 0 N - 1 < 0 is 1
about 3 years ago · Santiago Trujillo Denunciar

0

El escollo es su especificador de formato al imprimir a archivo . El especificador de formato %d permite que printf interprete a como un entero con signo, sin importar el tipo de datos que sea en realidad. Pero en realidad, es un entero sin signo, y a-- resultó en un desbordamiento, es decir, a == 4294967295 . Por lo tanto a < 0 es false . Al interpretar este valor como un entero con signo, es -1. Intente usar %u como especificador de formato al imprimir a y verá el valor real de a .

about 3 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Nuestro proceso Comercial
Legal
Términos y condiciones Política de privacidad
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recomiéndame algunas ofertas
Necesito ayuda