Me falta algo muy pequeño aquí, no pude entenderlo, solo trato de obtener el factorial del número ingresado, usando una llamada recursiva por concepto de referencia en C ++. Por favor, hágame saber lo que me estoy perdiendo. Declarando algunas variables adicionales para más alteraciones en los programas.

#include <iostream>
using namespace std;
int factorial(int &m);
int factorial(int &m)
{
    int i,result=0;
    
    
    if(m>=1)
    return  m * factorial(m-1);
    else
        return 0;

}

int main(){

    int m,i,factorial1=1;
    
    cout<<"Please enter the number to factor   "<<std::endl;
    cin>>m;
    factorial1=factorial(m);

    cout<<"Factorial value is " << factorial1<<std::endl;
    return 0;
    }

Obteniendo el error de la siguiente manera

factorial_func.cc: In function ‘int factorial(int&)’:
factorial_func.cc:33:25: error: cannot bind non-const lvalue reference of type ‘int&’ to an rvalue of type ‘int’
   33 |  return m * factorial((m-1));
      |                       ~~^~~
factorial_func.cc:27:20: note:   initializing argument 1 of ‘int factorial(int&)’
   27 | int factorial(int &m)
      |               ~~~~~^
c++
0
Jfrd 22 jun. 2020 a las 21:34

3 respuestas

La mejor respuesta

Los errores en su programa:

  1. Intenta vincular una referencia no constante lvalue (más o menos significa una variable que podría asignarse en el lado izquierdo del signo =) de tipo una referencia entera (del argumento) a una {{ X2}} de un entero en la sintaxis:

    return  m * factorial(m - 1);
    
  2. Pasar una referencia no es obligatorio aquí en absoluto. Puede eliminar &.

  3. La instrucción else devuelve un cero en lugar de uno cuando m es menor que 1 y eso le da un resultado inesperado ya que cualquier operación de multiplicación con un cero siempre es un cero.

Deberías probar:

  1. Devolver un entero del argumento directamente en lugar de devolver un valor de referencia.

  2. Debe devolver 1 en lugar de 0 cuando m alcanza menos de 1 en la condición else.

  3. Las variables declaradas en factorial() están totalmente sin usar y son redundantes y i no se usa en main().


Código redefinido:

#include <iostream>

int factorial(int param) {
    if (param >= 1)
        return param * factorial(param - 1); // new * (-1 than new) recursively
    else
        return 1;
}

int main(void) {
    int fact = 1;
    int num;

    std::cout << "Please enter the number to factor: ";
    std::cin >> num;

    fact = factorial(num);

    std::cout << "Factorial is: " << fact << std::endl;

    return 0;
}

Después de corregir los errores, obtendrá resultados como:

$ g++ -o prog prog.cpp; ./prog
Please enter the number to factor: 5 // --- INPUT
Factorial is: 120 // --- OUTPUT
2
Rohan Bari 22 jun. 2020 a las 19:34

La respuesta de Dude es correcta, no es necesario aplicar una referencia de valor como argumento, un valor de pasar por (r) es correcto, esto se aplica como un consejo general para la funcionalidad recursiva para evitar efectos secundarios. Más grave es una falla: ¡el factorial de 0 no es 0, pero por definición es 1! Si esto suena ilógico, vea la discusión en https : //www.quora.com/Why-does-zero-factorial-0-equal-one-1-1

@Dorian: Es fácil ahorrar 2 llamadas recursivas al abordar los factoriales de 0 1 2:

int factorial(int m)
{
    if (m > 2)
        return  m * factorial(m - 1);
    else if (m == 0)
        m = 1;
    return m;
}
1
Lois 24 jun. 2020 a las 17:41

Aquí está tu código de trabajo. Algunos consejos:

  1. por qué no usar using namespace std

  2. Debe pasar 1 en el último factorial, de lo contrario su resultado se multiplica por 0 y eso es 0, por lo que no funcionará

  3. si solo pasa int s individuales, puede pasarlos más fácilmente por valor (le da menos problemas al principio). PERO: en cualquier caso, pasar por referencia aquí es incorrecto, porque no desea que cambie el valor original, pero en la recursividad desea tener un valor de RETORNO.

  4. con respecto a su error original: está intentando vincular un rvalue (un valor que SÓLO se encuentra en el lado derecho de una ecuación) a una referencia de lvalue (&m ), que no puede hacer, ya que si está cambiando la referencia lvalue , no puede cambiar el lado derecho de la ecuación. Puede usar referencias rvalue (&&m), pero esto es bastante avanzado C++ y tal vez debería leer aquí primero para tener una idea de lo que está tratando.

#include <iostream>
int factorial(int m);
int factorial(int m)
{    
    if (m >= 1)
       return  m * factorial(m-1);
    else
       return 1;

}

int main(){

    int m, factorial1 = 1;
    
    std::cout << "Please enter the number to factor" <<std::endl;
    std::cin >> m;
    factorial1=factorial(m);

    std::cout<<"Factorial value is " << factorial1 << std::endl;
    return 0;
}
1
Dorian 23 jun. 2020 a las 09:07