簡體   English   中英

為什么我的C程序在遞歸調用中變量會更改值?

[英]Why is my variable changing values in recursive call in my C program?

我編寫了一個程序來查找數組中最大的數字。 問題在於,每次遞歸調用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
    }
}

程序返回零作為最大整數。 有任何想法嗎?

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;
}

largest被初始化為0在每個單獨的函數調用,這里有一個快速修復:

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之前返回其值。

每次調用find_largest()時,都在創建一個int maximum局部變量,並將其賦值為零。 因此,當n最終達到零時,它實際上並不關心過去5個遞歸調用所做的事情,它只是返回您剛剛設置為最大的零。 要么使最大的全局值,要么將其作為參數傳遞給函數(可能是更好的做法)。

使int最大= 0; 進入static int maximum = 0; 通過添加靜態變量,最大變量將在整個遞歸中僅初始化一次。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM