valores tipos que programacion logicos logica ejemplos ejemplo definicion datos caracter booleanos booleano c language-design c99 c89

que - tipos de datos caracter



¿Por qué C no tenía un tipo de datos booleano antes de C99? (11)

Me doy cuenta de que simplemente puede #define algunos enteros, pero ¿por qué C no tenía un tipo de datos booleano dedicado antes de C99?

Es una ocurrencia tan común en la programación y la lógica, que no entiendo la ausencia de un tipo y notación explícitos.


Agregar un tipo "booleano" separado que no sea compatible con enteros habría complicado el compilador más que el simple uso de enteros para tal fin. Tener un tipo booleano diferente que sea compatible con enteros hace que sea necesario especificar las posibles consecuencias de almacenar un valor distinto de 0 o 1 en un objeto booleano o realizar cálculos numéricos en un objeto booleano cuya representación no contenga el patrón de bits asociado con " 0 "ni" 1 ". Dado:

someBool = intFunction(); someInt = someBool;

requiriendo que someInt debe recibir el valor 1 si intFunction devuelve cualquier valor distinto de cero generalmente haría que lo anterior fuera más caro que

someChar = intFunction(); someInt = someChar;

En los casos en que se requiera la semántica anterior, podrían lograrse sin el uso de un tipo booleano, a través de:

someChar = !!intFunction(); someInt = someChar;

Como todo lo que se puede hacer usando tipos booleanos también se puede hacer sin ellos, y en muchos casos el código que usa tipos de caracteres puede ser más eficiente que los tipos booleanos, sugeriría que nunca hubo (y todavía no existe) necesidad de ellos.


C es en realidad poco más que un lenguaje ensamblador de alto nivel. Sí, tiene estructuras de control y todo eso e incluso tiene tipos que el ensamblador ciertamente no necesita.

Pero el lenguaje fue diseñado hace décadas. Y dado que cada resultado booleano se reduce a bits individuales en la palabra de estado del procesador, obviamente fue suficiente con solo usar un tipo de datos integral para él. Y hizo el compilador probablemente un poco menos complejo ya que puede omitir alguna verificación de tipo (en los lenguajes posteriores las estructuras de control necesitan un valor booleano, en C solo necesitan un valor integral de 0 o algo más).


El tipo que usa para almacenar un booleano (por lo general) representa una compensación entre el espacio y el tiempo. Por lo general, obtendrá los resultados más rápidos (al menos para una operación individual) utilizando un int (generalmente cuatro bytes). Por otro lado, si está usando muchas, puede tener mucho más sentido usar un byte o incluso empaquetarlas para que cada valor que esté almacenando solo use un solo bit, pero cuando / si lo hace, leer o escribir un solo bit se vuelve sustancialmente más caro.

Dado que no había una sola respuesta que fuera realmente "correcta", dejaron la decisión al usuario para hacerla según los requisitos del programa que estaban escribiendo.

La verdadera pregunta, entonces, es por qué se agregó un tipo booleano en C99. Creo que hay un par de factores involucrados. En primer lugar, se dieron cuenta de que la conveniencia para el programador ahora es más importante que ofrecer el mejor rendimiento posible. En segundo lugar, los compiladores ahora hacen un análisis bastante más global, por lo que al menos es posible adivinar que alguien podría escribir un compilador que intente elegir una representación que sea más apropiada para un programa en particular (aunque no conozco ninguna que realmente lo haga). )


El viejo C realmente no "faltaba" un tipo booleano; era simplemente que todos los tipos integrales también se consideraban adecuados para cumplir doble función, almacenando booleanos. Puedo ver dos razones principales para esto:

  • Los procesadores de direccionamiento de bits no eran en absoluto comunes (y aún no lo son), por lo que el compilador no podría usar realmente un tipo "booleano verdadero" para guardar ningún espacio: el booleano aún sería al menos tan grande como un char todos modos (si esperabas acceder de manera eficiente).

  • Los tipos más estrechos que int se amplían a int en las expresiones de todos modos, por lo que los operadores booleanos seguirían trabajando en los operandos int .

... así que parece que no había un caso lo suficientemente convincente como para que un tipo booleano dedicado realmente transmitiera beneficios prácticos.

Recuerde que el lenguaje C tiene un conjunto de operadores que producen resultados booleanos (definidos como 0 o 1) - ! , && , || , != , == , < , <= , > y >= - entonces solo es un tipo booleano dedicado que no está allí.


Era común (y todavía lo es en algunos casos) tratar el cero como falso y cualquier otro que no sea cero como verdadero. Esto tiene ventajas para la taquigrafía: por ejemplo, en lugar de while (remaining != 0) , puede usar simplemente while (remaining) .

Algunos lenguajes estandarizados en el ser verdadero -1. La razón para esto es que en la notación de dos complementos (que la mayoría de las computadoras usan para representar números negativos), el bitwise-not de 0 es -1 (en binario de 8 bits, 11111111 es decimal -1).

Con el tiempo, se descubrió que el uso de una constante definida por el compilador evitaría una gran confusión potencial. Ha pasado un tiempo desde que hice C ++, pero estoy bastante seguro de que cualquier valor distinto de cero evaluará "verdadero".


Porque ninguno puede prever todo, incluido el tipo de datos faltante en un lenguaje de programación.


Porque no pusieron uno. Lo siento si eso suena raro, pero básicamente no fue definido como tal.

Recuerde que la mayoría de las personas # define VERDADERO y FALSO.

Se puede decir que bool es estándar, pero obviamente no era estándar antes de C99, que se fabricó hace 10 años;) Lo agregaron cuando se hizo evidente que faltaba un artículo.


Razones históricas, probablemente:

CPL, que fue fuertemente influenciado por ALGOL, probablemente tenía un tipo booleano, pero mi google-fu no fue suficiente para encontrar una referencia para esto. Pero CPL era demasiado ambicioso para su tiempo, lo que resultó en una versión simplificada llamada BCPL, que tenía el beneficio de que realmente podría implementarlo en el hardware disponible.

BCPL solo tenía un tipo único - la ''palabra'' - que se interpretó como falso en contextos booleanos si 0 y como verdadero si ~0 (es decir, el complemento de 0 , que representaría el valor -1 si se interpreta como un entero de dos dígitos completado ) La interpretación de cualquier otro valor dependía de la implementación.

Después del sucesor aún sin letra B, C reintrodujo un sistema de tipo, pero todavía estaba muy influenciado por la naturaleza sin tipo de sus predecesores.


Si pasas un tiempo en la biblioteca, no tienes que especular. Aquí hay algunas declaraciones tomadas del artículo de Dennis Ritchie sobre la evolución de C. El contexto es que Dennis está construyendo sobre el lenguaje B de Ken Thompson, que se implementó en el minúsculo PDP-7, una máquina con palabra escrita. Debido al creciente interés, el grupo obtuvo uno de los primeros PDP-11. Dennis escribe,

El advenimiento del PDP-11 expuso varias deficiencias del modelo semántico de B. Primero, sus mecanismos de manejo de caracteres, heredados con pocos cambios de BCPL, eran torpes: el uso de procedimientos de biblioteca para separar cadenas empaquetadas en celdas individuales y luego reempaquetar, o para acceder y reemplazar caracteres individuales, comenzó a parecer incómodo, incluso tonto, en una máquina orientada a bytes.

El modelo B y BCPL implicaba una sobrecarga en el manejo de punteros: las reglas del lenguaje, al definir un puntero como un índice en una matriz de palabras, los punteros forzados se representan como índices de palabras. Cada referencia de puntero generaba una conversión de escala de tiempo de ejecución desde el puntero a la dirección de bytes que esperaba el hardware.

Por todos estos motivos, parecía que era necesario un esquema de tipado para hacer frente al direccionamiento de caracteres y bytes, y para prepararse para el próximo hardware de coma flotante. Otros problemas, particularmente la seguridad de tipo y la comprobación de interfaz, no parecían tan importantes como lo fueron después.

(Énfasis mío)

El documento continúa describiendo las luchas de Dennis para inventar una nueva semántica de punteros, hacer que las matrices funcionen y llegar a un acuerdo con esta nueva idea de struct . Las nociones de seguridad tipográfica y distinguir booleanos de enteros no parecían importantes hasta mucho más tarde :-)


Sospecho que se consideró suficiente tener un tipo de entero, 0 es falso y nada 0 verdadero.


Una CPU no tiene "tipo booleano", solo funcionan en bytes y múltiplos de ellos, por lo que un tipo booleano no tenía sentido en ese momento, ya que no daba una ventaja (¿por qué usar un tipo cuando solo se puede marcar "es 0"? o "no es nulo")