输出整型变量的十进制字符值

The C Programming Language 2nd(ch4.10 Recursion)的实现为(参数n不能是最小整数):

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

C Traps and Pitfalls(ch7.11 An example of portability problems)的实现与之类似:

void printnum(long n, void (*p)(int)) {
    if (n < 0) {
        (*p)('-');
        n = -n;
    }
    if (n >= 10)
        printnum(n / 10, p);
    (*p)((int)(n % 10) + '0');
}

作者Andrew Koenig从兼容性的角度, 认为最后一条语句有问题. '0'+5得到'5', 是假设计算机是基于ANSI实现的, 字符'0'到'9'才是连续的. 所以应该改为:

   (*p)("0123456789"[(n % 10)]);

2个程序正确执行的前提是, 参数n不能是最小整数. 否则n=-n将会导致溢出. 改变正数的符号是不会溢出的, 所以Andrew Koenig把程序改成只处理负数(如果参数是正数, 改变其符号):

void printneg(long n, void (*p)(int)) {
    if (n <= -10)
        printneg(n / 10, p);
    (*p)("0123456789"[-(n % 10)]);
}
void printnum(long n, void (*p)(int)) {
    if (n < 0) {
        (*p)('-');
        printneg(n, p);
    } else
        printneg(-n, p);
}

这里还有一个假设: n%10(n<0)的值为负数. 但是C语言并没有定义结果的符号, 只能保证表达式r=a%b, 当a>=0且b>0时, 有r>0, |r|<|b|(ch7.7 How does division truncate?). 所以还要修改printneg函数:

void printneg(long n, void (*p)(int)) {
    long q;
    int r;

    q = n / 10;
    r = n % 10;
    if (r > 0) {
        r -= 10;
        ++q;
    }
    if (n <= -10)
        printneg(q, p);
    (*p)("0123456789"[-r]);
}

以下是执行结果(ubuntu 10.4.1 linux, 32bits):

printd(0x80000000): --214748364(
printnum(0x80000000, (void(*)(int))putchar): -2147483648
References:

The C Programming Language 2nd(ch4.10 Recursion)

C Traps and Pitfalls(ch7.11 An example of portability problems)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值