printf indicateur de conversion pour le type Bool?
Avec printf()
, je peux utiliser %hhu
pour unsigned char
, %hi
pour un short int
, %zu
pour un size_t
, %tx
pour un ptrdiff_t
, etc.
Quel est le spécificateur de format de conversion que j'utilise pour un _Bool
? N'existe dans la norme?
ou dois-je le lancer comme ceci:
_Bool foo = 1;
printf("foo: %in", (int)foo);
5 réponses
il n'y a pas de modificateur de longueur de conversion spécifique pour le type _Bool
.
_Bool
est un non signé de type entier assez grand pour stocker les valeurs 0
et 1
. Vous pouvez imprimer un _Bool
de cette façon:
_Bool b = 1;
printf("%d\n", b);
en raison des règles de promotions entières, _Bool
est garanti de promouvoir à int
.
Jusqu'à C99, bool ne faisait pas partie de la norme C, et n'existait donc pas en tant que modificateur de printf. C99, défini _Bool (que vous utilisez) pour être un entier, donc vous devriez être fin casting comme un entier à afficher (au moins d'un point de vue machine). Alternativement, vous pourriez faire quelque chose comme:
printf("%d",foo?1:0);
comme vous l'avez déclaré dans un commentaire à @Jack, " 6.3.1.1p1 dit que le rang de conversion de _Bool
est moins que le rang de tous les autres types entiers standard".
dans un appel à printf
, un char
ou short
sera promu et transmis sur la pile comme un int
(ou un unsigned int
), donc je pense que l'utilisation de %d
comme spécificateur de format serait bien. Cela signifie également que vous n'avez pas besoin de cast explicite int
, parce que cela va se faire automatiquement.
le seul problème possible serait de savoir comment le compilateur représente un _Bool
, quelque chose qu'il a probablement défini dans sa mise en œuvre et qui pourrait varier d'un compilateur à l'autre. Je vois deux implémentations probables: 0 et 1 ou 0 et -1.
pour le summum de la portabilité, suivez la réponse de @user325181 et utilisez un ternaire pour choisir entre deux options. Soit des entiers (qui le compilateur peut optimiser à distance) ou les chaînes.
modifier: comme indiqué dans d'autres réponses, un _Bool
est défini comme un type intégral non signé qui peut stocker soit 0 ou 1. À cause de cela, et le fait qu'il sera promu à un unsigned
int
lorsqu'il est passé à printf()
, je dirais que %u
%d
est le plus approprié spécificateur.
Il n'est pas. Il suffit de le manipuler comme un int
en utilisant %d
ou %i
spécificateur.
en C99, un nouveau mot-clé, _Bool, est introduit comme le nouveau type booléen. Dans de nombreux aspects, il se comporte un peu comme un int non signé, mais les conversions d'autres types entiers ou des pointeurs toujours contraints à 0 et 1. Autres que pour les autres types non signés, et en en droit d'attendre pour un type booléen, une telle conversion est 0 si et seulement si l'expression question évalue de 0 à 1 dans tous les autres cas. Tête stdbool.h fournit des macros bool, true et false qui sont définis comme _Bool, 1 et 0, respectivement.
la première façon de le mettre en œuvre qui vient de l'esprit est d'utiliser un char
ou( int8_t
) un enum
et avec bit fields
. Mais en fait, c' dépend. Il peut être un typedef
pour un int
(comme je l'ai mentionné, il est utilisé, mais n'est pas recommandé, sujet à des bogues) ou char
ou unsigned int
ou un enum et #define
qui est couramment utilisé.
par exemple, Apple implementation utilise int
, comme vous pouvez le voir:
#ifndef _STDBOOL_H_
#define _STDBOOL_H_
#define __bool_true_false_are_defined 1
#ifndef __cplusplus
#define false 0
#define true 1
#define bool _Bool
#if __STDC_VERSION__ < 199901L && __GNUC__ < 3
typedef int _Bool;
#endif
#endif /* !__cplusplus */
#endif /* !_STDBOOL_H_ */
autres mises en œuvre:
j'utilise %b
pour un spécificateur de conversion Java printf()
. J'ai essayé récemment et à ma surprise ça a marché.
Voici la ligne de code:
System.out.printf("firstRobot == secondRobot: %b",firstRobot == secondRobot);
Voici la sortie:
firstRobot == secondRobot: false