Putchar peut-il imprimer un entier?

Comment puis-je imprimer un entier à l’aide de putchar uniquement. Je veux le faire sans utiliser de stockage externe.
Cette question a été posée lors d’une interview l’année dernière.

Lorsque vous êtes confronté à de vagues exigences lors d’un entretien, c’est une bonne idée d’exprimer vos hypothèses.

Je prendrais l’exigence de pouvoir utiliser putchar uniquement comme signifiant que c’est la seule fonction de bibliothèque que j’ai le droit d’appeler. Je supposerais en outre que “pas de stockage externe” signifiait que je ne pouvais pas créer explicitement de tampon. Si l’intervieweur était d’accord avec mes hypothèses, je procéderais avec:

 void pr_int(int n) { if (n < 0) { putchar('-'); n = -n; } if (n / 10 != 0) pr_int(n / 10); putchar((n % 10) + '0'); } 

Si l'intervieweur a ensuite commenté que n = -n; échouerait pour INT_MIN , comme indiqué ci-dessous, je le INT_MIN ainsi:

 void pr_uint(unsigned int n) { if (n / 10 != 0) pr_uint(n / 10); putchar((n % 10) + '0'); } void pr_int(int n) { if (n < 0) { putchar('-'); n = -n; } pr_uint((unsigned int) n); } 

Pensez à utiliser la fonction itoa (vous devez importer sa bibliothèque) puis à parcourir en boucle chaque caractère de la chaîne générée par celle-ci (utilisez strlen pour obtenir la limite supérieure de cette boucle), puis utilisez simplement putchar () sur chaque caractère.

Répondre correctement à cette question dépend en grande partie de ce que l’on entend par “stockage externe” et ” putchar uniquement”.

 void print_int_r (int x, int neg) { int y = x/10; int d = x%10; if (y) print_int_r(y, neg); putchar('0' + (neg ? -d : d)); } void print_int (int x) { int neg = x < 0; if (neg) putchar('-'); print_int_r(x, neg); putchar('\n'); } 

L'implémentation ci-dessus suppose la sémantique C99, comme décrit dans la section 6.5.5 p6 de C99:

Lorsque les entiers sont divisés, le résultat de l'opérateur / est le quotient algébrique, toute partie décimale étant ignorée. Si le quotient a/b est représentable, l'expression (a/b)*b + a%b doit être égale à a .

Cependant, la sémantique ANSI C (C 89) pour % est pire. ANSI C Section 3.3.5, p. 5 dit:

Si l'un des opérandes est négatif, que le résultat de l'opérateur / soit le plus grand nombre entier inférieur au quotient algébrique ou que le plus petit entier supérieur au quotient algébrique soit défini par l'implémentation, comme le signe du résultat de l'opérateur % .

La deuxième réponse de Ferruccio est presque parfaite. Le problème est que la conversion n'est pas correcte. Le résultat de n = -n n'est pas défini si le résultat de l'opération est une valeur non représentable par un int . Donc, la conversion devrait être faite de cette façon:

 void pr_int(int n) { if (n < 0) { putchar('-'); pr_uint(-(unsigned int)n); } else pr_uint(n); putchar('\n'); } 

Et la solution est maintenant conforme à toutes les normes ISO C. Les détails peuvent être trouvés ici .

Il y avait déjà une question semblable à celle-ci, j’ai répondu à cela.

Il devrait être assez facile de convertir ceci en un programme utilisant uniquement putchar (par exemple, faites quelque chose comme ça:

 while(buf[i]) putc(buf[i++]); putc('\n'); 

Je viens d’assembler quelque chose d’effrayant. C’est principalement une preuve de concept, c’est vraiment effrayant , ne fonctionne que pour les entiers positifs mais n’utilise presque pas de stockage. Ah, et le nombre entier ne peut pas être trop grand aussi, et il peut être bogué.

 #include  #include  int main() { const int max_precision = 100000; int b = 7414; int max = b * max_precision; assert(b > 0); while (b <= max && b >= 0) { putchar('0' + (b / max_precision) % 10); b *= 10; } putchar('\n'); } 

max_precision définit le nombre de chiffres à imprimer. b enregistre le nombre réel et max est utilisé pour terminer la boucle (soit ce dépassement, soit un dépassement d’entier).