else - jsp if condition
Embedded C: qué hace var=0xFF; ¿hacer? (9)
Estoy trabajando con C incrustado por primera vez. Aunque mi C está oxidado, puedo leer el código pero realmente no entiendo por qué ciertas líneas son como son. Por ejemplo, quiero saber si una variable es verdadera o falsa y enviarla a otra aplicación. En lugar de establecer la variable a 1 o 0, el implementador original eligió 0xFF.
¿Está tratando de establecerlo en un espacio de direcciones? o bien, ¿por qué establecer una variable booleana para ser 255?
0xFF es la representación hexadecimal de ~ 0 (es decir, 11111111)
En, por ejemplo, VB y Access, -1 se usa como True.
A menudo, en los sistemas integrados hay un programador que escribe todo el código y su idiosincrasia en toda la fuente. Muchos programadores incrustados eran ingenieros de HW y tenían que hacer funcionar un sistema lo mejor que podían. No hubo ningún requisito ni concepto de "portabilidad". Otra consideración en los sistemas integrados es que el compilador es específico para la CPU HW. Consulte el ISA para esta CPU y verifique todos los usos del "booleano".
Aquí hay una razón probable: 0xff
es el complemento binario de 0
. Puede ser que en su arquitectura integrada, almacenar 0xff
en una variable sea más eficiente que almacenar, digamos 1
, lo que podría requerir instrucciones adicionales o una constante almacenada en la memoria.
O tal vez la forma más eficiente de verificar el "valor de verdad" de un registro en su arquitectura es con una instrucción "verificar bits de bits". Con 0xff
como el valor VERDADERO, no importa qué bit se verifique ... están todos configurados.
Lo anterior es solo una especulación, por supuesto, sin saber qué tipo de procesador integrado estás usando. 8 bits, 16 bits, 32 bits? PIC, AVR, ARM, x86 ???
(Como otros han señalado, cualquier valor entero distinto de cero se considera VERDADERO a los efectos de las expresiones booleanas en C.)
Como han dicho otros, está configurando todos los bits en 1. Y dado que esto está incrustado en C, puede que esté almacenando esto en un registro donde cada bit es importante para algo, por lo que desea establecerlos todos en 1. Sé que lo hice similar al escribir en ensamblador.
Lo que es realmente importante saber sobre esta pregunta es el tipo de "var". Dices "boolean", pero ¿es ese un bool de C ++ / C99, o es (muy probablemente, una aplicación C incrustada), algo completamente diferente que se usa como booleano?
Si necesita desesperadamente memoria, es posible que desee almacenar 8 booleanos en un byte (o 32 en un largo, o lo que sea)
Esto se puede hacer fácilmente usando una máscara de bandera:
// FLAGMASK = ..1<<n for n in 0..7...
FLAGMASK = 0x10; // e.g. n=4
flags &= ~FLAGMASK; // clear bit
flags |= FLAGMASK; // set bit
flags ^= FLAGMASK; // flip bit
flags = (flags & ~FLAGMASK) | (booleanFunction() & FLAGMASK); // clear, then maybe set
esto solo funciona cuando booleanFunction () devuelve 0 (todos los bits son claros) o -1 (todos los bits configurados).
Además, al agregar de 1 a 0xff, se establece en 0 (suponiendo que no está firmado) y la comprobación podría haber estado en un bucle con un incremento para romper.
Estos chicos jóvenes, ¿qué saben ellos?
En uno de los idiomas incrustados originales - PL / M (-51 sí como en 8051, -85, -86, -286, -386) - no hubo diferencia entre los operadores lógicos (!, &&, || en C) y bitwise (~, &, |, ^). En cambio, PL / M tiene NOT, AND, OR y XOR para ambas categorías. ¿Estamos mejor con dos categorías? No estoy muy seguro. Extraño el operador lógico ^^ (xor) en C, sin embargo. Aún así, supongo que sería posible construir programas en C sin tener que involucrar la categoría lógica.
En PL / M, False se define como 0. Los booleanos generalmente se representan en variables de bytes. True se define como NOT False, que le dará 0ffh (PL / M-ese para C''s 0xff).
Para ver cómo se llevó a cabo la conversión del indicador de estado, por lo que se almacenó en una variable de byte (boolean no disponible como tipo), PL / M podría usar las instrucciones de ensamblaje "sbb al, al" antes de almacenar. Si se estableciera carry, al contendría 0ff, si no fuera así, contendría 0h. Si se requiriera el valor opuesto, PL / M insertaría un "cmc" antes del sbb o anexaría un "no al" después (en realidad xor - uno u otro).
Entonces el 0xff para TRUE es un puerto de compatibilidad directa desde PL / M. ¿Necesario? Probablemente no, a menos que no esté seguro de sus habilidades (en C) Y jugando de forma súper segura.
Como lo hubiera hecho.
PL / M-80 (usado para 8080, 8085 y Z80) no tenía soporte para enteros o flotadores, y sospecho que fue el mismo para PL / M-51. PL / M-86 (usado para los 8086, 8088, 80188 y 80186) números enteros añadidos, punto flotante de precisión simple, punteros de desplazamiento de segmento: y los modelos de memoria estándar pequeños, medianos, compactos y grandes. Para aquellos que lo deseaban, había directivas especiales para crear modelos híbridos de memoria hágalo usted mismo. El enorme modelo de memoria de Microsoft era equivalente al de Intel. MS también lucía modelos pequeños, pequeños, compactos, medianos y grandes.
0xFF
establece todos los bits en un char.
El implementador original probablemente decidió que el estándar 0
y 1
no era lo suficientemente bueno y decidió que si todos los bits desactivados son falsos, entonces todos los bits encendidos son verdaderos .
Eso funciona porque en C cualquier valor que no sea 0 es verdadero. Aunque esto configurará todos los bytes en una char, también funcionará para cualquier otro tipo de variable, ya que cualquier bit que se configure en una variable lo hace verdadero.