Pergunta

Eu sei que você pode apenas #define alguns inteiros, mas por que não c têm um tipo de dados booleano dedicado antes C99?

É uma ocorrência tão comum na programação e lógica, eu não entendo a ausência de um tipo explícito e notação.

Foi útil?

Solução

Se você gastar um pouco de tempo na biblioteca, você não tem que especular. Aqui estão algumas declarações tiradas de papel Dennis Ritchie sobre a evolução da C . O contexto é que Dennis está construindo sobre a linguagem B de Ken Thompson, que foi implementado no muito pequeno PDP-7, uma palavra-endereçado máquina. Por causa do crescente interesse, o grupo recebeu uma das primeiras PDP-11s. Dennis escreve,

O advento dos PDP-11 expostos várias insuficiências do modelo semântico da B. Primeiro, seus mecanismos de manipulação de caráter, herdados com poucas mudanças de BCPL, eram desajeitados: usando procedimentos de biblioteca para propagação embalado cordas em células individuais e, em seguida, reembalar, ou para acesso e substituir caracteres individuais, começou a se sentir estranho, mesmo bobo, em uma máquina orientado de byte.

O modelo B e BCPL implícita sobrecarga em lidar com ponteiros: as regras de linguagem, através da definição de um ponteiro como um índice em uma matriz de palavras, ponteiros para ser representados como índices palavra forçado. Cada referência ponteiro gerada uma conversão de escala de tempo de execução do ponteiro para o endereço de byte esperado pelo hardware.

Por todas estas razões, parecia que um esquema de tipagem era necessário para lidar com personagens e endereçamento de byte, e se preparar para o hardware de ponto flutuante que vem. Outras questões, particularmente tipo de segurança e interface de verificação, não parecia tão importante, em seguida, à medida que se tornou mais tarde.

(grifo meu).

O papel continua a descrever a luta de Dennis de inventar uma nova semântica ponteiro, para fazer matrizes de trabalho, e para chegar a um acordo com essa idéia struct newfangled. Noções de segurança de tipo e distinguir Booleans de inteiros não parecia importante até muito mais tarde: -)

Outras dicas

C é realmente pouco mais do que uma linguagem de montagem de nível superior. Sim, ele tem estruturas de controle e outros enfeites e até mesmo tipos que assembler certamente não precisa tem.

Mas a linguagem foi projetada décadas atrás. E uma vez que cada resultado boolean fica para baixo em pedaços individuais na palavra de estado do processador, obviamente, foi suficiente para usar apenas um tipo de dados integral para ele. E isso fez o compilador provavelmente um pouco menos complexa, pois você pode omitir algum tipo de verificação (em línguas posteriores controlar estruturas necessidade um valor booleano, em C eles só precisam de um valor inteiro de 0 ou qualquer outra coisa) .

Era comum (e ainda é em alguns casos) para tratar zero como falso e qualquer diferente de zero como verdadeiro. Isto tem vantagens para taquigrafia:. Por exemplo, em vez de while (remaining != 0) você pode apenas usar while (remaining)

Alguns idiomas padronizado em verdadeiro ser -1. A razão para isto é que, em dois complementos notação (a maioria dos computadores que utilizam para representar números negativos), o bit a bit, e não é de 0 -1 (em binário de 8 bits, é 11111111 decimal -1).

Com o tempo percebeu-se que o uso de uma constante definida pelo compilador iria evitar uma série de possíveis confusões. Tem sido um tempo desde que eu fiz C ++, mas estou bastante certeza de que qualquer valor diferente de zero ainda vai avaliar "verdadeiro".

A CPU não tem "tipo boolean", eles só funcionam em bytes e múltiplos de-los para um tipo boolean não faziam sentido naquele tempo como ele não deu uma vantagem (por que usar um tipo quando você só pode verificar " é 0" ou "não é nulo")

Eu suspeito que foi considerado suficiente para ter um tipo inteiro, com 0 sendo falso e qualquer coisa que não 0 verdadeiro.

O tipo que você usa para armazenar um valor booleano (geralmente) incorpora um trade-off entre o espaço eo tempo. Você normalmente vai obter os resultados mais rápidos (pelo menos para uma operação individual) usando um int (normalmente quatro bytes). Por outro lado, se você estiver usando muitos, ele pode fazer muito mais sentido usar um byte ou mesmo embalá-los de modo que cada valor que você está armazenando usa apenas um único bit - mas quando / se você fizer isso, ler ou escrever um único bit torna-se substancialmente mais caro (e usa código extra).

Uma vez que não havia uma resposta que era realmente "direita", eles deixaram a decisão para o usuário faça com base nos requisitos do programa que estavam escrevendo.

A verdadeira questão, então, é por isso que um tipo booleano foi introduzido no C99. Meu palpite é que um par de fatores estão envolvidos. Primeiro, eles perceberam que a legibilidade e conveniência para o programador agora é geralmente mais importante do que dar o melhor desempenho absoluto possível. Em segundo lugar, compiladores agora fazer um pouco de análise bastante mais global, por isso é pelo menos possível adivinhar que alguém pode escrever um compilador que tenta pegar uma representação que é mais apropriado para um determinado programa (embora I don' t sei de nenhum que realmente faz).

Old C não era realmente "perdido" um tipo de boolean - era apenas que todos os tipos integrais também foram considerados adequados para fazer duplamente dever, armazenar booleans. Vejo duas razões principais para isso:

  • processadores de endereçamento de bits não foram em todos os comum (e ainda não são), então o compilador não seria realmente capaz de usar um tipo de "verdade boolean" para salvar qualquer espaço - o boolean seria ainda ser pelo menos tão grande como um char qualquer maneira (se você esperava para acessá-lo de forma eficiente).

  • Tipos mais estreitas do que int são alargadas para int em expressões de qualquer maneira -. Por isso os operadores booleanos seria ainda trabalho em operandos int

.. por isso só parece que não foi um caso convincente o suficiente para que um tipo booleano dedicado seria realmente transmitir benefícios práticos.

Lembre-se que a linguagem C tem um conjunto de operadores que produzem resultados booleanos (definida para ser 0 ou 1) - !, &&, ||, !=, ==, <, <=, > e >= - por isso é apenas uma tipo booleano dedicado que não está lá.

Razões históricas, provavelmente:

CPL, que foi fortemente influenciado por ALGOL, provavelmente tinha um tipo boolean, mas meu google-fu não era suficiente para encontrar uma referência para isso. Mas CPL era demasiado ambicioso para a época, resultando em um despojado-down versão chamada BCPL, que teve o benefício que você realmente pode implementá-lo em hardware disponível.

BCPL só tinha um único tipo - a 'palavra' - que foi interpretado como falso em contextos boolean se 0 e como verdadeiro se ~0 (ou seja, o complemento de 0, o que representaria o valor -1 se interpretada como assinados dois complementos número inteiro). A interpretação de qualquer outro valor era dependente de implementação.

Após a ainda não tipificado sucessor B, C reintroduzido um sistema tipo, mas que ainda foi fortemente influenciado pela natureza não tipificado dos seus antecessores.

Adicionando um tipo separado "booleano" que não é compatível com inteiros teria feito o compilador mais complicado do que simplesmente usar inteiros para o efeito. Ter um tipo booleano separado, que é compatível com inteiros torna necessário especificar as possíveis consequências de armazenar um valor diferente de 0 ou um para um objecto booleano, ou realizando cálculos numéricos sobre um Booleano objeto cuja representação não contém nem o padrão de bits associados com "0" nem "1". Dado:

someBool = intFunction();
someInt = someBool;

exigindo que someInt deve receber o valor 1 se intFunction retorna qualquer valor diferente de zero, em geral, fazer o acima mais caro do que

someChar = intFunction();
someInt = someChar;

Nos casos em que os ex-semântica seriam necessários, eles poderia ser alcançado sem o uso de um tipo booleano, via:

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

Uma vez que tudo o que pode ser feito usando tipos booleanos também pode ser feito sem eles, e em código muitos casos que utiliza tipos de caracteres pode ser mais eficiente do que os tipos booleanos, eu sugiro que nunca houve (e ainda não é ) nenhuma necessidade real para eles.

Não é porque eles fizeram colocar um no. Desculpe se isso soa snippish, mas basicamente não foi definido como tal.

Lembre-se a maioria das pessoas #define TRUE e FALSE.

Você pode dizer bool é padrão - mas, obviamente, não era padrão antes de C99 - o que foi feito há 10 anos;). Eles acrescentaram que, em seguida, quando se tornou um item em falta óbvia

Porque ninguém pode prever tudo, inclusive faltando tipo de dados em uma linguagem de programação.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top