7
votes

Cmérologie de la valeur d'expression booléenne

Le langage C n'a pas de type de données booléen, en utilisant des entiers à la place. Comparaison Les opérateurs tels que == et <= renvoient la valeur entière 0 pour false et 1 pour vrai. Toutefois, l'instruction IF en C estime que toute valeur non nulle de sa condition est équivalente à la vraie. Pourquoi la différence? Pourquoi ne pas permettre aux opérateurs relationnels de renvoyer une valeur non nulle pour représenter True?


5 commentaires

En faisant les opérateurs relationnels renvoyer 0 et 1 , la langue permet "Calculs sténographiques": n + = (n% 2 == 0); // incrément n s'il est même ; De plus, la langue prend déjà une valeur non nulle pour représenter TRUE: utilisez-la directement dans des conditions sans opérateurs relationnels.


"Renvoie toute valeur non nulle pour représenter True" - Qu'est-ce qui doit être gagné en la laissant ambiguë? Est-ce que cela fournit plus de flexibilité aux exécutants? Comment pouvaient-ils capitaliser sur cette flexibilité?


C a eu un type de données booléen depuis 15 ans: _bool / bool , défini dans stdbool.h .


C a un type booléen. C'est ce qu'on appelle _bool (aliasé comme bool si vous avez #include ). Il a été ajouté par la norme ISO C de 1999. Mais les opérateurs de comparaison donnent toujours des résultats int .


Principalement basé sur l'opinion, surtout la discussion dans les commentaires à divers postes.


4 Réponses :


0
votes

in c, 0 est false, qu'il s'agisse du type de retour d'un opérateur de comparaison ou d'une instruction IF, ou de ce que vous voulez vérifier. Toutefois, tandis que la déclaration IF () acceptera tout ce qui est vrai que ce n'est pas zéro, les opérateurs de comparaison doivent ne renvoyer qu'un seul objet , et il a donc été décidé que cet objet serait «1». C'est la différence entre que vous retourniez ou acceptez.

Tout comme dans n'importe quelle autre fonction, disons int foo (int x) {} Vous pouvez accepter toute valeur de x, mais vous devez réellement choisir, avant de choisir Laissez la fonction, ce que vous voulez revenir. Je suppose que vous pourriez retourner un nombre aléatoire, mais quel est bon cela faire? '1' a été choisi à la place.


10 commentaires

Oh ... et pourquoi STRCMP () retour Toute valeur négative ou positive lorsque les chaînes sont différentes? :)


Je suis à peu près sûr que cela retourne simplement la différence entre STR1 et STR2, mais pas 100% positif.


@Keiththompson qui n'est pas la question qui a été posée.


@CIPHERMAGI: La standard C indique uniquement que STRCMP () renvoie une valeur négative, 0 ou positive. Ce n'est pas nécessaire que ce soit la différence entre rien - cependant, c'est parfois un moyen pratique de la mettre en œuvre.


@Keiththompson Arrêtez-vous intentionnellement d'interpréter les choses.


@CIPHERMAGI: Je crois que c'est exactement la question qui a été posée: "Pourquoi ne pas permettre aux opérateurs relationnels de renvoyer une valeur non nulle pour représenter la vraie?"


@Keiththompson et j'ai répondu à cette question: parce qu'une valeur devait être choisie, ils ont donc choisi une valeur.


Toute mauvaise interprétation de ma part est entièrement involontaire. Soyez prudent avec les accusations. Une valeur doit être choisie par la norme de langue ou par un compilateur individuel. La question, comme je le vois, c'est pourquoi la langue n'a pas laissé la décision à chaque compilateur, comme cela pourrait l'avoir.


L'ensemble de ce que j'ai dit est que la fonction elle-même ne peut pas simplement décider de manière arbitraire. Le programmeur a dû choisir au moment de la création de la bibliothèque qui a mis en œuvre les opérateurs de comparaison, une sorte de valeur de retour significative. Bien sûr, il aurait pu faire renvoyer une valeur aléatoire entre 1 et la limite binaire du type de retour variable, mais quelle bonne serait-ce que cela ferait?


Laissez-nous Continuer cette discussion en chat



1
votes

Lorsque vous utilisez un opérateur relationnel situé à l'intérieur d'un conditionnel, le compilateur va la compiler dans un "saut si plus grand" ou un opérateur similaire et ne se soucie pas de calculer réellement la valeur de retour de l'expression <= . Peu importe que l'expression renvoie toujours 0 ou 1 parce que cette valeur n'est jamais réellement calculée.

Le seul moment où les opérateurs relationnels de retour de 0 ou 1 sont compatibles lorsque leur valeur est utilisée dans une expression plus grande, comme l'arithmétique ou l'attribution à une variable. Ceci est beaucoup moins commun que la situation de les utiliser directement dans une branche et la commodité de toujours retourner 1 n'est pas très coûteuse.


2 commentaires

<< / code> n'est pas équivalent à la soustraction. Supposons x == int_max et y == int_min .


@KeithThompson: C'est un bon point. Je prenais un peu trop loin l'analogie CMP.



4
votes

Si une expression conditionnelle pourrait renvoyer une valeur non nulle pour true, vous pouvez avoir des problèmes lorsque vous le stockez dans une variable trop petite, dans le cas extrême un bitfield one bit.

struct foo { unsigned int bar: 1; } baz;
baz.bar = 1 == 1;


0 commentaires

6
votes

Je crois que c'était une décision arbitraire, revenant à la langue des ancêtres de C B.

citant le référence des utilisateurs à B : p>

Les opérateurs relationnels (moins de), (inférieur ou égal à), > code> (supérieur à), et > = code> (supérieur ou égal à) prendre des opérandes de rvalue entier. Le résultat est un si les opérandes sont dans la relation donnée les unes aux autres. Le résultat est zéro sinon. P> blockQuote>

aucune explication n'est donnée de ce choix particulier, ni expliqué dans le ANSI C JUSTINE ou dans la 1ère édition de 1978 du livre de Kernighan & Ritchie" The C Programming Language "(K & R1). P>

(langue ancestrale de B BCPL avait vrai code> et false code> littéraux, avec true code> étant représenté avec tous les bits définis sur 1 code>.) p>

Les em> pourraient-ils être définis différemment, et cela aurait toujours été cohérent en interne. Par exemple, la norme aurait pu dire que les opérateurs relationnels et à égalité résultent du résultat de 0 code> si la condition est fausse ou une valeur non nulle arbitraire si la condition est vraie. Le résultat pourrait toujours être utilisé correctement dans un si code> instruction ou tout autre contexte nécessitant une condition. Et il est facile d'imaginer une CPU sur laquelle il est plus efficace d'être représenté comme une valeur réelle comme tous les bits-one plutôt que comme 1 code> - mais la norme de langue ne le permet pas. P>

Plusieurs fonctions de la bibliothèque standard, telles que ISDigit () CODE>, peuvent renvoyer une valeur non nulle arbitraire pour indiquer une condition vraie, ce qui démontre en outre qu'il s'agissait d'un choix arbitraire. ( isdigit code> est naturellement implémenté via une recherche de table pouvant générer des valeurs autres que 0 code> et 1 code>). p>

Il y a Certains plus de commodité ont ajouté que les opérateurs d'égalité et de relation ne rendent 0 code> et 1 code>. Par exemple, cela facilite la conservation du nombre de conditions de nombre de conditions: P>

int count = 0;
count += x == y;
count += foo > bar;
count += this <= that;


0 commentaires