C中偶数数组的递归

Recursion for even array in C

我知道这里甚至有很多关于递归的问题,但我不知道在 C 中它是我的逻辑还是我的语法错误(或者可能两者都是错误的),因为据我所知我可能需要指针。特别是当我在 C 中使用函数时,所以我很难找到任何我作为 cs 本科生新生可以理解的问题。

所以我的任务是简单地创建一个数组,其中包含在输入中确定的范围内的偶数,如果输入 n = 10,则该数组需要包含 [0, 2, 4, 6, 8, 10],如果 n = 9,则该数组将只是 [0, 2, 4, 6, 8]。但是我必须用递归来做,我不知道我的代码有什么问题,因为输出有点奇怪。

#include <stdio.h>

int even(int x, int arrEven[]) {

    if (x == 0) {
        arrEven[0] = 0;
        return 0;
    }
    else if (x > 0) {    
        arrEven[x - 1] = even(x - 2, arrEven) + 1;
        return arrEven[x - 1];
    }
}

int main(void) {

    printf("n = ");
    int n;
    scanf("%d", &n);
    n = (n / 2) + 1;
    int arrEven[n];
    even(n, arrEven);

    for (int i = 0; i < (n - 1); i++) {
        printf("%d, ", arrEven[i]);
    }
    printf("%d", arrEven[n - 1]);
}

当我输入 10 时,输出是

0, 1, -731908444, 2, 781232032, 3

而不是

0, 2, 4, 6, 8, 10

您混合使用一个变量用于两个目的。 在您的代码中,n 用作数组中的索引,同时用作要放入数组中的值。

有很多选择可以做到这一点。可能看起来像这样:

#include <stdio.h>

void even(int *arrEven, int value, int limit) {

    *arrEven = value;

    if (value < limit) {
        even(arrEven+1, value+2, limit);
    }
}

int main (void) {
    int limit;
    int count;

    printf("n = ");
    scanf("%d", &limit);
    // TODO: Check return value.
    if (limit < 0)
    {
      fprintf(stderr, "Only non-negative limits are allowed.\n");
      exit(-1);
    }

    count = (limit / 2) + 1;
    int arrEven[count];

    even(arrEven, 0, limit);

    for (int i = 0; i < count-1; i++){
        printf("%d, ", arrEven[i]);
    }
    printf("%d\n", arrEven[count-1]);
}

我想你想要的是这样的:

int even(int x, int arrEven[])
{
    if (x == 0)
        return 0;
    arrEven[x - 1] = even(x - 1, arrEven);
    return arrEven[x - 1] + 2;
}

这里x纯粹是数组索引,只有偶数值进入数组的事实是由2添加到[=13=返回的值这一事实处理的] 以及返回 0.

的终止条件

您的递归函数只初始化目标数组的一半,因为在 arrEven[x - 1] = even(x - 2, arrEven) + 1; 中您将 x 递减 2,而不是将值递增 2。您可以这样修复您的代码:

int even(int x, int arrEven[]) {

    if (x == 0) {
        arrEven[0] = 0;
        return 0;
    } else
    if (x > 0) {    
        arrEven[x - 1] = even(x - 1, arrEven) + 2;
        return arrEven[x - 1];
    }
}

但是请注意,上面的代码不使用尾递归,并且需要与 x 成比例的堆栈深度。这是一个替代方案,其中递归仅在从函数返回之前发生:

void even(int n, int arrEven[]) {
    if (n > 0) {
        errEven[n - 1] = 2 * (n - 1);
        even(n - 1, arrEven);
    }
}

以上函数应编译为与等效迭代版本类似的可执行代码:

void even(int n, int arrEven[]) {
    while (n > 0) {
        n = n - 1;
        errEven[n] = 2 * n;
    }
}