2012-08-15 147 views
1

如何在putchar的幫助下打印整數。我想在不使用外部存儲的情況下做到這一點。
這個問題在去年的一次採訪中被問到。可以putchar打印一個整數嗎?

+1

順便說一下,這位採訪者是否認爲你正在爲2013年的IOCCC做準備? – 2012-08-15 19:47:43

+0

「不使用外部存儲器」是什麼意思? – 2012-08-15 20:43:49

+1

@MichaelBurr @MichaelBurr我認爲面試官的意思是不使用變量,我也很困惑 – akash 2012-08-16 05:24:12

回答

1

考慮使用itoa函數(您需要導入其庫),然後遍歷它生成的cstring中的每個字符(使用strlen獲取此循環的上限),然後在每個字符上使用putchar()。

+0

只提到了putchar – akash 2012-08-15 19:31:57

+0

他們的意思是「putchar」只是專門用於輸出或任何外部庫引用嗎?我假設前者。 – mjgpy3 2012-08-15 19:33:44

+0

可以認爲'itoa'使用外部存儲器 – dvvrd 2012-08-15 19:37:42

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); 
} 
+4

對於INT_MIN,n = -n將失敗。 – 2012-08-15 19:40:32

+0

+1 @ H2CO3:但是'n = -n;'**可能**失敗。 C標準允許在不失敗的情況下執行:-) – pmg 2012-08-15 20:04:52

+0

@pmg當然:) – 2012-08-15 20:31:52

0

有一個類似的問題,我回答this.

它應該很容易轉換成一個程序使用putchar只(例如,做這樣的事情:

while(buf[i]) 
    putc(buf[i++]); 

putc('\n'); 
+0

爲什麼downvote? – 2012-08-15 20:41:25

0

我剛剛裝配了一些可怕的東西。這主要是概念驗證,它是真的很可怕,只適用於正整數,但幾乎不使用存儲。啊,整數也不能太大,它可能是越野車。

#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用於終止循環(無論是那個還是整數溢出)。

1

正確回答這個問題很大程度上取決於「外部存儲」和「僅限於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