J'ai remarqué que dans C, ma variable booléenne est en quelque sorte changée d'une manière que je ne comprends pas. si je saisie une valeur de 1 code> pour
x code> et n'importe quelle valeur pour
y code> (
1 code> dans cet exemple): p>
x: 1
x is 1
y: 1
x is 0
y is 1
7 Réponses :
OK, deux points ici. P>
bool code> est définie par la mise en œuvre. li>
- Il n'y a pas de spécificateur de format défini pour
bool code> type dans la norme. LI>
ol>
Alors, tandis que Numérisation forte> la valeur, passant l'adresse d'un bool code> comme argument pour % d code> est mauvais Voir note sup> comme le type fourni n'est pas identique au type attendu. p>
Vous pouvez utiliser un entier intermédiaire, numériser la valeur en cela et (après validation ou transformation sur true code> et false code> macros) Attribuer le résultat retour à BOOL code> variable de type. P>
pour Impression forte>, cependant, en raison de la promotion des arguments par défaut, un bool code> peut être un candidat à l'argument pour % d code> sans problème . P>
Remarque: P>
% d code> avec * scanf () code> attend que l'argument soit un int * code>, fournissant plutôt un bool * Code> va causer comportement non défini . P>
liés, citant du chapitre § 7.21.6.2, paragraphe 10 p>
[....] Sauf si une suppression d'affectation n'a été indiquée par un * code>, le
Le résultat de la conversion est placé dans l'objet pointé par le premier argument suivant
L'argument code> format code> qui n'a pas déjà reçu de résultat de conversion. si cet objet
n'a pas de type approprié ou si le résultat de la conversion ne peut pas être représenté
Dans l'objet, le comportement est indéfini. strong> p>
blockQuote>
Pourriez-vous expliquer davantage sur la façon dont "transmettre l'adresse d'un bool comme argument de % d code> n'est pas bon"?
Celui-ci est peut-être utile: printf ("\ n_bool:% zu \ nint:% zu", Tailleof (_bool), Tailleof (int)); code> montrant qu'ils n'ont peut-être pas la même taille. Sur ma machine (GCC 4.8.5), j'obtiens:
_bool: 1 code> et
int: 4 code>.
@Andrekampling Pas extrêmement pertinent car il est toujours un comportement non défini pour utiliser le spécificateur de format incompatible, même pour deux types qui ont la même taille
@ Mm pour développer, comme, pour int code> et
float code>. L'alignement joue également un rôle.
@ M.m aussi, édité la dernière partie pour le rendre plus clair, c'est mieux?
@ M.m monsieur, même si bool code> est un
typedef code> pour un
int code>?
@ M.m Si je peux, il n'est pas nécessaire de ne pas être un int * code>, strictement, il peut s'agir d'un pointeur sur un type d'entier signé. Corrigez-moi si j'ai tort, s'il-vous plait.
@ M.m Merci de corriger alors, j'ai mis à jour la réponse.
Vous passez une adresse de la variable booléenne à Pour résoudre ce problème, utilisez temporairement Démo strong> p> scanf () code> qui attend la variable de type
int * code>. Cela invoquera un comportement non défini et vous risquez d'obtenir des résultats erronés ou même de crash.
int code> pour stocker la numérisation d'une valeur booléenne (comme INT), et après cela à une variable booléenne. p>
bool x, y;
int tmp;
printf("x: ");
scanf("%d", &tmp);
x = tmp;
x = (TMP! = 0? true: false); code> z->
x = !! TMP; code>
A par Si une spécification de conversion n'est pas valide, le comportement est indéfini. P>
blockQuote>
Notez que le paragraphe 9 de Si une spécification de conversion n'est pas valide, le comportement est
indéfini. Si un argument n'est pas le type correct pour le
Spécification de conversion correspondante, le comportement est
non défini. p>
blockQuote>
Mais c'est pour bool code> n'est pas un
int code>. Le lire avec le spécificateur de format
% d code> pour un
int code> est un comportement indéfini. P>
FSCANF code> fonction strong>, paragraphe 13 de la norme C : p>
fprintf code> fonction strong> états: p>
fprintf () code>, pas
fscanf () code>. Les spécificateurs de format sont beaucoup plus stricts pour les fonctions
SCANF () CODE> Comme il n'y aura aucun argument de promotion que
permet un format tel que
% d code> à "fonctionner" pour un
char code> ou
bool code>, qui est promu à
int code> Pour un
printf () code> appel. Les fonctions
Ceci est faux b>. La spécification de conversion est non invalide b> ici. Voir Ceci
@Souravghosh Comment savez-vous?
@Souravghosh: Mais n'est-ce pas exactement ce que vous dites dans votre réponse ???
@PaulR Non monsieur, la spécification de conversion est Fine B>, c'est l'argument qui ne s'inscrit là-bas.
@Souravghosh hein? De toute évidence, les gens veulent dire "le spécificateur de conversion est faux pour l'argument fourni"
@SOURAVGHOSH: Le point est que la spécification de conversion et le type du paramètre ne correspondent pas. C'est une réponse parfaitement bonne si vous le lisez attentivement.
@SOURAVGHOSH Non Monsieur, la spécification de conversion va bien, c'est l'argument qui l'incompatible. I> Comment la spécification de conversion peut-elle être "bien" si elle ne correspond pas à l'argument? C'est la définition b> d'une spécification de conversion non valide: "Sous le contrôle de la chaîne pointée par format spécifiant les séquences d'entrée admissibles et la manière dont ils doivent être convertis pour une affectation, en utilisant des arguments ultérieurs en tant que pointeurs vers les objets. recevoir l'entrée convertie. "
@PaulR mal et non valide sont utilisés dans un contexte différent, comme je l'ai lu. En outre, j'ai lié une question de mienne dans ce contexte.
@ user694733 c'est une note de bas de page explicative. Et dans cette copie de la norme C , Note de bas de page 282 se lit "282) Voir" "Directions de la bibliothèque futures" (7.31.11). "
Tout d'abord, je viens de commencer à apprendre C deux jours il y a deux jours, je ne comprends donc pas 90% des choses dans ce PDF. De plus, ces commentaires me rendent simplement plus confus quant à ce qui est la cause du problème. Pour l'instant, cela ressemble à une question de sémantique pour moi.
@ user694733 OK, vous citez la section FPRRTINF () CODE>, paragraphe 9. La phrase suivante n'est pas au paragraphe 13 de la section
FSCANF () code> que j'ai citée. Je pense que la section
FSCANF () CODE> est plus appropriée, en particulier depuis
fprintf () code> Spécificateurs de format de facto i> Autoriser beaucoup de "pont" En raison de la promotion de l'argument, qui n'aidera pas les fonctions
scanf () code>.
@Andrewhenle je me sens comme un idiot maintenant: P désolé. Supprimer des commentaires.
@ user694733 qui était utile, explique probablement certains des commentaires autres i> Downvotes, comme il y a no i> référence à l'argument ne correspondant pas à la spécification de conversion Dans la section FSCANF i> B> de la norme.
Lire le FSCANF CODE> DOCS, je pense toujours qu'il peut y avoir un problème. Je pense que vous auriez dû citer le paragraphe 10, précisément "... Si cet objet n'a pas de type approprié, ni ..., le comportement est indéfini" i>. Je crois que le paragraphe 13 ne couvre que la syntaxe de spécificateur de conversion malformée (comme non existant
% k code>).
@ user694733 Je vais devoir reformuler le paragraphe 10 maintenant. : - / J'avais vu cela comme faisant référence au traitement des données d'entrée, mais à la fin, il passe à la rédaction de la conservation des résultats de la conversion.
C'est bien que cette réponse met l'accent sur % d code> pas un
bool code> ou
int code>, mais un
int * code>.
clang strong> compilateur généré avertissement: p> bool code> est un type de données différent, puis
int code>, et il est susceptible d'être un seul octet.
scanaf code> n'est pas TYPE -Safe fonction, vous le disez avec le spécificateur de conversion
% d code> qui s'attend à Pointeur sur un Int Strard> et
scanaf code> n'a aucun moyen de savoir que Vous avez passé le pointeur
à bool code> au lieu de pointeur sur un int fort>. Ensuite, vous obtiendrez
Considérez le programme suivant
scanf("%d", &y);
Connaissez-vous sur Tailleof CODE>?
@ Mm je l'ai trouvé plus illustratif de cette façon.
ou peut-être (si la chaîne d'entrée contient true ou est 1 retournera 1 code> - sinon
0 code>)
Sans le !! code>, la valeur de retour serait la même. Je suppose un problème de style.
Dans ce cas oui
Toutes les autres réponses sont techniquement correctes, mais ne vous aidez pas vraiment. p>
Votre problème principal n'est pas X ni Y, mais le fait que vous ne soyez pas en mesure de déboguer les problèmes de programmation les plus triviaux vous-même. Ceci est facile à réparer - Activer les avertissements du compilateur (si vous utilisez gcc code>, ajoutez l'option
-wall code>). COMPILER vous informera d'une erreur comme celle-ci et beaucoup d'autres autres. Pas besoin de venir à Stackoverflow à chaque fois :) p>
Sidenote: Vérifiez toujours la valeur de retour de
Scanf code> Fonctions. Sinon, vous ferez l'expérience du comportement indéfini i> lorsque l'utilisateur donne une entrée non valide (dans ce cas non numérique).
Gagnez du temps, activez les avertissements de complier.
bool x, y; ... Scanf ("% d", & x); code> aurait dû vous avertir.
@chux je suis d'accord, j'ai ajouté cela comme une réponse.