【问题标题】:Can putchar() print an integer?putchar() 可以打印一个整数吗?
【发布时间】:2012-08-15 19:22:20
【问题描述】:

如何仅在putchar() 的帮助下打印整数。我想在不使用外部存储的情况下做到这一点。
这个问题是在去年的一次采访中被问到的。

【问题讨论】:

  • 顺便说一句,这位面试官认为你是在为 2013 年的 IOCCC 做准备吗?
  • “不使用外部存储”是什么意思?
  • @MichaelBurr 我认为面试官的意思是不使用变量,我也很困惑

标签: c file-io integer output putchar


【解决方案1】:

在面试中遇到模糊的要求时,最好表达你的假设。

我认为只能使用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);
}

【讨论】:

  • n = -n INT_MIN 将失败。
  • +1 @H2CO3: 但n = -n; 可能失败。 C 标准允许实现不会失败:-)
【解决方案2】:

考虑使用 itoa 函数(您需要导入它的库),然后循环遍历它生成的 cstring 中的每个字符(使用 strlen 获取此循环的上限),然后简单地对每个字符使用 putchar()。

【讨论】:

  • 他们的意思是“putchar”仅专门用于输出或任何外部库引用吗?我假设是前者。
  • 可以认为itoa使用了外存
  • “外部存储”?他是说什么都不能存储在ram中吗?
  • itoa 甚至不是标准函数……
  • 我从来没有说过。事实上我确实说过,“你需要导入它的库”。
【解决方案3】:

正确回答这个问题很大程度上取决于“外部存储”和“仅限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 节说:

如果任一操作数为负,则/ 运算符的结果是小于代数商的最大整数还是大于代数商的最小整数是实现定义的,结果的符号也是% 运营商。

Ferruccio 的第二个答案几乎是完美的。问题是转换不正确。如果运算结果是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 标准。详情可见here

【讨论】:

    【解决方案4】:

    已经有类似的问题了,我回答了this.

    将其转换为仅使用 putchar 的程序应该很容易(例如,执行以下操作:

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

    【讨论】:

      【解决方案5】:

      我刚刚组装了一些可怕的东西。它主要是概念验证,它真的很可怕,仅适用于正整数,但几乎不使用任何存储空间。啊,而且整数也不能太大,会出错。

      #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 用于终止循环(或者整数溢出)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-03-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-03
        • 2016-10-24
        • 1970-01-01
        相关资源
        最近更新 更多