1

配列内の最大数を見つけるプログラムを作成しました。find_largest問題は、関数が再帰的に呼び出されるたびに、largest変数がメモリ内の別の場所からのガベージで満たされているように見えることです。デバッガーを使用してステップ実行しましたが、再帰呼び出しまで正常に動作しているようです。配列のポインターと への更新largest(該当する場合) は、予期される値を示します。

/*This program will find the largest integer in an array. It was written to practice
using recursion.*/

#include <stdio.h>
void find_largest(int *a, int n);
int main() {
    int a[] = {10, 27, 101, -8, 16, 93}; 
    int n = 6, i = 0;
    printf("Current array: ");
    while(i < n) {//print array
        printf("%d ", a[i]);
        i++;
    }
    find_largest(a, n);
    return 0;
}//end main

//This function will start at the last element, and then step through the array 
//in reverse order using pointers. 
void find_largest(int *a, int n) {  //formulate the size-n problem.
    int largest = 0;
    if(n == 0) {    //find the stopping condition and the corresponding return
        printf("\nThe largest number is: %d \n", largest);
    }
    else { //formulate the size-m problem.
        n--; //decrement so that the proper number is added to pointer reference
        if(largest <= *(a + n)) //check if element is larger
            largest = *(a + n); //if larger, assign to largest
        find_largest(a, n); //recursive call
    }
}

プログラムは、最大の整数としてゼロを返します。何か案は?

4

4 に答える 4

6

largestすべての再帰呼び出しで共有されているわけではなく、それぞれが独自のコピーを取得します。つまり、基本ケースでは、次のコードを実行します。

int largest = 0;
if (n == 0) { 
    printf("\nThe largest number is: %d \n", largest);
}

いつもどこlargestにいるでしょう。0

ちょっと変わった方法ですが、作ることはできますlargest staticし、うまくいきます。私はこのようなことをしたいと思います:

int find_largest(int *a, int n)
{
    int subproblem;

    // base case - single element array, just return that element
    if (n == 1)
    {
        return *a;
    }

    // recursion - find the largest number in the rest of the array (increase 
    // array pointer by one, decrease length by one)
    subproblem = find_largest(a + 1, n - 1);

    // if the current element is greater than the result of the subproblem,
    // the current element is the largest we've found so far - return it.
    if (*a > subproblem)
        return *a;

    // otherwise, return the result of the subproblem
    else
        return subproblem;
}
于 2013-06-13T04:42:02.560 に答える
3

largest0個別の関数呼び出しごとに初期化されます。簡単な修正は次のとおりです。

int find_largest(int *a, int n) {  //formulate the size-n problem.
    static int largest = 0;
    if(!n) {    //find the stopping condition and the corresponding return
        int answer = largest;
        largest = 0;
        return answer;
    }
    else { //formulate the size-m problem.
        n--; //decrement so that the proper number is added to pointer reference
        if(largest <= *(a + n)) //check if element is larger
             largest = *(a + n); //if larger, assign to largest
        find_largest(a, n); //recursive call
    }
}

このstatic属性は、変数を一度だけ初期化し、その後はそのデータを保持する必要があることをコンパイラに伝えます。各再帰呼び出しの後、largestゼロにリセットされないため、これで問題が解決します。代わりに、最後の呼び出し (この場合は呼び出し関数) の値が含まれます。

関数の最後に、次の呼び出しで前の呼び出しの値がまだ含まれないように、にリセットlargestする必要があります。0これが、一時変数が作成される理由でもあります。これにより、に設定される前にその値を返すことができます0

于 2013-06-13T04:46:31.787 に答える
0

find_largest() を呼び出すたびに、ローカル変数 int maximum を作成し、それにゼロの値を割り当てます。したがって、n が最終的にゼロに到達すると、過去 5 回の再帰呼び出しが何を行ったかは気にせず、設定した最大値のゼロを返すだけです。最大のグローバルを作成するか、パラメーターとして関数に渡します (おそらくより良い方法)。

于 2013-06-13T04:44:26.773 に答える