-3

Al compilar el siguiente programa en CodeBlocks me sale este mensaje:

Ambos números son iguales

Aunque no lo sean. ¿por qué puede suceder eso?

Éste es el código:

#include<iostream>

using namespace std;
 int main(){
 float n1,n2,n3;
 cout<<"Escriba tres numeros: "<<endl;
 cin>>n1>>n2>>n3;


 if ((n1=n2=n3)){
    cout<<"Ambos numeros son iguales";
 }
else if ((n1>n2)and(n1>n3)){
  cout<<"el mayor es: "<<n1;
 }
 else if ((n2>n1)and(n2>n3)){
  cout<<"el mayor es: "<<n2;
 }
 else {cout<<"el mayor es: "<<n3;
 }
 return 0;
}
Alvaro Montoro
  • 48,157
  • 26
  • 100
  • 179
Diego Guillen
  • 63
  • 1
  • 1
  • 4
  • 3
    Porque estás usando `=` en lugar de `==`. Un solo `=` es una asignación en vez de una comparación. Como parte de una expresión booleana, toma el valor `true` si lo asignado es distinto de cero. – abulafia Nov 13 '18 at 21:51
  • un signo de igual `=` es asignar; por ejemplo `a = 10` aqui decimos que a vale 10, por el contrario aqui `10 == 10` verificamos si ambos valores son iguales –  Nov 13 '18 at 22:03

2 Answers2

7

El error está en la condición:

if ((n1=n2=n3))

Porque un = se considera un operador de asignación y lo que intentas es comparar valores y el operador para realizar una comparación sería ==. Además, tienes que recordar que tienes que evaluar los tres por esa razón te escribí esto:

if ((n1==n2 && n1==n3 && n2==n3))

Te comparto tu código, nada más tiene un do..while para que la prueba sea mas fácil de realizar.

Esté sería tu código funcionando:

#include<iostream>

using namespace std;
 int main(){
     float n1,n2,n3;
     int op;
     do
     {
         cout<<"Escriba primer numero: ";
         cin>>n1;
         cout<<"\nEscriba segundo numero: ";
         cin>>n2;
         cout<<"\nEscriba tercer numero: ";
         cin>>n3;


         if ((n1==n2 && n1==n3 && n2==n3)){
                cout<<"\nAmbos numeros son iguales";
            }
        else if ((n1>n2)&&(n1>n3)){
                cout<<"\nel mayor es: "<<n1;
            }
        else if ((n2>n1)&&(n2>n3)){
                cout<<"\nel mayor es: "<<n2;
            }
        else {
                cout<<"\nel mayor es: "<<n3;
            }

            cout<<"\n\n 1 - Salir";
            cout<<"\n 0 - Continuar";
            cout <<"\n\t Opcion: ";
            cin>>op;
    }

    while(op!=1);
    return 0;
}

Pero te recomendaría algo como esto (si lo que intentas es encontrar el mayor):

#include <iostream>

using namespace std;
int main()
{
    int numero, mayor, op;
    do
    {
        cout << "\nIntroduzca el primer n%cmero (entero): ";
        cin >> mayor;
        cout << "\nIntroduzca el segundo n%cmero (entero): ";
        cin >> numero;

        if ( numero > mayor )
            mayor = numero;
         cout << "\nIntroduzca el tercer n%cmero (entero): " ;
         cin >> numero;
        if ( numero > mayor )
            mayor = numero;
         cout << "\n el mayor es: " <<  numero;


        cout<<"\n\n 1 - Salir";
        cout<<"\n 0 - Continuar";
        cout <<"\n\t Opcion: ";
        cin>>op;
    }
    while(op!=1);
    return 0;
}
SourceCode
  • 144
  • 5
  • se te agradece el apoyo pero solo poner código en la respuesta se considera de baja calidad, dale editar y añade la explicación de por que esto es una respuesta –  Nov 13 '18 at 22:21
  • Espero se entienda un poco mejor ahora. – SourceCode Nov 13 '18 at 22:30
  • Solamente lo había escrito más descriptivo. Pero gracias, espero os sea de ayuda. Gracias – SourceCode Nov 13 '18 at 22:41
  • 1
    Se agradece que seas descriptivo en las respuestas. Poner solo la solución y que el resto tenga que adivinar por qué lo tuyo funciona y lo suyo no suele ser de demasiada ayuda – eferion Nov 14 '18 at 07:11
3

La respuesta de SourceCode es muy buena, pero querría añadir detalles que no ha comentado.

Para empezar, quiero señalar un problema semántico: estás comparando TRES números pero tu mensaje de error se refiere a DOS:

cout<<"Ambos numeros son iguales";

El mensaje no debería mencionar Ambos, es muy confuso (y una fuente de errores comunes) que el código diga una cosa y la información que aparece por pantalla diga otra.

Comparaciones.

Seguidamente, como te han señalado, la instrucción (n1=n2=n3) no compara los tres números, esa instrucción se desglosa de derecha a izquierda así:

  1. Asigna a n2 el valor de n3.
  2. Devuelve n2.
  3. Asigna a n1 el valor de n2.
  4. Devuelve n1.

Así que al final de la instrucción los tres números tendrán el valor de n3 pero eso no es lo que hace que se cumpla la condición if ((n1=n2=n3)) si no el hecho de que n1 no es 0.

Al final de la instrucción de doble asignación se devuelve n1 (que ha recibido el valor de n2 que ha recibido el valor de n3) en C++ cualquier expresión numérica puede ser convertida implícitamente a una expresión booleana siguiendo las siguientes normas:

  • Si el valor de la expresión numérica es 0 se considera que su valor booleano es false.
  • Si el valor de la expresión no es 0 se considera que su valor booleano es true.

Por lo tanto, si en tu código hubieses dado valor 0 a n3 no se habría cumplido la condición if ((n1=n2=n3)) ya que n1 (que recibió el valor de n2 que recibió el valor de n3) sería 0 y se consideraría false.

Si quieres comprobar si los tres valores son iguales, basta con comparar el primero con el segundo y el segundo con el tercero usando el operador de comparación (==) (no el de asignación (=)) y enlazando la comparación con un Y lógico (&&):

if (n1 == n2 && n2 == n3)
    cout << "Los números son iguales\n";

Nunca podrás comprobar si los tres valores son iguales encadenando tres operadores de comparación (==):

if (n1 == n2 == n3) // Esto no funciona!

Ya que la instrucción anterior se desglosa de derecha a izquierda así:

  1. Compara n2 (de tipo float) con n3 (de tipo float).
  2. Devuelve un valor booleano.
  3. Compara n1 (de tipo float) con un valor booleano (de tipo bool).
  4. Convierte n1 a bool siguiendo las normas mencionadas antes.
  5. Compara n1 convertido a bool con el booleano de la primera comparación.

De esta manera, si n2 y n3 son iguales y n1 no es 0 se cumplirá la condición aunque n1 sea diferente a n2 y n3.

El máximo.

Es tremendamente confuso encadenar comparaciones para determinar cuál es el mayor de una serie de números, yo aconsejo usar la función std::max , tu código podría quedar así:

#include <iostream>
#include <algorithm>

int main() {
    using namespace std;

    float n1, n2, n3;
    cout << "Escriba tres numeros: \n";
    cin >> n1 >> n2 >> n3;

    if (n1 == n2 && n2 == n3) {
        cout << "Los numeros son iguales\n";
    }
    else {
        cout << "El mayor es: " << max(n1, max(n2, n3)) << '\n';
    }

    return 0;
}

Avanzado.

Si quieres generalizar la comprobación de valores y la búsqueda del máximo para que reciban una cantidad arbitraria de parámetros, podrías usar plantillas variádicas:

template <typename T, typename ... VALORES>
T multi_max(const T &valor, const VALORES & ... valores)
{
    if constexpr (sizeof...(VALORES) == 0)
        return valor;
    else
        return std::max(valor, multi_max(valores ...));
}

template <typename T, typename ... VALORES>
bool todos_iguales(const T &a, const T &b, const VALORES & ... valores)
{
    if constexpr (sizeof...(VALORES) == 0)
        return a == b;
    else if constexpr (sizeof...(VALORES) == 1)
        return a == b && todos_iguales(b, valores ...);
    else
        return a == b && todos_iguales(valores ...);
}

Así:

if (todos_iguales(n1, n2, n3) {
    cout << "Los numeros son iguales\n";
}
else {
    cout << "El mayor es: " << multi_max(n1, n2, n3) << '\n';
}

Otras cosas a tener en cuenta.

A parte de corregir la primera comparación y usar max para buscar el máximo he hecho los siguientes cambios:

  • He movido la cláusula using namespace std; a main. Es una buena práctica evitar usar esa cláusula en el ámbito global, úsala en el ámbito más pequeño posible. Lee este hilo para saber por qué.
  • He substituido std::endl por \n ya que puede causar problemas de rendimiento. Lee este hilo para saber por qué.
  • He añadido mayor separación en los símbolos para dejar al código respirar. En los 90 teníamos pantallas de 80 caracteres de ancho y 25 líneas de alto, por entonces tenía sentido apretujar el código para que cupiera en la pantalla. Hoy día tenemos pantallas enormes y separar las cosas hace que el código sea más legible.
PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82