のみを使用して整数を出力するにはどうすればよいですかputchar()
。外部ストレージを使わずにやりたい。
この質問は昨年のインタビューで聞かれました。
5 に答える
面接で漠然とした要件に直面した場合は、仮定を表明することをお勧めします。
のみ使用できるという要件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 セクション 6.5.5 p6 で説明されているように、C99 セマンティクスを想定しています。
整数が除算されると、
/
演算子の結果は小数部分が破棄された代数商になります。商a/b
が表現可能な場合、式(a/b)*b + a%b
は と等しくなりa
ます。
ただし、ANSI C (C 89) のセマンティクス%
はより悪いです。ANSI C セクション 3.3.5 p5 は次のように述べています。
いずれかのオペランドが負の場合、演算子の結果が
/
代数商よりも小さい最大の整数であるか、代数商よりも大きい最小の整数であるかは、%
演算子の結果の符号と同様に実装定義です。
Ferruccio の 2 番目の答えはほぼ完璧です。問題は、変換が正しくないことです。n = -n
演算の結果が で表現できない値である場合、 の結果は未定義ですint
。したがって、変換は次のように行う必要があります。
void pr_int(int n) {
if (n < 0) {
putchar('-');
pr_uint(-(unsigned int)n);
} else
pr_uint(n);
putchar('\n');
}
そして、このソリューションは現在、すべての ISO C 規格に準拠しています。詳細はこちらをご覧ください。
itoa 関数 (そのライブラリをインポートする必要があります) を使用してから、それが生成する cstring 内の各文字をループし (strlen を使用してこのループの上限を取得します)、各文字で putchar() を使用することを検討してください。
怖いものを組み立てたところです。これは主に概念実証であり、非常に恐ろしく、正の整数に対してのみ機能しますが、ストレージをほとんど使用しません。ああ、整数も大きすぎることはできず、バグがある可能性があります。
#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
、ループを終了するために使用されます(それまたは整数のオーバーフロー)。
似たような質問がありましたので、回答させていただきました。
これを putchar のみを使用するプログラムに変換するのは簡単なはずです (たとえば、次のようにします。
while(buf[i])
putc(buf[i++]);
putc('\n');