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);
14
demandé sur Richard Hansen 2012-06-28 21:55:42

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 .

11
répondu ouah 2012-06-28 19:22:26

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);
6
répondu Claris 2012-06-28 18:07:23

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.

2
répondu tomlogic 2012-06-28 23:16:01

Il n'est pas. Il suffit de le manipuler comme un int en utilisant %d ou %i spécificateur.

_Bool

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:

typedef int8_t _Bool;

typedef enum { false = 0, true = 1 } bool;

typedef unsigned char Boolean; typedef _Bool Boolean;

1
répondu Jack 2017-05-23 12:12:27

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
0
répondu Stephanie G 2013-09-22 03:38:24