【问题标题】:Recursion using local variable, which is only visible from one "function-part"使用局部变量进行递归,仅在一个“函数部分”中可见
【发布时间】:2015-01-02 00:02:27
【问题描述】:

假设我在 C 中有以下函数:

#include <stdio.h>
int sum(int n);
int main(){
    int num,add;
    printf("Enter a positive integer:\n");
    scanf("%d",&num);
    add=sum(num);
    printf("sum=%d",add);
}
int sum(int n){
    int temp;
    temp += 2;
    printf("Temp is : %i", temp);
    if(n==0)
       return n;
    else
       return n+sum(n-1);    /*self call  to function sum() */
}

我的问题是我只想在循环的第一级做temp += 2;。所以我希望它只对 sum 的第一个循环是本地的,而不是对所有被调用的 sum 函数本身。所以为了让问题更清楚一点:在递归函数中定义的变量是否仅在递归“树”的第一部分本地?很难解释我的问题,所以如果你不明白,请询问。谢谢!

编辑:在总和中添加了 printf。所以我想要的输出是: 温度是:2 温度是:2

但我认为会发生的是:

温度是:2 温度是:4 等等……

编辑 2:对于想要尝试硬代码的人,这里是:(我的问题实际上是,一旦声明 ar_in[i]+ space_fill == lw &amp;&amp; used[i] == 0 为真,我想执行之后声明的所有内容 @ 987654324@语句,直到return 1;再一路返回到函数search_combi。注意:ar_in[]数组是几个数的数组,例如{10,80,70,60,80})

bool search_combi(int ar_in[], int index){
    if (ar_in[index] == lw){
        used[index] = 1;
        comb[combcount][0] = index;
        return 1;
    } else{
        tempcomb[0] = index;
        tempcombcount++;
        space_fill = ar_in[index];
        //search right of element
        search_right(index+1, ar_in);
        return 0;
    }

}

int search_right(int start, int ar_in[]){
    int i, j;
    int temp_space_fill = space_fill;
    printf("Tempspace = %i \n", temp_space_fill);
    if(choose == 1) {
        choose = 0;
        return 1;
    }
    if(start == cn){
        return 1;
    }else{
        for(i = start; i < cn; i++){
             space_fill = temp_space_fill;
             if(choose == 1) {
                break;
             }
            if (ar_in[i] + space_fill == lw && used[i] == 0){
                tempcomb[tempcombcount] = i;
                for(j = 0; j <= tempcombcount; j++){
                    comb[combcount][j] = tempcomb[j];
                    used[tempcomb[j]] = 1;
                }
                combcount++;
                memset(tempcomb, 0 , sizeof(tempcomb));
                tempcombcount = 0; 
                space_fill = 0;
                temp_space_fill = 0; 
                choose = 1;             
                return 1;
            } else if (ar_in[i] + space_fill < lw && used[i] == 0){
                space_fill += ar_in[i];
                tempcomb[tempcombcount] = i;
                tempcombcount++;
            }
            search_right(i+1, ar_in);
        }

    }
    return 1;
}

【问题讨论】:

  • 您的代码中未使用此局部变量。所以举一个你确实需要一个局部变量的例子。
  • int temp; temp +=2; 嗯。你认为你要添加什么2
  • 局部变量 'temp' 未初始化为任何值。使用未初始化的变量执行数学运算是未定义的行为。

标签: c function variables recursion scope


【解决方案1】:

局部变量位于堆栈中,因此在递归函数中,每次调用都会创建一个新变量,例如

void recursion( void )
{
     int depth = 0;
     if( depth < 10 ) {
          depth++;
          recursion();
     }
}

将导致无限循环,因为每次递归调用都会在堆栈上创建一个新的depth 并使用0 对其进行初始化。

你可以通过包装实际的递归来解决这个问题。像这样:

 void recursion( void )
 {
     int depth = 0;
     recursion_internal( &depth );
 }

 void recursion_internal( int *depth )
 {
     if( *depth < 10 ) {
          (*depth)++;
          recursion_internal( depth );
     }
 }

我希望更一般的例子能有所帮助。

【讨论】:

    【解决方案2】:

    首先,我认为您不了解递归的实际工作原理。无论我如何理解您的问题,我都会说,如果您希望 temp+=2; 只被阅读一次,那么请在 #include"stdio.h" 下方声明它

    <code>
    #include"stdio.h"
    int temp=0;
    temp+=2;
    </code>
    

    还要了解递归,您可以访问此站点:http://pages.cs.wisc.edu/~vernon/cs367/notes/6.RECURSION.html

    在本站使用System.out.println("To print a text : ");,与

    相同

    printf("To print a text : "); in c.

    希望这对你有点帮助。

    【讨论】:

    • 嗯,我其实理解它,但我正在处理一个非常复杂的递归函数,但是这里发布它太长了,所以我试着做一个更简单的例子。如果你愿意,我可以发布整个代码..
    【解决方案3】:

    一般的方法是使用具有静态存储持续时间的局部变量。在第一次递归调用时,它例如等于零。如果它等于零,那么您将其设置为某个值。所有其他递归调用检查变量是否等于零。如果不是,那么他们不会改变它。当递归结束时,您需要再次将此变量设置为零。

    这是一个例子

    int sum( int n )
    {
        static int temp;
    
        if ( temp == 0 ) temp += 2;
    
        printf( "Temp is : %i", temp );
    
        if ( n == 0 )
        {
           return temp = 0;
        }
        else
        {
           return n + sum( n-1 );    /*self call  to function sum() */
        }
    }
    

    这是一个更有趣的例子

    #include <stdio.h>
    
    unsigned int sum( unsigned int n, char c )
    {
        static char dot;
    
        if ( dot == 0 ) dot += c;
    
        printf( "%c", c );
    
        if ( n == 0 )
        {
           return dot = 0;
        }
        else
        {
           return n + sum( n - 1, c );    /*self call  to function sum() */
        }
    }
    
    int main(void) 
    {
        printf( "%u\n", sum( 10, '.' ) );
        printf( "%u\n", sum( 10, '*' ) );
    
        return 0;
    }
    

    输出是

    ...........55
    ***********55
    

    【讨论】:

    • 另一种使递归函数在第一次(或其他)递归时表现不同的方法是传递一个名为level 的参数,您可以在每次递归时递增该参数,例如使用sum(n-1, level+1); 递归。 (您也可以使用level 来限制递归深度。)但是您最好调用一级函数,然后调用递归函数。
    • @Weather Vane 严格来说这不是递归。它是一个调用递归函数的单独函数。
    • 对不起,@Vlad 我以为这就是我写的。
    猜你喜欢
    • 2012-01-23
    • 1970-01-01
    • 2022-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    相关资源
    最近更新 更多