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

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

#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);) не сработала?


person helpmepleaseibad    schedule 27.02.2020    source источник
comment
Что, на ваш взгляд, означает эта строка?   -  person ForceBru    schedule 27.02.2020
comment
Вы не можете ничего присвоить возвращаемому значению функции. Это не имеет смысла. Замените последние 2 строки на return factorial(i - 1) * i;.   -  person r3mainer    schedule 27.02.2020
comment
factorial(i) возвращает целое число. factorial(i) = thing; вызовет factorial(i), получит возвращаемое значение и сразу же перезапишет его thing. Не имеет особого смысла   -  person ForceBru    schedule 27.02.2020
comment
Я прочитал все ответы, и я очень ценю помощь. В принципе, то, что я делал, не имело смысла. я вызываю функцию, которая возвращает значение, и присваиваю ее той же функции, которая возвращает значение. Это был беспорядок.   -  person helpmepleaseibad    schedule 27.02.2020
comment
.. компилятор сказал мне, что в следующей строке есть проблемы. [Требуется ссылка] Включите точный текст, который он сообщил.   -  person Jongware    schedule 27.02.2020


Ответы (4)


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/< /а>

person Alex Lop.    schedule 27.02.2020

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

person backspace    schedule 27.02.2020

Потому что в этом фрагменте

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

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

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

    int result = (factorial(i - 1) * i);
    return result;
person Hellmar Becker    schedule 27.02.2020

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

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

person Nick Gkloumpos    schedule 27.02.2020