Может кто-нибудь объяснить мне, почему мой код факторной рекурсии не может быть скомпилирован - PullRequest
0 голосов
/ 27 февраля 2020

Я сделал простую программу для вычисления факториала числа. Ниже приведен код.

#include <stdio.h>

int factorial(int i);

int main(void)
{
    int i;
    printf("Factorial of: ");
    scanf("%i", &i);
    printf("Answer: %i\n", factorial(i));

}

int factorial(int i)
{
    if (i == 0)
    {
        return 1;
    }

    factorial(i) = (factorial(i - 1) * i);
    return factorial(i);
}

компилятор сказал мне, что в следующей строке есть проблемы

factorial(i) = (factorial(i - 1) * i);

, поэтому я изменил приведенную выше строку на следующую, и она заработала

int a = (factorial(i - 1) * i);
return a;

Итак, кто-то может объяснить мне, почему не сработала начальная строка (factorial (i) = (factorial (i - 1) * i);)?

Ответы [ 4 ]

2 голосов
/ 27 февраля 2020
factorial(i) = (factorial(i - 1) * i);

Эта строка недопустима с точки зрения C стандарта. Он связан с определением lvalue и rvalue.

lvalue - это выражение, относящееся к объекту. Имя 'lvalue' происходит из выражения присваивания E1 = E2, в котором левый операнд E1 должно быть выражением lvalue.

rvalue - это выражение, которое не является lvalue (я не могу найти его точное определение). Другими словами, rvalue нельзя переназначить.

Пример:

int n;
...
n = 3; // --> Legal, n is an lvalue and 3 is an rvalue
3 = n; // --> illegal, 3 is rvalue and thus n cannot be assigned to it

Другой пример

int a, b, c;
...

a = b + c; // --> Legal since 'a' is an lvalue (refers to an object/memory)
/* Note that 'b' is also lvalue, 'c' is also lvalue BUT 'b + c' is an rvalue expression! */
/* the temporal storage allocated for the result of the expression 'b + c' cannot be "visible" */
/* one cannot check the address of such expression: &(a + b) ==> illegal */
b + c = a; // --> Illegal

В вашем примере factorial(i) представляет возвращаемое значение функции, которое является rvalue.

Для более подробной информации: https://www.embedded.com/lvalues-and-rvalues/

1 голос
/ 27 февраля 2020

Это потому, что в этом фрагменте

    factorial(i) = (factorial(i - 1) * i);
    return factorial(i);

во всех местах, где упоминается factorial(i), это всегда будет интерпретироваться как попытка вызова функции еще раз.

Исправить это, введите временную переменную:

    int result = (factorial(i - 1) * i);
    return result;
1 голос
/ 27 февраля 2020

factorial(i) = (factorial(i - 1) * i);

Вы пытаетесь присвоить целое число при вызове функции. Когда вы пишете factorial(i), вы говорите системе вызвать функцию факториала и вернуть значение. Вы не можете присвоить значение этому значению.

1 голос
/ 27 февраля 2020

Просто потому, что вы не можете присвоить значение вызову функции в C. factorial(i) вызывает функцию (которая, между прочим, приведет к бесконечной рекурсии), и вы пытаетесь присвоить значение этому вызову, что невозможно. В некоторых других языках это способ вернуть значение, но не в C.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...