5

我在读 K&R; 到目前为止,我做得很好,但是功能itoa()中有一些我不明白的东西。他们在这里itoa()说他们自己颠倒了数字。例如 10 是 01 (他们反转字符串):

void itoa(int n, char s[])
{
    int i, sign;
    if ((sign = n) < 0) /* record sign */
        n = -n; /* make n positive */
    i = 0;
    do { /* generate digits in reverse order */
        s[i++] = n % 10 + '0'; /* get next digit */
    } while ((n /= 10) > 0); /* delete it */
    if (sign < 0)
        s[i++] = '-';
    s[i] = '\0';
    reverse(s);
    return;
}

我不明白它是如何颠倒数字的。即使我们只是在做n % 10 + '0'它的下一个数字,10 然后 1 被删除然后它变成 0 对吗?还是我不明白它的逻辑?

4

3 回答 3

12

在 do-while 循环中,它从后面拉出数字(首先是最低有效位)。所以,如果你有数字 -123456789,它会处理 9,然后是 8,然后是 7,等等。

因此,当它到达空终止符(第 3 行到最后一行)时,您将得到“987654321-”,然后将其反转。

于 2009-10-02T16:13:17.603 回答
2

n % 10给出0for n = 10,所以在循环之后,字符串s包含01.

调用来reverse()解决这个问题。

于 2009-10-02T16:13:25.103 回答
1

该算法确定从最低到最高有效顺序的数字。因为预先不知道将生成的总位数,所以在生成它们时无法确定正确的位置 - 最低有效位将在末尾,但不知道“末尾”。因此它们按照计算顺序(反向)进行缓冲,然后将整个字符串反转以更正排序。

避免这种情况的一种方法是提前确定长度:

decimal_digits = (int)log10( n ) + 1 ;

但是在没有 FPU 的设备(以及一些非常简单的 FPU)上,这可能是比字符串反转更重的任务。

于 2009-10-02T20:41:44.750 回答