2017-03-14 91 views
2

我沒有與誰寫一個unsigned int打印功能:遞歸打印數量c。與寫

ssize_t  putc_fdr(char c, int fd) 
{ 
    return (write(fd, &c, sizeof(char))); 
} 

ssize_t  putuint_fdr(uintmax_t i, int fd) 
{ 
     return (i != 0 ? putuint_fdr(i/10, fd) + putc_fdr(i % 10 + '0', fd) : 0); 
} 

但它沒有爲I = 0工作,因爲功能不顯示任何信息。 如果我用': putc_fdr('0', fd)'代替': 0',它將不起作用,因爲如果i> 10,遞歸結束時總會打印一個額外的'0'。 (邏輯) 但是如何僅在開始i爲0時打印此0?

+1

操作數對「+」的求值是未指定的順序。您的號碼可能會被正確打印,因爲它會被反向打印。 – StoryTeller

+0

如果= 0,它將返回0,因爲這就是你編碼它要做的。爲了更清楚,表達式(i!= 0?X:Y)將始終返回Y. – NomeQueEuLembro

+0

[爲什麼這些構造(使用++)未定義的行爲?](http://stackoverflow.com/questions/949433/why-are-these-constructs-using-undefined-behavior) – Olaf

回答

4

而不是停在零,當你達到一個數字時停止。

你應該通過開溝?:操作,並允許你的函數用更少的重複中的默認行爲解決排序問題(這樣就保證了正確的打印順序):

ssize_t  putuint_fdr(uintmax_t i, int fd) { 
     ssize_t ret1 = 0; 

     if(i/10 != 0) 
      ret1 = putuint_fdr(i/10, fd); 

     if (ret1 < 0) 
      return ret1; 

     ssize_t ret2 = putc_fdr(i % 10, fd); 

     if (ret2 < 0) 
      return ret2; 

     return ret1 + ret2; 
} 
+0

好的,謝謝。我沒有想到操作數的執行順序。 – tfontain

1

考慮你的表情做什麼:

(i != 0 ? putuint_fdr(i/10, fd) + putc_fdr(i % 10 + '0', fd) : 0); 

首先,它檢查條件i != 0。然後,如果條件爲真,它將:

  • 遞歸調用所作的發言putuint_fdr(i/10, fd)

  • 呼叫putc_fdr(i % 10 + '0', fd)

  • 總和兩者的返回值,什麼也不做它。

請注意,它可以按任意順序調用函數。

如果I = 0它會:

  • return 0

,不會做任何事情,真的是在你的代碼的中間只是一個數字。你需要調用一個函數來寫0,而不僅僅是說「0」

0

由於二進制+是無序的,所以你需要強制執行所需的評估操作數的順序。大多數情況下,打印個別數字意味着您首先要打印MSD,因此推遲打印數字直至您建立了MSD。這意味着您希望首先進行遞歸,並在遞歸調用返回時進行打印。

如果要保留當前的代碼結構,可以使用逗號運算符,對兩個調用進行排序。爲了解決您的困境,我們檢測輸入何時是單個數字。

ssize_t  putuint_fdr(uintmax_t i, int fd) 
{ 
    ssize_t ret = 0; 
    return (i/10 != 0 
      ? ret = putuint_fdr(i/10, fd), 
       ret + putc_fdr(i % 10 + '0', fd) 
      : putc_fdr(i + '0', fd)); 
} 

這裏假設write在打印您的號碼時不會返回錯誤。如果你想增加額外的健壯性,你也應該嘗試考慮這種情況。


在這個答案的註釋,你問:

有沒有辦法不使用一個變量,並保持有序電話? (ret ssize_t

您需要某種變量來添加兩個順序函數調用的結果。但是,可以通過將第一個函數調用的結果作爲參數傳遞給第二個函數調用來隱藏賦值。

ssize_t  putc_fdr(char c, int fd, ssize_t ret) 
{ 
    return ret + write(fd, &c, sizeof(char)); 
} 

ssize_t  putuint_fdr(uintmax_t i, int fd) 
{ 
    return putc_fdr(i%10 + '0', fd, 
        i/10 ? putuint_fdr(i/10, fd) : 0); 
} 
+0

沒有辦法不使用變量並保持順序調用? (ret ssize_t) – tfontain