如何仅借助putchar()
打印整数。 我想在不使用外部存储的情况下做到这一点。
这个问题是在去年的一次采访中提出的。
当面对面试中的模糊要求时,表达你的假设是个好主意。
我会接受关于只能使用 putchar
的要求意味着它是我唯一被允许调用的库函数。我进一步假设"没有外部存储"意味着我无法显式创建缓冲区。如果面试官同意我的假设,我会继续:
void pr_int(int n) {
if (n < 0) {
putchar('-');
n = -n;
}
if (n / 10 != 0)
pr_int(n / 10);
putchar((n % 10) + '0');
}
如果面试官随后评论说n = -n;
会失败INT_MIN
,如下所述,那么我会将其重写为:
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);
}
回答这个问题在很大程度上取决于"外部存储"和"仅putchar
"的含义。
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');
}
上述实现假定 C99 语义,如 C99 第 6.5.5 节 p6 中所述:
当整数被除以时,
/
运算符的结果是代数商,丢弃任何小数部分。如果商a/b
可表示,则表达式(a/b)*b + a%b
应等于a
。
但是,%
的ANSI C(C 89)语义更差。ANSI C 第 3.3.5 节 p5 说:
如果任一操作数为负数,则
/
运算符的结果是小于代数商的最大整数还是大于代数商的最小整数都是实现定义的,%
运算符的结果的符号也是如此。
费鲁乔的第二个答案几乎是完美的。问题是转换不正确。如果操作的结果是无法由int
表示的值,则未定义n = -n
的结果。因此,转换应以这种方式完成:
void pr_int(int n) {
if (n < 0) {
putchar('-');
pr_uint(-(unsigned int)n);
} else
pr_uint(n);
putchar('n');
}
该解决方案现在符合所有ISO C标准。详细信息可以在这里找到。
itoa 函数(您需要导入其库),然后遍历它生成的字符串中的每个字符(使用 strlen 获取此循环的上限),然后简单地在每个字符上使用 putchar()。
已经有一个类似的问题,我在那里回答了这个问题。
仅使用 putchar 将其转换为程序应该很容易(例如,执行以下操作:
while(buf[i])
putc(buf[i++]);
putc('n');
我刚刚组装了一些可怕的东西。它主要是概念验证,它真的很可怕,仅适用于正整数,但几乎不使用存储空间。啊,整数也不能太大,而且可能会有问题。
#include <stdio.h>
#include <assert.h>
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
设置将打印的位数。 b
存储实际数字,max
用于终止循环(该或整数溢出)。