C 如何计算”之前所有元素的总和;x";元素递归?

C 如何计算”之前所有元素的总和;x";元素递归?,c,C,我正在编写一个程序,递归地计算x元素之前所有元素的摘要。它总是返回0。你能帮我一下吗?当我调用main中的SumBeforeX函数时,你能解释一下它是如何有序工作的吗?。 这是我的密码和密码 #include <stdio.h> int SumBeforeX(int a[], int n, int x) { int i = 0; static int s = 0; if (n == 0) return 0; if (a[i] == x)

我正在编写一个程序,递归地计算
x
元素之前所有元素的摘要。它总是返回0。你能帮我一下吗?当我调用main中的
SumBeforeX
函数时,你能解释一下它是如何有序工作的吗?。 这是我的密码和密码

#include <stdio.h>
int SumBeforeX(int a[], int n, int x)
{
    int i = 0;
    static int s = 0;
    if (n == 0)
        return 0;
    if (a[i] == x)
        s+=SumBeforeX(a, i -1, x) +a[i-1];
    return s;

}
void main()
{
    int a[] = {2,6,13,17,47,8};
    printf("%d",SumBeforeX(a,6,13));
    _getch();
}
#包括
int SumBeforeX(int a[],int n,int x)
{
int i=0;
静态int s=0;
如果(n==0)
返回0;
如果(a[i]==x)
s+=SumBeforeX(a,i-1,x)+a[i-1];
返回s;
}
void main()
{
int a[]={2,6,13,17,47,8};
printf(“%d”,SumBeforeX(a,6,13));
_getch();
}

我猜预期的解决方案有点像这样:

int sumBeforeX(const int *a, int x)
{
    if (x == *a) return 0;           // termination condition
    return *a + sumBeforeX(a+1, x);  // recursive step
}
int sumBeforeX(const int *a, int x)
{
    int sum = 0;                  // accumulator to replace recursion
    while (*a != x) sum += *a++;
    return sum;
}
printf("%d\n", SumBeforeX(a, 6, 13, 0));
要理解这一点,请注意数组不能在C中传递,因此它们在函数参数中的类型将调整为相应的指针类型,并传递指向第一个元素的指针。我在上面的代码片段中明确了这一点,直接编写了指针类型

const
只是一个小小的改进:该函数从不通过这个指针修改数组,所以也要显式地修改它

还要注意此实现如何从不分配任何内容。这是函数式编程的一个典型特性,递归特别适用于函数式编程。函数调用没有副作用


旁注:不要在现实世界的C代码中递归编写,如果幸运的话,编译器会优化递归(在这个简单的例子中,一个好的编译器应该这样做),但这不应该被依赖,如果递归保持不变,性能通常会受到影响,如果递归非常深入,您可能会面临堆栈溢出的风险。因此,为了完整起见,真实世界的代码应该更像这样:

int sumBeforeX(const int *a, int x)
{
    if (x == *a) return 0;           // termination condition
    return *a + sumBeforeX(a+1, x);  // recursive step
}
int sumBeforeX(const int *a, int x)
{
    int sum = 0;                  // accumulator to replace recursion
    while (*a != x) sum += *a++;
    return sum;
}
printf("%d\n", SumBeforeX(a, 6, 13, 0));

我猜预期的解决方案有点像这样:

int sumBeforeX(const int *a, int x)
{
    if (x == *a) return 0;           // termination condition
    return *a + sumBeforeX(a+1, x);  // recursive step
}
int sumBeforeX(const int *a, int x)
{
    int sum = 0;                  // accumulator to replace recursion
    while (*a != x) sum += *a++;
    return sum;
}
printf("%d\n", SumBeforeX(a, 6, 13, 0));
要理解这一点,请注意数组不能在C中传递,因此它们在函数参数中的类型将调整为相应的指针类型,并传递指向第一个元素的指针。我在上面的代码片段中明确了这一点,直接编写了指针类型

const
只是一个小小的改进:该函数从不通过这个指针修改数组,所以也要显式地修改它

还要注意此实现如何从不分配任何内容。这是函数式编程的一个典型特性,递归特别适用于函数式编程。函数调用没有副作用


旁注:不要在现实世界的C代码中递归编写,如果幸运的话,编译器会优化递归(在这个简单的例子中,一个好的编译器应该这样做),但这不应该被依赖,如果递归保持不变,性能通常会受到影响,如果递归非常深入,您可能会面临堆栈溢出的风险。因此,为了完整起见,真实世界的代码应该更像这样:

int sumBeforeX(const int *a, int x)
{
    if (x == *a) return 0;           // termination condition
    return *a + sumBeforeX(a+1, x);  // recursive step
}
int sumBeforeX(const int *a, int x)
{
    int sum = 0;                  // accumulator to replace recursion
    while (*a != x) sum += *a++;
    return sum;
}
printf("%d\n", SumBeforeX(a, 6, 13, 0));
关于:当我在main中调用SumBeforeX函数时,您能解释一下它是如何有序工作的吗

#包括
int SumBeforeX(int a[],int n,int x)
{
int i=0;
静态int s=0;
如果(n==0)
返回0;
如果(a[i]==x)
s+=SumBeforeX(a,i-1,x)+a[i-1];
返回s;
}
void main()
{
int a[]={2,6,13,17,47,8};
printf(“%d”,SumBeforeX(a,6,13));
_getch();
}
第一次执行
SumBeforex()

  • n
    的值为6,因此没有提前退出
  • s的值为0
  • i
    的值为0,因此
    a[i]
    的值为2
  • x
    的值为13
  • 因此,`if(a[i]==x)是假的
  • 因此,不会发生递归
  • 因此0被返回到“main()”
  • 所以打印的值是0
  • 关于:当我在main中调用SumBeforeX函数时,您能解释一下它是如何有序工作的吗

    #包括
    int SumBeforeX(int a[],int n,int x)
    {
    int i=0;
    静态int s=0;
    如果(n==0)
    返回0;
    如果(a[i]==x)
    s+=SumBeforeX(a,i-1,x)+a[i-1];
    返回s;
    }
    void main()
    {
    int a[]={2,6,13,17,47,8};
    printf(“%d”,SumBeforeX(a,6,13));
    _getch();
    }
    
    第一次执行
    SumBeforex()

  • n
    的值为6,因此没有提前退出
  • s的值为0
  • i
    的值为0,因此
    a[i]
    的值为2
  • x
    的值为13
  • 因此,`if(a[i]==x)是假的
  • 因此,不会发生递归
  • 因此0被返回到“main()”
  • 所以打印的值是0
  • 用户3629249给出的答案已经解释了为什么
    SumBeforeX()
    总是返回
    0
    ,Felix Palmen的答案谈到了解决问题的递归和非递归方法。这个答案只是为了让您了解如何使用尾部递归计算
    “x”
    元素之前的和:

    int SumBeforeX(const int *a, int n, int x, int sum)
    {
        if (n == 0) return 0;
        if (x == *a) return sum;
    
        return SumBeforeX(a + 1, n - 1, x, sum + *a);
    }
    
    在这里,您可以看到我向函数
    SumBeforeX
    添加了一个参数
    sum
    ,并将元素的总和累加到其中。你可以这样称呼它:

    int sumBeforeX(const int *a, int x)
    {
        if (x == *a) return 0;           // termination condition
        return *a + sumBeforeX(a+1, x);  // recursive step
    }
    
    int sumBeforeX(const int *a, int x)
    {
        int sum = 0;                  // accumulator to replace recursion
        while (*a != x) sum += *a++;
        return sum;
    }
    
    printf("%d\n", SumBeforeX(a, 6, 13, 0));
    
    似乎您正在学习递归,熟悉尾部递归也很好


    如果函数返回后除了返回其值之外无需执行任何操作,则称函数调用为尾部递归。尾部递归函数可以很容易地转换为迭代函数,因此编译器还可以通过消除递归来优化此类函数的代码,这意味着尾部递归调用在恒定的堆栈空间中运行,也就是说,它们递归调用自己时不需要创建新的堆栈帧。检查以下内容以获得更好的想法:
    1)
    2) 用户3629249给出的答案已经解释了为什么
    SumBeforeX()
    总是返回
    0