Pregunta

Me doy cuenta de que sólo puede #define algunos números enteros, pero ¿por qué no en C tiene un tipo de datos booleano dedicado antes de C99?

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

¿Fue útil?

Solución

Si vas a gastar un poco de tiempo en la biblioteca, que no tiene que especular. Aquí están algunas declaraciones tomadas de papel Dennis Ritchie en la evolución de C . El contexto es que Dennis está construyendo sobre Ken Thompson lengua B, el cual fue implementado en la muy pequeña PDP-7, una máquina de palabra con su dirección. Debido a la creciente interés, el grupo consiguió uno de los primeros PDP-11s. Dennis escribe:

  

El advenimiento de la PDP-11 expuesto varias insuficiencias del modelo semántico de B. En primer lugar, sus mecanismos de administración de caracteres, heredan con pocos cambios con respecto a BCPL, eran torpes: el uso de procedimientos de la biblioteca para difundir cadenas apiñados en celdas individuales y volver a empaquetar, o para acceder y reemplazar los caracteres individuales, comenzó a sentirse incómodo, incluso tonto, en una máquina orientada bytes.

     

La sobrecarga implícita B y BCPL modelo en el trato con punteros: las reglas del lenguaje, mediante la definición de un puntero como un índice en una matriz de palabras, los punteros obligado a ser representado como índices de palabras. Cada referencia de puntero genera una conversión de la escala de tiempo de ejecución del puntero a la dirección de byte esperado por el hardware.

     

Por todas estas razones, parecía que un esquema de tipificación era necesario para hacer frente a los personajes y direccionamiento de byte, y para prepararse para el hardware de punto flotante que viene. Otras cuestiones, en particular seguridad de tipos y la interfaz de comprobación, no parecía tan importante, entonces ya que se convirtió más tarde.

(énfasis.)

En el documento se pasa a describir las luchas de Dennis inventar una nueva semántica puntero, para hacer arreglos de trabajo, y para ponerse de acuerdo con esta idea novedosos struct. Las nociones de seguridad de tipos y Booleanos distinguen de los números enteros no parecen importantes hasta mucho más tarde: -)

Otros consejos

C es en realidad poco más que un lenguaje de ensamblaje de nivel superior. Sí, se puso estructuras de control y otras cosas e incluso llegó tipos que ensamblador ciertamente no necesita.

Sin embargo, el lenguaje fue diseñado hace décadas. Y puesto que cada resultado booleano se pone manos a bits individuales de la palabra de estado del procesador que, obviamente, era suficiente para usar sólo un tipo de datos integral de la misma. Y se hizo el compilador probablemente un poco menos complejo ya que se puede omitir algunos comprobación de tipos (en las estructuras de control de lenguas posteriores necesidad un valor booleano, en C que sólo tiene un valor entero de 0 ó alguna otra cosa) .

Era común (y sigue siendo en algunos casos) para tratar cero como falso y cualquier no-cero como verdadero. Esto tiene ventajas para la taquigrafía:. Por ejemplo, en lugar de while (remaining != 0) sólo puede utilizar while (remaining)

Algunos lenguajes estandarizados en verdadero ser -1. La razón de esto es que en la notación de complemento a dos (que la mayoría de los equipos utilizan para representar números negativos), el bit a bit-no de 0 es -1 (8-bit binario, 11111111 es decimal -1).

Con el tiempo se dio cuenta de que el uso de una constante definida por el compilador evitaría mucha confusión potencial. Ha sido un tiempo desde que he hecho en C ++, pero estoy bastante seguro de que cualquier valor distinto de cero todavía evaluará "verdadero".

Una CPU no tiene ningún "tipo lógico", que sólo funcionan en bytes y múltiplos de ellos para un tipo booleano no tenía sentido en ese momento, ya que no dio una ventaja (¿por qué utilizar un tipo cuando sólo se puede comprobar " es 0" o "no es nulo")

Sospecho se consideró suficiente para tener un tipo entero, siendo 0 falsa y nada no 0 cierto.

El tipo que se utiliza para almacenar un valor booleano (por lo general) representa una solución de compromiso entre el espacio y el tiempo. Por lo general va a obtener los resultados más rápidos (al menos para una operación individual) mediante el uso de un int (típicamente cuatro bytes). Por otro lado, si usted está utilizando muy muchos, puede hacer mucho más sentido utilizar un byte o incluso empacar por lo que cada valor que se está almacenando usos solamente un único bit - pero cuando / si lo hace, leer o escribir un solo bit pasa a ser sustancialmente más caro (y utiliza el código adicional).

Como no había una respuesta que era realmente "derecho", salieron de la decisión de que el usuario realice en base a los requisitos del programa que estaban escribiendo.

La verdadera pregunta es, entonces, ¿por qué se agregó un tipo booleano en C99. Mi conjetura es que un par de factores están involucrados. En primer lugar, se dieron cuenta de que la legibilidad y comodidad para el programador es ahora por lo general más importante que dar el mejor rendimiento absoluto posible. En segundo lugar, los compiladores ahora hacer un poco de análisis bastante más global, por lo que es al menos posible adivinar que alguien podría escribir un compilador que intenta escoger una representación que es más apropiado para un programa en particular (aunque yo no' sé de ninguna que realmente lo hace).

C vieja no era realmente "falta" un tipo booleano - era sólo que todos los tipos integrales también se consideraron adecuados para hacer doblemente deber, almacenar valores booleanos. Veo dos razones principales para esto:

  • procesadores de bits de direccionamiento no eran en absoluto común (y todavía no), por lo que el compilador no sería realmente capaz de utilizar un tipo "verdadero booleano" para guardar cualquier espacio - el booleano seguiría siendo ser al menos tan grande como una char de todos modos (si usted esperaba para acceder a ella de manera eficiente).

  • Los tipos más estrechos que int se ensanchan a int en las expresiones de todos modos -. Por lo que los operadores booleanos todavía funcionaría sobre operandos int

.. por lo que sólo parece que no fue un caso bastante convincente de que un tipo booleano dedicado en realidad transmitir beneficios prácticos.

Recuerde que el lenguaje C tiene un conjunto de operadores que producen resultados booleanos (definido a ser 0 o 1) - !, &&, ||, !=, ==, <, <=, > y >= - por lo que es una dedicada tipo booleano que no está allí.

Razones históricas, probablemente:

CPL, que fue fuertemente influenciado por Algol, muy 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 época, lo que resulta en una versión reducida llamada BCPL, que tenía la ventaja de que en realidad se podría implementar en hardware disponible.

BCPL sólo tenía un solo tipo - la 'palabra' - que fue interpretado como falsa en contextos booleanas si 0 y tan cierto si ~0 (es decir, el complemento de 0, lo que representaría el -1 valor si se interpreta como firmados complemento a dos entero). La interpretación de cualquier otro valor era dependiente de la implementación.

Después de que el sucesor aún sin tipo B, C volvió a introducir un sistema de tipo, pero todavía estaba fuertemente influenciado por la naturaleza sin tipos de sus predecesores.

Adición de un tipo separado "booleano", que no es compatible con números enteros habrían hecho el compilador más complicado que el simple uso de números enteros para el propósito. Tener un tipo booleano separado que es compatible con números enteros hace que sea necesario especificar las posibles consecuencias de almacenar un valor distinto de 0 o 1 en un objeto Booleano, o la realización de cálculos numéricos en un Boolean objeto cuya representación no contiene ni el patrón de bits asociado con "0" ni "1". Teniendo en cuenta:

someBool = intFunction();
someInt = someBool;

requiriendo que someInt debe recibir el valor 1 si intFunction devuelve cualquier valor distinto de cero sería en general que el anterior más caro que

someChar = intFunction();
someInt = someChar;

En los casos en que serían necesarios los antiguos semántica, podrían lograrse sin el uso de un tipo booleano, a través de:

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

Desde cualquier cosa que se pueda hacer uso de tipos de Boole también se puede hacer sin ellos, y en muchos casos código que utiliza tipos de caracteres pueden ser más eficientes que los tipos de Boole, me gustaría sugerir que nunca hubo (y todavía no es ) ninguna necesidad real para ellos.

Debido a que no pusieron en una. Lo siento si suena snippish, pero básicamente no se definió como tal.

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

Se puede decir bool es estándar - pero obviamente no era estándar antes de C99 - que se hizo hace 10 años;) Se añaden entonces cuando se hizo evidente que falta un elemento

.

Debido a que ninguno puede prever todo tipo de datos que incluye falta de un lenguaje de programación.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top