La Web del Programador: Comunidad de Programadores
 
    Pregunta:  65843 - SWICH COMPUESTO (CON DOS VARIABLES) EN C
Autor:  Alejandro Caro
como hago un switch compuesto (con dos variables) en c , cuando lo intento me tira error

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(){
double a, b, c, r1, r2, real, compleja, d; //Declaración de variables
int varseleccion;
printf("a = "); printf("b = "); printf("c = ");
printf("Ecuaci¢n: %e.x^2 + %e.x + %e", a, b, c);

switch (varseleccion){ //Ecuación degenerada
case a = 0 && case b = 0: //<-- case label does not reduce to an integer constant
printf("La ecuaci¢n es degenerada");
break;
case a = 0 && case b != 0: //Dos raíces reales iguales //<-- case label does not reduce to an integer constant
r1 = -c / b;
//r2 = r1
printf("r1 = r2 = %e", r1);
break;
default:
d = pow(b,2) - 4 * a * c;

switch (varseleccion){
case d >= 0: //Dos raíces reales diferentes //<-- case label does not reduce to an integer constant
r1 = (pow(-b + (pow(b,2) - 4 * a * c), (1 / 2))) / (2 * a);
r2 = (pow(-b - (pow(b,2) - 4 * a * c), (1 / 2))) / (2 * a);
printf("r1 = %e", r1);
printf("r2 = %e", r2);
break;
default: //Dos raíces complejas conjugadas
real = -b / (2 * a);
compleja = ((pow(b,2) + 4 * a * c), ((1 / 2))) / (2 * a); //<-- warning: value computed is not used|
printf("r1 = %e + %e.i", real, compleja);
printf("r2 = %e + %e.i", real, compleja);
}
}
return 0;
}

  Respuesta:  Capitan Kirk
Estás utilizando mal switch. Su sintaxis es:

switch (nombre_variable)
{
case valor_1:
(codigo);
break;
case valor_2:
(codigo);
break;
default:
(codigo);
break;
}

nombre_variable es la variable de control del switch, y por supuesto que debe haber sido iniciada a algún valor antes de entrar al switch. Cosa que no has hecho, has entrado con varseleccion pero sin haberle asignado un valor previamente.

Los elementos valor_1, valor_2, etc (pueden ser tantos como haga falta) no pueden ser variables, deben ser valores constantes y de tipo entero. Por eso te indica "case label does not reduce to an integer constant". Por supuesto, no puedes utilizar asignaciones, operaciones ni comparaciones: el resultado, aunque sea de tipo entero, no sería una constante de tipo entero.

Para lo que quieres hacer, es mucho más sencillo utilizar comparaciones simples, con if. Por cierto, las comparaciones de igualdad serían

if (a == 0)

sí, con dos signos igual consecutivos (y la condición del if siempre va entre paréntesis), si pones simplemente

if (a = 0)

te va a hacer dos cosas:

1. La variable a pasa a valer 0 (le has hecho una asignacion, no una comparacuion).

2. El resultado de if (a = 0) es siempre verdadero, dado que lo que hay entre paréntesis (que es lo que estás comprobando) es una asignación, que siempre va a poder hacerse.

Otros detalles, relacionados con la lógica de tu programa, son:

Si a == 0 y b != 0, no tienes dos raíces reales, lo que tienes es una ecuación de primer grado con una sola solución. Las dos raíces iguales las tienes en el caso a != 0, b == 0.

Si ya has calculado el discriminante en la variable d (d = pow(b,2)- 4*a*c), no necesitas volverlo a calcular cuando calculas las raíces. Además, tenías la b en el sitio equivocado. Simplemente sería

r1 = (-b + pow(d, (1.0 / 2.0) ) ) / (2 * a)
r2 =

Cuando utilizas para calcular la raíz cuadrada la función pow, estás empleando como exponente la expresión (1/2). Matemáticamente, es correcto, pero al compilar el compilador te va a evaluar el 1 como entero, el 2 como entero, y el resultado de la division entera 1/2 es cero, con lo que al final estás elevando a cero. En las operaciones entre números de distintos tipos (en tu caso, entre int y double) se "promociona" a los de menor rango al mayor rango (es decir, los int, momentáneamente, te los considera como double), pero en este caso, dado que el (1/2) lo tienes entre parentesis, te calcula primero el parentesis como entero (resultado, 0) y luego te lo promociona a double (resultado, 0.0, y no el 0.5 que debería ser). La conclusión de este rollo es que, cuando utilices constantes numéricas que vayan a trabajar con tipos float o double, les añadas detrás el punto decimal. Bastaría con poner (1. / 2.) en lugar de (1/2). El poner el 0 detrás del punto decimal es por legibilidad, para verlo al primer golpe de vista.

De todos modos, tienes una función sqrt para calcular la raíz cuadrada.

Si las raíces no son reales (d < 0), has hecho mal el cálculo de la parte compleja. Simplemente, cambia el signo a d:

d = -d;
compleja = sqrt(d) / (2*a);
printf("r1 = %e + %e.i", real, compleja);
printf("r2 = %e - %e.i", real, compleja);

Saludos,