Question

Je sais que vous pouvez juste #define certains entiers, mais pourquoi ne pas C ont un type de données booléen dédié avant C99?

Il est une telle occurence commune dans la programmation et la logique, je ne comprends pas le absense d'un type et la notation explicite.

Était-ce utile?

La solution

Si vous passez un peu de temps dans la bibliothèque, vous n'avez pas à spéculer. Voici quelques déclarations des Dennis papier de Ritchie sur l'évolution de C . Le contexte est que Dennis est construit sur le B de la langue de Ken Thompson, qui a été mis en œuvre sur le PDP-7 très petite, une machine mot adressé. En raison de l'intérêt croissant, le groupe a obtenu un des premiers PDP-11s. Dennis écrit,

  

L'avènement du PDP-11 exposé plusieurs insuffisances du modèle sémantique de B. Tout d'abord, ses mécanismes de traitement des caractères, hérités avec peu de changements de BCPL, étaient maladroits: en utilisant des procédures de bibliothèque pour diffuser des chaînes entassées dans des cellules individuelles, puis remballer, ou pour accéder et remplacer les caractères individuels, a commencé à se sentir maladroit, même stupide, sur un Machine orienté octet.

     

Le modèle B et les frais généraux BCPL implicite dans le traitement des pointeurs: les règles linguistiques, en définissant un pointeur comme un index dans un tableau de mots, forcé pointeurs être représentés comme des indices de mots. Chaque référence de pointeur généré une conversion à grande échelle d'exécution du pointeur à l'adresse de l'octet attendu par le matériel.

     

Pour toutes ces raisons, il semble qu'un système de frappe était nécessaire pour faire face à des caractères et octets d'adressage et de se préparer à l'arrivée du matériel à virgule flottante. D'autres questions, en particulier sécurité de type et vérification interface, ne semblaient pas aussi importants alors qu'ils sont devenus plus tard.

(Non souligné.)

Le document décrit ensuite les luttes de Dennis pour inventer une nouvelle sémantique de pointeur, pour faire des tableaux de travail, et de se réconcilier avec cette idée dernier cri de struct. De type sécurité notions et booléens distinguer des nombres entiers ne semblent pas importants que beaucoup plus tard: -)

Autres conseils

C est en fait un peu plus d'un langage d'assemblage de niveau supérieur. Oui, il a des structures de contrôle et ainsi de suite et il a même eu des types qui assembleur n'a certainement pas besoin.

Mais la langue a été conçu il y a quelques décennies. Et puisque chaque résultat booléen descend à des bits individuels dans le mot d'état du processeur, il était évidemment suffisant pour que l'utilisation d'un type de données intégré pour elle. Et il a fait le compilateur probablement un peu moins complexe puisque vous pouvez omettre quelques vérifications de type (dans les structures de contrôle des langues plus tard besoin une valeur booléenne, en C, ils ont juste besoin d'une valeur intégrale de 0 ou autre chose) .

Il était courant (et est encore dans certains cas) pour traiter zéro faux et tout non nul comme vrai. Cela présente des avantages pour la sténographie. Par exemple, au lieu de while (remaining != 0) vous pouvez simplement utiliser while (remaining)

Certaines langues standardisées sur un véritable être -1. La raison de ceci est que, dans la notation complément à deux (dont la plupart des ordinateurs utilisent pour représenter des nombres négatifs), le niveau du bit, non de 0 est -1 (en binaire, décimal est 11111111 -1 8 bits).

Au fil du temps on a réalisé que l'aide d'une constante définie par le compilateur empêcherait beaucoup de confusion possible. Cela fait un moment que je l'ai fait en C ++, mais je suis assez sûr que toute valeur non nulle évaluera encore « vrai ».

CPU n'a pas de « type booléen », ils ne fonctionnent que sur des octets et des multiples d'entre eux donc un type booléen n'a pas de sens à ce moment-là car il n'a pas donné un avantage (pourquoi utiliser un type lorsque vous ne pouvez vérifier " est 0" ou "est non nul")

Je pense qu'il a été jugé suffisant pour avoir un type entier, 0 étant faux et rien de 0 vrai.

Le type que vous utilisez pour stocker une valeur booléenne (généralement) incarne un compromis entre l'espace et le temps. Vous aurez généralement obtenir les résultats les plus rapides (au moins pour une opération individuelle) en utilisant un int (généralement quatre octets). D'autre part, si vous utilisez très nombreux, il peut faire beaucoup plus logique d'utiliser un octet ou même les emballer de sorte que chaque valeur que vous stockez ne utilise qu'un seul bit - mais quand / si vous faites cela, la lecture ou l'écriture d'un seul bit devient beaucoup plus cher (et utilise le code supplémentaire).

Comme il n'y avait pas de réponse qui était vraiment « droit », ils ont laissé la décision à l'utilisateur de faire en fonction des exigences du programme qu'ils écrivaient.

La vraie question est donc pourquoi un type booléen a été ajouté à C99. Je pense que deux facteurs sont impliqués. Tout d'abord, ils ont réalisé que la lisibilité et la commodité pour le programmeur est maintenant généralement plus importante que de donner la meilleure performance absolue possible. En second lieu, les compilateurs maintenant faire tout à fait un peu une analyse plus globale, il est donc au moins possible de deviner que quelqu'un peut écrire un compilateur qui essaie de choisir une représentation qui est le plus approprié pour un programme particulier (bien que je ne » sais de tout qui fait vraiment).

Old C n'a pas été vraiment « manque » un type booléen - il était juste que tous les types entiers ont été également adaptés pour faire doublement devoir, le stockage booléens. Je vois deux raisons principales:

  • Bit-adressage des processeurs ne sont pas du tout commun (et ne sont toujours pas), de sorte que le compilateur ne serait pas vraiment en mesure d'utiliser un type « true booléen » pour enregistrer un espace - le booléen serait encore être au moins aussi grand comme char de toute façon (si vous espériez y accéder efficacement).

  • Les types plus étroits que int sont élargis à int dans les expressions de toute façon -. De sorte que les opérateurs booléens seraient encore travailler sur opérandes int

.. il ressemble il n'y avait pas un cas assez convaincant qu'un type booléen dédié serait en fait donner des avantages pratiques.

Rappelez-vous que le langage C a un ensemble d'opérateurs qui produisent des résultats booléens (défini comme 0 ou 1) - !, &&, ||, !=, ==, <, <=, > et >= - il est donc seulement type booléen dédié qui est pas là.

Des raisons historiques, sans doute:

CPL, qui a été fortement influencée par Algol, très probablement eu un type booléen, mais mon google-fu ne suffisait pas à trouver une référence pour cela. Mais CPL était trop ambitieux pour son temps, entraînant une version allégée appelée BCPL, qui avait l'avantage que vous pouvez réellement mettre en œuvre sur le matériel disponible.

BCPL n'avait qu'un seul type - le « mot » - qui a été interprété comme faux dans des contextes booléens si 0 et comme vrai si ~0 (ce qui signifie le complément de 0, ce qui représenterait la valeur -1 si elle est interprétée comme complément à deux signés entier). L'interprétation de toute autre valeur a été mise en œuvre dépend.

Après le successeur encore sans type B, C réintroduite un système de type, mais il était encore fortement influencée par la nature de ses prédécesseurs sans type.

Ajout d'un séparé de type « Boolean » qui n'est pas compatible avec les entiers auraient fait le compilateur plus compliqué que d'utiliser simplement des entiers dans le but. Ayant un type booléen qui est compatible avec des nombres entiers, il est nécessaire de préciser les conséquences possibles de stockage d'une valeur autre que 0 ou 1 dans un objet booléenne, ou effectuer des calculs numériques sur un booléen objet dont la représentation ne contient ni la configuration de bits associée à "0" ni "1". Compte tenu:

someBool = intFunction();
someInt = someBool;

exigeant que SomeInt doit recevoir la valeur 1 si intFunction retourne une valeur non nulle serait généralement ce qui précède plus cher que

someChar = intFunction();
someInt = someChar;

Dans les cas où l'ancienne sémantique seraient nécessaires, ils pourraient être atteints sans l'utilisation d'un type booléen, via:

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

Comme tout ce qui peut être fait en utilisant les types booléens peut aussi se faire sans eux, et dans le code beaucoup de cas qui utilise des types de caractères peuvent être plus efficaces que les types booléens, je vous suggère qu'il n'y a jamais eu (et est toujours pas ) besoin réel pour eux.

Parce qu'ils ne sont pas mis un. Désolé si cela semble snippish, mais au fond, il n'a pas été défini comme tel.

Rappelez-vous la plupart des gens #Define VRAI et FAUX.

Vous pouvez dire bool est la norme - mais de toute évidence, il n'a pas été standard avant C99 - qui a été fait il y a 10 ans) Ils ont ajouté alors quand il est devenu évident un élément manquant

.

Parce que nul ne peut tout prévoir, y compris le type de données manquantes dans un langage de programmation.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top