93 votes

La norme C indique-t-elle explicitement que la valeur de la vérité est 0 ou 1?

Nous savons que tous les nombres qui ne sont pas égaux à 0 sont considérés comme true en C, nous pouvons donc écrire:

 int a = 16;

while (a--)
    printf("%d\n", a);  // prints numbers from 15 to 0
 

Cependant, je me demandais si vrai / faux sont définis comme 1 - 0 en C, alors j'ai essayé le code ci-dessous:

 printf("True = %d, False = %d\n", (0 == 0), (0 != 0));  // prints: True = 1, False = 0
 

La norme C indique-t-elle explicitement les valeurs de vérité de vrai et faux en tant que 1 et 0 respectivement?

102voto

haccks Points 33022

Le C standard indiquer explicitement la vérité des valeurs de true et false comme 0 et 1 respectivement?

La norme définit true et false sous forme de macros en stdbool.h qui augmentent à l' 1 et 0 respectivement.

C11-§7.18:

Les trois autres macros sont adaptés pour une utilisation en #if de prétraitement des directives. Ils sont

true

qui s'étend de la constante entière 1,

false

qui s'étend de la constante entière 0 [...]

Les exploitants, == et !=

C11-§6.5.9/3:

L' == (égal à) et != (pas égal à) les opérateurs sont analogues aux opérateurs relationnels à l'exception de leur priorité inférieure.108) , Chacun des exploitants des rendements en 1 si le rapport est vrai et 0 si elle est fausse. Le résultat est de type int. Pour toute paire d'opérandes, exactement une des relations est vrai.

52voto

KennyTM Points 232647

Il n'est pas explicitement indiqué dans le C11. Tous langue niveau des opérations sera de retour 1 comme truthy (et accepter toute différente de zéro, y compris NaN comme vrai).

  • Si vous en êtes inquiet à propos de _Bool, alors vrai doit être de 1 parce que la norme seulement besoin de tenir des 0 et des 1. (§6.2.5/2).
  • Aussi, en <stdbool.h> la macro true s'étend à d' 1 (§7.18/3)
  • ==, !=, <, >, <= et >= return 0 ou 1 (§6.5.8/6, §6.5.9/3).
  • !, && et || return 0 ou 1 (§6.5.3.3/5, §6.5.13/3, §6.5.14/3)
  • defined s'étend de 0 ou de 1 (§6.10.1/1)

Mais toutes les fonctions de bibliothèque standard par exemple, islower il suffit de dire "non nulle" pour truthy (par ex. §7.4.1/1, §7.17.5.1/3, §7.30.2.1/1, §7.30.2.2.1/4).


§6.2.5/2: Un objet déclaré comme étant de type _Bool est assez grand pour stocker les valeurs 0 et 1.

§6.5.5.3/5: Le résultat de la négation logique de l'opérateur ! est 0 si la valeur de son opérande compare inégale à 0, 1 si la valeur de son opérande compare égal à 0. ...

§6.5.8/6: Chacun des opérateurs < (moins de), > (plus grand que), <= (inférieur ou égal), et >= (supérieur ou égal à) donnera 1 si la relation est vraie et 0 si elle est fausse.107) ...

§6.5.9/3: L' == (égal à) et != (pas égal à) les opérateurs sont analogues aux opérateurs relationnels à l'exception de leur priorité inférieure.108), Chacun des exploitants des rendements de 1 si la relation est vraie et 0 si elle est fausse. ...

§6.5.13/3: L' && - opérateur de donne 1 si les deux opérandes de comparer l'inégalité 0; ...

§6.5.14/3: L' || - opérateur de rendement 1 si l'un de ses opérandes de comparer l'inégalité 0; ...

§6.10.1/1: ... il peut contenir de l'opérateur unaire expressions de la forme - defined identifier - ou - defined ( identifier ) - qui évalue à 1 si ...

§7.4.1 (Caractère de classification des fonctions)/1: Les fonctions de ce sous-alinéa retour différent de zéro (vrai) si et seulement si ...

§7.18/3: Les trois autres macros sont adaptés pour une utilisation en #if de prétraitement des directives. Ils sont - true - qui s'étend de la constante entière 1, ...

§7.17.5.1/3: L' atomic_is_lock_free générique la fonction retourne une valeur non nulle (vrai) si et seulement si l'objet de la opérations sont sans verrouillage. ...

§7.30.2.1 (caractère Large de la classification des fonctions)/1: Les fonctions de ce sous-alinéa retour différent de zéro (vrai) si et seulement si ...

§7.30.2.2.1/4: L' iswctype de la fonction retourne une valeur non nulle (vrai) si et seulement si ...

23voto

paxdiablo Points 341644

Il y a deux zones de la norme, vous devez être conscient lorsque vous traitez avec des valeurs Booléennes (je veux dire le vrai/faux des valeurs plutôt que sur les C bool/_Bool type) en C.

La première a à voir avec le résultat des expressions et peuvent être trouvés dans différentes parties de la C11 6.5 Expressions (relationnel et de l'égalité des opérateurs, par exemple) . La ligne de fond est que, chaque fois qu'une valeur de type Boolean est généré par une expression, il est ...

... les rendements de 1 si la relation est vraie et 0 si elle est fausse. Le résultat est de type int.

Donc, oui, le résultat de tout Boolean-la génération de l'expression sera un pour de vrai, ou zéro pour de faux. Cela correspond à ce que vous trouverez en stdbool.h où la norme macros true et false sont définies de la même manière.

Gardez cependant à l'esprit que, à la suite de la robustesse du principe de "être prudent dans ce que vous envoyez, libéral dans ce que vous acceptez", l'interprétation des nombres entiers dans le contexte Booléen est un peu plus détendu.

Encore une fois, à partir de différentes parties de l' 6.5, vous allez voir la langue comme:

L' || - opérateur de rendement 1 si l'un de ses opérandes de comparer l'inégalité à 0; sinon, il donne de 0. Le résultat est de type int.

De ce que (et d'autres pièces), il est évident que le zéro est considérée comme fausse et toute autre valeur est true.


Comme une part, le langage de spécification de quelle valeur sont utilisés pour Booléenne génération et l'interprétation apparaissent également de retour en C99 et C89 de sorte qu'ils ont été autour depuis un certain temps. K&R (ANSI-C deuxième édition et la première édition) a précisé que, avec des segments de texte tels que:

Relationnel des expressions comme i > j et expressions logiques reliés par && et || sont définies de la valeur 1 si la valeur est true, et 0 si la valeur est false.

Dans la partie test de if, while, for, etc, "true" signifie simplement "non nulle".

L' && opérateur ... retourne 1 si les deux ses opérandes de comparer non égale à zéro, 0 sinon.

L' || opérateur ... retourne 1 si l'un de ses opérandes comparer non égale à zéro, et 0 sinon.

Les macros en stdbool.h apparaissent en arrière en C99, mais pas en C89 ou K&R depuis ce fichier d'en-tête n'existe pas à ce point.

10voto

Lundin Points 21616

Vous mélangez beaucoup de choses différentes: des instructions de contrôle, les opérateurs booléens et de types. Chacun ont leurs propres règles.

Les instructions de contrôle du travail, comme par exemple l' if déclaration, C11 6.4.8.1:

Dans les deux formes, la première substatement est exécutée si l'expression compare inégale à 0.

while, for etc ont la même règle. Cela n'a rien à voir avec le "vrai" ou "faux".

Comme pour les opérateurs qui sont soi-disant en produisant un résultat booléen, ils sont réellement, ce qui donne un int de la valeur 1 ou 0. Par exemple, les opérateurs d'égalité, C11 6.5.9:

Chacun des opérateurs des rendements de 1 si la relation est vraie et 0 si elle est fausse

Tous les ci-dessus est parce que C n'ont pas de type booléen jusqu'à l'année 1999, et même lorsqu'il n'a en obtenir un, les règles ci-dessus n'ont pas changé. Donc, contrairement à la plupart des autres langages de programmation où les états et les opérateurs de rendement d'un type booléen (comme C++ et Java), ils ont juste donner un int, avec une valeur nulle ou non nulle. Par exemple, sizeof(1==1) donnera 4 en C, mais 1 en C++.

La réelle type booléen en C est nommé _Bool et nécessite un compilateur moderne. L'en-tête stdbool.h définit les macros bool, true et false, que l'élargir à d' _Bool, 1 et 0 respectivement (pour la compatibilité avec le C++).


Il est cependant considéré comme une bonne pratique de programmation traiter des instructions de contrôle et des opérateurs comme si il nécessaire/a abouti à un type booléen. Certaines normes de codage comme MISRA-C de recommander une telle pratique. C'est:

if(ptr == NULL) au lieu de if(ptr).

if((data & mask) != 0) au lieu de if(data & mask).

Le but de ce style est d'augmenter la sécurité de type à l'aide de l'analyse statique des outils, ce qui réduit les bugs. Sans doute, ce style n'est utile que si vous utilisez des analyseurs statiques. Si, dans certains cas, elle conduit à plus lisible, l'auto-documentation du code, par exemple

if(c == '\0') 

Bon, l'intention est claire, le code est auto-documentation.

rapport

if(c) 

Mauvais. Pourrait signifier quoi que ce soit, et nous devons aller chercher le type d' c comprendre le code. Est-il un entier, un pointeur ou un personnage?

4voto

Russell Hankins Points 355

J'ai programmé dans de nombreuses langues. J'ai vu true être 1 ou -1 selon la langue. La logique de l'être véritable 1 était un peu ça a été un 0 ou 1. La logique de l'être véritable -1 a été que le ! l'opérateur a été un complément. Il a changé tous les 1 à 0 et de tous les 0 à 1 dans un int. Donc, pour un int, !0 = -1 et !(-1) = 0. Cela a déclenché m'assez que je ne compare pas quelque chose à être == vrai, mais au lieu de le comparer à être != faux. De cette façon, mon style de programmation fonctionne dans toutes les langues. Donc, ma réponse est de ne pas s'en soucier, mais le programme de sorte que votre code fonctionne correctement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X