12
votes

C: Impression de gros nombres

Prenez les éléments suivants:

Without variable : 18035667472744448
With variable    : 285212672


0 commentaires

4 Réponses :


3
votes

285212672 est une valeur int . printf attend un non signé long long et vous y passez un int . Par conséquent, cela prendra plus d'octets hors de la pile que de votre valeur réelle et imprime des ordures. Lorsque vous le mettez dans une variable non signé longue long Avant de le transmettre à la fonction, il sera favorisé à non signé long long dans la ligne d'affectation et vous passez cette valeur à printf qui fonctionne correctement.


0 commentaires

25
votes

essayer 285212672ull code>; Si vous l'écrivez sans suffixes, vous trouverez que le compilateur le traite comme un entier régulier. La raison pour laquelle il fonctionne dans une variable est que l'entier est en train d'être jeté jusqu'à un non signé long long code> dans l'affectation, de sorte que la valeur transmise à printf () code> est la droite Tapez.

et avant de demander, non, le compilateur probablement n'est pas assez intelligent pour le comprendre à partir du "% llu code>" dans le printf () code> chaîne de format. C'est un niveau d'abstraction différent. Le compilateur est responsable de la syntaxe de langue, printf () code> la sémantique ne fait pas partie de la syntaxe / em>, c'est une fonction de bibliothèque d'exécution (pas vraiment différente de vos propres fonctions sauf que c'est Inclus dans la norme). P>

Considérez le code suivant pour un système long long de 32 bits INT et 64 bits non signé de 32 bits: P>

What you pass     Stack frames     What printf() uses
                 +------------+
0                | 0          | \
                 +------------+  > 64-bit value for %llu.
"hello"          | 0xbf000000 | /
                 +------------+
0                | 0          |    value for %s (likely core dump here).
                 +------------+
                 | ?          |    value for %d (could be anything).
                 +------------+


6 commentaires

Mais je pense que le compilateur est suffisamment intelligent pour comprendre% u dans la spécification de format Printf, essayez impression ("% d% u", ~ 0, ~ 0) .. Les deux imprimeront les valeurs comme prévu ..


Non - ces types de données sont de la même taille - c'est PrintF () SIGNING SOIT - ESSAYEZ% D avec 'A'.


Pax: C'est bien aussi, les littéraux de caractère sont des constantes entière.


Droit vous êtes @CAF, mais le compilateur est toujours pas à l'intérieur des arguments de printf. Et cela ne devrait pas car c'est un niveau d'abstraction différent (langage par rapport à la bibliothèque d'exécution). J'ai mis à jour la réponse avec plus d'informations.


Dans le code que vous utilisez 1 et 2, mais dans le texte que vous utilisez 0 et 1 :)


Merci, @litb, corrigé. J'ai eu à l'origine 0/1 mais le comportement semblait un peu ambigu, c'est pourquoi j'ai changé [certaines parties de].



0
votes

DataType est simplement un moyen d'interpréter le contenu d'un emplacement de mémoire.
Dans le premier cas, la valeur constante est stockée en lecture seule Emplacement de la mémoire comme INT, le PrintF tente d'interpréter cette adresse sous forme d'emplacement à 8 octets, car il est demandé que la valeur stockée est longue pendant laquelle elle imprime la valeur de la poubelle.
Dans le second cas, Printf tente d'interpréter une longue valeur longue en tant que 8 octets et imprime ce qui est attendu.


0 commentaires

5
votes

Il convient de souligner que certains compilateurs donnent un avertissement utile pour ce cas - par exemple, c'est ce que GCC dit à propos de votre code:

x.c: In function ‘main’:
x.c:6: warning: format ‘%llu’ expects type ‘long long unsigned int’, but argument 2 has type ‘int’


1 commentaires

Encore une autre raison de ne pas ignorer la compilation avertissements .