2016-11-09 94 views
0

目前我正在編寫一個程序,其中我需要一個變量count,每當我調用該函數時該變量都會遞增。在我的情況下,我有一個遞歸函數,並想知道該程序做了多少次迭代。如何在遞歸函數中實現運行變量

我通過計算一個數的階乘簡化了代碼。

我的第一個方法是行不通的,並警告消息結束了:

#include <stdio.h> 

int factorial(unsigned int i, int *count) 
{ 
    *count += 1; 
    if(i <= 1) 
    { 
    return 1; 
    } 
    return i * factorial(i - 1, &count); 
} 

int main() 
{ 
    int i = 10; 
    int count = 0; 
    printf("%d Iterations, Factorial of %d is %d\n", count, i, factorial(i, &count)); 
    return 0; 
} 


warning: passing argument 2 of ‘factorial’ from incompatible pointer type 

我的第二個方法不起作用要麼也不會與任何警告消息結束。

#include <stdio.h> 

int factorial(unsigned int i, int count) 
{ 
    count += 1; 
    if(i <= 1) 
    { 
    return 1; 
    } 
    return i * factorial(i - 1, count); 
} 

int main() 
{ 
    int i = 10; 
    int count = 0; 
    printf("%d Iterations, Factorial of %d is %d\n", count, i, factorial(i, count)); 
    return 0; 
} 

我該如何讓它運行?有任何想法嗎?我使用Ubuntu和gcc。

+0

在第一個問題中,使用'return i * factorial(i - 1,count);' –

+1

在'factorial'函數中,變量'count'已經是一個指針。使用它的地址 - 運算符會給你一個指向指針的指針(即'&count'是'int **'類型的)。 –

+1

當您打印結果時,您在'main'函數中還有* undefined behavior *。函數參數的求值順序沒有定義,所以你不知道'countial'的調用是否在'count'變量傳遞給'printf'之前。你需要在'printf'調用之前分別進行'factorial'調用。 –

回答

0

在您的第一個案例中,factorial()函數count的類型爲int *。因此,在遞歸調用函數時(在return聲明中),不要傳遞count的地址,只需傳遞count本身。

也就是說,因爲count要在函數調用factorial()中修改,所以不要將它們(變量和修改變量的函數調用)都放在同一個參數列表中,因爲沒有順序點在作爲參數列表傳遞的元素中,所以你最終會調用undefined behavior

0

在factorial函數本身內聲明count變量爲static

static int count = 0; 
0

解決這個問題有兩種方法。

  1. 在遞歸函數中聲明一個靜態變量來計算它被調用的次數。

例如

int factorial(unsigned int i, int *count) 
{ 
    static int count2; 
    *count = ++count2; 
    if(i <= 1) 
    { 
    return 1; 
    } 
    return i * factorial(i - 1, count); 
} 

int main() 
{ 
    int i = 10; 
    int count = 0, fact; 
    fact = factorial(i, &count); 
    printf("%d Iterations, Factorial of %d is %d\n", count, i, fact); 
    return 0; 
} 
  • 有無算作一個指針整數,其然後可以在每個功能被更新以找到迭代次數。
  • 例如

    int factorial(unsigned int i, int *count) 
    { 
        (*count)++; 
        // Remaining lines the same as first solution. 
    } 
    

    第二溶液將僅在一些特殊類型的遞歸函數的工作,其中第一函數調用第二和第二調用第三等在遞歸fibbonaci序列算法它不會例如工作。

    第一個解決方案是一個更通用的解決方案,並將適用於所有條件。

    0

    正如其他解決方案所暗示的,不需要靜態變量。以下是正確的:

    int factorial(unsigned int i, int *count) 
    { 
        *count += 1; 
        if(i <= 1) 
        { 
        return 1; 
        } 
        return i * factorial(i - 1, count); 
    } 
    
    int main(void) 
    { 
        int i = 10; 
        int count = 0; 
        printf("%d Iterations, Factorial of %d is %d\n", count, i, factorial(i, &count)); 
        return 0; 
    } 
    

    一個注意:如printf語句參數計算的順序是沒有保證的,據我瞭解的count在調用價值printf可以是零(它是通過在調用factorial之前)或者可能是10(調用階乘之後的值)。因此,主可以更好地被寫爲:

    int main(void) 
    { 
        int i = 10; 
        int count = 0; 
        int fact= factorial(i, &count); 
        printf("%d Iterations, Factorial of %d is %d\n", count, i, fact); 
        return 0; 
    } 
    

    6.5.2.2函數調用:10的功能標誌,實際參數的評估順序,和實際的參數內的子表達式是不確定的,但有實際調用之前的序列點。