10
votes

Printf Trop intelligent Casting de Char to int?

Pourquoi l'appel suivant:

printf("%d %d", 'a', 'b');


3 commentaires

% D est un entier signé, ne dit rien sur le nombre d'octets impliqués ...


@Leppie: Cependant, il doit être transmis avec un nombre définitif d'octets, et printf doit choisir un certain nombre d'octets de la pile pour cela, et ces chiffres doivent être identiques.


'a' a type int pas char .


3 Réponses :


16
votes

Dans ce cas, les paramètres reçus par printf seront de type int .

Tout d'abord, tout ce que vous passez à imprimer (sauf le premier paramètre) Sousge "Promotions par défaut", ce qui signifie (entre autres) que Char et court-court sont tous deux favorisés à int avant d'être passé. Donc, même si ce que vous passiez a vraiment fait de type caractère, au moment où il est arrivé à printf il aurait le type int . Dans votre cas, vous utilisez un littéral de caractère, qui a déjà du type int de toute façon.

Il en va de même avec Scanf et d'autres fonctions qui prennent des paramètres variadiques.

second, même sans promotion par défaut, les littéraux de caractères en C ont déjà type int de toute façon (§6.4.4.4 / 10):

Une constante de caractère entier a le type INT.

Donc, dans ce cas, les valeurs commencent par type int , et ne sont pas promus - mais même si vous avez commencé avec Char S, quelque chose Comme: xxx

... Qu'est-ce que printf serait de type int , pas de type char < / code> quand même.


9 commentaires

Promotions par défaut? Vraiment? Depuis quand les varargs font-elles des promotions par défaut? N'est-ce pas juste que le type d'un littéral de caractère est int ?


Oui et non - oui, un type de type int , mais même s'il l'a attribué à un char et est passé que, printf serait Recevez toujours un INT , il est donc à peu près pertinent.


Aucune promotion ne se passe ici. 'A' et 'B' ayez le type int dans C.


@R: Gee, merci! Je suis sûr que personne d'autre ici a remarqué quoi que ce soit comme ça. Sous-titrage fermé pour l'humour altéré : Si "@R" avait pris la peine de lire les commentaires précédents, il veillé à ce que tout le monde ait remarqué qu'il y a des semaines - et que j'ai déjà souligné que / comment hors du sujet.


@R .. votre point m'a forcé à poser une autre question: pourquoi printf ("% d", (char) 'a'); fonctionne bien? printf contourner la coercition de contourne-t-il aussi? Do éclaire. :)


@Chaz: les appels vers des fonctions variadiques soumettent tous les arguments variadiques sur Parfumions par défaut , qui favorisent tous les types d'entiers avec rang inférieur à int à int ou non signé INT et promouvoir float à double . Il est fondamentalement impossible de passer un char comme argument variadique.


@R .. alors dois-je supposer que Promotions se passe ici?


Dans le cas de printf ("% d", (char) 'a'); , les promotions par défaut, qui seraient peut-être mieux décrites comme Les promotions obligatoires , aboutir à Le Char -Type Expression (char) 'a' a ' être promu à int avant d'être passé sur printf . Dans le cas de printf ("% d", 'a'); , 'a' a simplement le type int pour commencer.


Voici un lien de référence (voir la section "Conversions par défaut"): en.cppreference.com/ W / CPP / Langue / Variadic_Arguments



4
votes

in C , un charcutéal est une valeur de type int .


0 commentaires

0
votes

Il imprime l'ASCI DEC pour les caractères entrés par vous.


0 commentaires