Unexpected output using the switch statement for this complex logic - c

I am trying to use a switch statement for 3 conditions. Conditions were:
When a, b, and c are all zero, any value of x is a solution. Print: Any value of x is a solution.
When a and b are zero and c is not, no solution exists. Print: No solution exists.
When a is zero and b is not zero, the only solution is x = -c/b. Calculate the value of x and print the solution.
When I tried to run my program, it displayed the wrong results. My input were
a = 0
b = 0
c = 0
So it's supposed to print "Any value of x is a solution", but it didn't.
My program is:
#include <stdio.h>
//Function declarations
void getData (int* a, int* b, int* c);
float calculateX (int a, int b, int c);
//===================================================
int main (void)
{
//Local declarations
int a;
int b;
int c;
float x;
//Statements
getData (&a, &b, &c);
calculateX (a, b, c);
int temp;
printf("\nEnter an integer and press enter to exit the program: ");
scanf("%d", &temp);
return 0;
}
//----------------------------------------------------
void getData (int* a, int* b, int* c)
{
printf("Enter three integers: ");
scanf("%d %d %d", a, b, c);
return;
}
//----------------------------------------------------
float calculateX (int a, int b, int c)
{
float x;
printf("Input is: %d %d %d\n", a, b, c);
switch(a, b, c)
{
case 1: (a, b, c == 0);
printf("Any value of x is a solution.");
break;
case 2: (a, b == 0 && c!= 0);
printf("No solution exists.");
break;
case 3: (a == 0 && b!= 0);
x = (float)(-c/b);
printf("The value of x is: %.1f", x);
break;
default: printf("Cannot calculate.");
}
return a, b, c;
}
And my output was:
Enter three integers: 0 0 0
Input is: 0 0 0
Cannot calculate.
Enter an integer and press enter to exit the program:

This is not how a switch statement works. It compiles, but for very obscure reasons. Obviously, it doesn't do what you expect when it runs.
Generally speaking, you use a switch statement on a single expression, and each of the case labels represents one possible value of that expression. e.g.:
switch (x)
{
case 1:
// Code here runs when x == 1
break;
case 2:
// Code here runs when x == 2
break;
default:
// Code here runs for all other values of x
break;
}
In your application, you want to test multiple variables, and combine them in complex ways. There is no neat way to do that with switch. You should consider a set of if statements instead.

Is there any reason you have to use switch? Just do
if (a == 0 && b == 0 && c == 0)
...
else if (a == 0 && b == 0 && c != 0)
....
...

Actually, here's a valid way to use the switch statement for this problem:
switch ((a != 0) * 4 + (b != 0) * 2 + (c != 0))
{
case 0: // a, b, c == 0
printf("Any value of x is a solution.");
break;
case 1: // a, b == 0 && c!= 0
printf("No solution exists.");
break;
case 2: // a == 0 && b!= 0
case 3:
x = (float)(-c/b);
printf("The value of x is: %.1f", x);
break;
default:
printf("Cannot calculate.");
}
I've based this on your code, except that I use conditionals (which evaluate to 0 or 1) to encode the state of each variable (zero or not, respectively) in the expression, assigning each to a separate bit. The switch then decodes it -- the interesting part for you, as a beginner, is that case 2 falls through to case 3 because we don't care whether c is zero.
Your code has some other issues, but I'm restricting myself to the switch that you asked about. Best of luck.

Related

Infinite loop error in for loop in c programming when writing code to find out gcd

so i tried writing a program to find gcd of two numbers. but the output comes out as an infinite loop. I don't understand why this is happening. Can someone please explain why the output is an infinte loop?
Output comes out as 1818181818...
when i run the code
1 being "t"
and 8 being the second integer 8
which I printed to see if the code is printing anything because no output was showing without these before i printed "b" and "t".
I just want why the output is an infinite loop.
I am new to c programming.
below is the code i typed:
// Write a program to find the HCF of two integers entered by the user.
#include <stdio.h>
int main()
{
int a, b, hcf, t, f1, f2;
printf("enter the first integer");
scanf("%d", &a);
printf("enter the second integer");
scanf("%d", &b);
for (t = 1; t <= a / 2; a++)
{
if (a % t == 0)
{
f1 = t;
printf("%d",f1);}
if (b % f1 == 0)
{printf("%d",b);
hcf = f1;
}
}
printf("%d", hcf);
}
output:
enter the first integer6
enter the second integer8
18181818181818181818181818...
t is always 1 , while a is incrementing , so the condition of loop t <= a/2 is always true
and because t is 1 , the condition of a % t == 0 is always true also , so it prints the value of f1 that is 1.
Then the next condition b % f1 == 0 while f1 gets have the value 1 this condition is true also , so it prints the value of b (it's the 8 in your case)
try :
#include <stdio.h>
int main(){
int a , b , gcd ;
printf("the first indicator :");
scanf ("%d",&a);
printf("the second indicator :");
scanf("%d",&b);
int min = a < b ? a : b ;
for(int i=1;i<min;i++){
if( ( a % i == 0 ) && ( b % i == 0 ) ){
gcd = i ;
printf(" the number %d is a commun devisor of %d and %d \n",gcd, a, b);
}
}
if( gcd != 1 )
printf("the GCD of %d and %d is %d",a,b,gcd) ;
else
printf(" there is no GCD of %d and %d",a,b) ;
return 0;
}

C Newbie/ not understanding what might the problem be

since im learning C language i decided to make a simple program that adds, substracts and calculates the product of two variables . Depending on users' input whether its 1,2 or 3 to choose addition/substraction/folding.
#include <stdio.h>
int main (void) {
int a, b, c, d, e, f, g;
a=19; b=11; c=a+b; d=a-b; e=a*b; f=-1;
while (f<0 && f>3) {
printf("-press 1 to calculate the sum of a and b\n");
printf("-press 2 to calculate the difference between a and b\n");
printf("-press 3 to calculate the product of a and b\n");
scanf("%d\n",&g);
f=g;
return;
}
if (f == 1) {
printf("A+B= %ls\n", &c);
} else if (f == 2) {
printf("A-B= %ls\n", &d);
} else if (f == 3) {
printf(" A*B= %ls\n", &e);
}
return 0;
}
When i run the program its reads "g" and then it stops.
any suggestions to why is this happening
btw i also tried removing the while statement.
I think you mean the following while loop
while ( f < 0 || f > 3 )
{
printf("-press 1 to calculate the sum of a and b\n");
printf("-press 2 to calculate the difference between a and b\n");
printf("-press 3 to calculate the product of a and b\n");
scanf( "%d", &g );
f = g;
}
That is pay attention to 1) the condition of the while loop, 2) removed the return statement and 3) removed the character '\n' in scanf because it is redundant.
And in printf calls remove the operator & and use the conversion specifier %d.
if ( f == 1 ) {
printf(" A+B= %d\n", c) ;
}
else if ( f == 2) {
printf(" A-B= %d\n", d );
}
else if ( f == 3 ) {
printf(" A*B= %d\n",e );
}
I fixed you code and added some comments to it. Hope you can understand it! If you have questions, just comment them.
#include <stdio.h>
int main (void) {
// values can be given to ints by int a = value
int a = 19, b = 11, c, d, e, f = -1, g;
// '||' means OR, while '&&' means AND.
// A value can't be smaller then and bigger then 3 at the same time
while (f < 0 || f > 3) {
printf("-press 1 to calculate the sum of a and b\n");
printf("-press 2 to calculate the difference between a and b\n");
printf("-press 3 to calculate the product of a and b\n");
scanf("%d", &g); //you don't need \n for scanf
f=g;
// return stops the program. In this case, this is not what you want
}
// For printf you don't need &e, &f, etc.
// Instead of calculating a value and storing it in a different int,
// you can just print the outcome of the calculation.
if (f == 1) {
printf("A + B = %d\n", a + b);
} else if (f == 2) {
printf("A - B = %d\n", a - b);
} else if (f == 3) {
printf(" A * B = %d\n", a * b);
}
return 0;
}
Try this:
while (f<0 && f>3){
printf("-press 1 to calculate the sum of a and b\n");
printf("-press 2 to calculate the difference between a and b\n");
printf("-press 3 to calculate the product of a and b\n");
scanf("%d\n",&g);
f=g;
// remove the "return" from here;
}
Also change :
printf(" A+B= %ls\n",&c);
To:
printf(" A+B= %d\n",c);
You don't need the '&' operator to print values, if used it will print the address and not the resultant value.
I would like to add that you could replace your if/else if statements with the switch/case . To be more specific (after changing some small mistakes in your code %d instead %ls and so on) the section of your code should look like this:
// code above
switch(f) {
case 1:
printf(" A+B= %d\n", c) ;
break; // if you want the program to stop after doing this operation
case 2:
printf(" A-B= %d\n", d );
break;
case 3:
printf(" A*B= %d\n",e );
break;
// default: // if the input is not one of the above(1,2 or 3)
// printf(" Please give a valid option. \n");
// break;

How to convert if to switch-case in c

if(a > b)
{printf("%d is greater than %d", a, b);}
else if( a < b )
{printf("%d is greater than %d", b, a);}
else
{printf("%d is equal to %d", a, b);}
How do I convert an if statement to a switch-case in C?
I'm trying, but i don't know the answer to this problem
switch statements are used to test an input expression against a finite set of possible values.
You're trying to compare two variables. This is not a use case for switch.
Your if / else if chain is fine.
switch ((a < b) - (a > b)) {
case -1:
printf("%d is greater than %d", a, b);
break;
case 1:
printf("%d is greater than %d", b, a);
break;
default:
printf("%d is equal to %d", a, b);
}
joke :
switch ((a > b) ? 1 : ((a == b) ? 0 : -1)) {
case 1:
printf("%d is greater than %d", a, b);
break;
case 0:
printf("%d is equal to %d", a, b);
break;
default:
printf("%d is greater than %d", b, a);
}
You're stumbling on a three way comparison here.
You could write switch ((a < b) - (a > b)) { with -1, 0 and +1 as the case labels for a < b, a == b, and a > b respectively. Note that you need the parentheses since binary - has a higher precedence than < or >.
In C++ that expression has been encapsulated in the three way comparison operator <=> and you could write, simply
switch (a <=> b){
with the case labels as before. As far as I know there is no proposal to include that operator in C.

Bermudez C Chapter 5 P 2: No use of arrays or loops for ascending order

Going through Bermudez's C Programming Tutorial (supplement to KN King's book), and perplexed by the second question of Chapter 5 (Selection Statements).
The problem is as follows: write a program that will read in five values and write them out in ascending order.
The very budding programmer is not allowed to use arrays or loops. The only available tools are "if" and "switch" statements.
Here is my issue: I solved the problem by brute force--it's super inelegant. One guess is that I am supposed to feel upset about this exercise; that is, maybe Bermudez wants to show the reader that one needs to do 5! permutations when solely relying on "if" and/or "switch" statements.
Another guess (and probably the more likely one) is that I am doing something really wrong. Something tells me I can cut this code at least in half.
Any suggestions?
This might be really cheating but it can be done with a tiny bit of code in a Sorting Network.
#include <stdio.h>
int main()
{
int a, b, c, d, e, temp;
printf("Program 5.2: Ascending Order of Values\n");
printf("======================================\n\n");
printf("Enter first value: ");
scanf("%d", &a);
printf("Enter second value: ");
scanf("%d", &b);
printf("Enter third value: ");
scanf("%d", &c);
printf("Enter fourth value: ");
scanf("%d", &d);
printf("Enter fifth value: ");
scanf("%d", &e);
printf("\nRe-arranged in ascending order: \n");
printf("===============================\n\n");
/* Sorting Network - 9 comparators */
if (a > b) { temp = a; a = b; b = temp; } // 0,1
if (d > e) { temp = d; d = e; e = temp; } // 3,4
if (c > e) { temp = c; c = e; e = temp; } // 2,4
if (c > d) { temp = c; c = d; d = temp; } // 2,3
if (a > d) { temp = a; a = d; d = temp; } // 0,3
if (a > c) { temp = a; a = c; c = temp; } // 0,2
if (b > e) { temp = b; b = e; e = temp; } // 1,4
if (b > d) { temp = b; b = d; d = temp; } // 1,3
if (b > c) { temp = b; b = c; c = temp; } // 1,2
printf("%d %d %d %d %d\n", a, b, c, d, e);
return 0;
}
Demo on ideone.com
I have an algorithm, but it cheats with recursion.
it uses O(n) stack, and O(n^2) time complexity.
#include <stdio.h>
#include <stdbool.h>
bool sorted;
void sort(int a, int b, int c, int d, int e) {
if (sorted) return;
if (a <= b && b <= c && c <= d && d <= e) {
printf("%d %d %d %d %d\n", a, b, c, d, e);
sorted = true;
} else {
if (a > b) sort(b, a, c, d, e);
if (b > c) sort(a, c, b, d, e);
if (c > d) sort(a, b, d, c, e);
if (d > e) sort(a, b, c, e, d);
}
}
int main() {
sorted = false;
sort(5, 4, 2, 3, 1);
return 0;
}
About the BF algorithm, maybe comparing 2 numbers a time may lead to some simplicity. Many algorithms lead to a tree traversal, there are many factors about the efficiency, like pruning, branch-choosing, etc.
UPD
So, for this very problem, there're total 5!=120 situations. So 120 if else could have solve it...
if (a <= b && b <= c && c <= d && d <= e)...
else (b <= a && b <= c && c <= d && d <= e)...
My solution is not as elegant as #Blastfurnace's but I thought you should just compare each element to everyone else, and decide it's final location using that compare (kinda like quicksort). It's still a fair amount of code, but I think it's easier to understand and simpler...
Time complexity: n*(n-1) [count] + n^2 [switch] == 2*(n^2) - n < n! [for big numbers (such as 5 :) )]
space comlexity: n [initial variables] + n[count] + n[first,second...] = 3n
int main()
{
int a,b,c,d,e;
scanf("%d",&a);
scanf("%d",&b);
scanf("%d",&c);
scanf("%d",&d);
scanf("%d",&e);
int a_count = 0;
int b_count = 0;
int c_count = 0;
int d_count = 0;
int e_count = 0;
int first,second,third,fourth,fifth;
if(a>b)
++a_count;
if(a>c)
++a_count;
if(a>d)
++a_count;
if(a>e)
++a_count;
if(b>a)
++b_count;
if(b>c)
++b_count;
if(b>d)
++b_count;
if(b>e)
++b_count;
if(c>a)
++c_count;
if(c>b)
++c_count;
if(c>d)
++c_count;
if(c>e)
++c_count;
if (d>a)
++d_count;
if (d>b)
++d_count;
if (d>c)
++d_count;
if (d>e)
++d_count;
if (e>a)
++e_count;
if (e>b)
++e_count;
if (e>c)
++e_count;
if (e>d)
++e_count;
switch(a_count){
case 0:
first = a;
break;
case 1:
second = a;
break;
case 2:
third = a;
break;
case 3:
fourth = a;
break;
case 4:
fifth = a;
break;
}
switch(b_count){
case 0:
first = b;
break;
case 1:
second = b;
break;
case 2:
third = b;
break;
case 3:
fourth = b;
break;
case 4:
fifth = b;
break;
}
switch(c_count){
case 0:
first = c;
break;
case 1:
second = c;
break;
case 2:
third = c;
break;
case 3:
fourth = c;
break;
case 4:
fifth = c;
break;
}
switch(d_count){
case 0:
first = d;
break;
case 1:
second = d;
break;
case 2:
third = d;
break;
case 3:
fourth = d;
break;
case 4:
fifth = d;
break;
}
switch(e_count){
case 0:
first = e;
break;
case 1:
second = e;
break;
case 2:
third = e;
break;
case 3:
fourth = e;
break;
case 4:
fifth = e;
break;
}
printf("%d %d %d %d %d\n", first,second,third,fourth,fifth);
return 0;
}
One last thing: every solution here will not be as simple and elegant as using a simple loop. I do think Bermudez intended to show how to work around such basic capabilities of the language, but to make you keep in mind that this workaround is very not comfortable :)

How to optimise my C code to solve quadratic equations in R?

I just wanna know how I can optimize my C code. My program works fine, I tested it with many different values, all is good. However, I'd like to reduce the number of lines and write my program in better quality.
Here's the source code:
#include <stdio.h>
#include <math.h>
int main(void) {
float a,b,c,x,x1,x2;
printf("aX^2 + bX + c = 0\n");
printf("Type the value of a: ");
scanf("%f", &a);
printf("Type the value of b: ");
scanf("%f", &b);
printf("Type the value of c: ");
scanf("%f", &c);
if ( a!=0 && b!=0 && c!=0){
float delta = b*b - 4*a*c;
if (delta>0){
x1 = (-b-sqrt(delta))/(2*a);
x2 = (-b+sqrt(delta))/(2*a);
printf("Solutions are x1 = %f and x2 = %f\n",x1,x2);
}
else if (delta == 0){
x = -b/(2*a);
printf("One unique solution is x = %f\n", x);
}
else {
printf("No solutions !\n");
}
}
if ( a==0 && b!=0 && c!=0)
printf("One unique solution x = %f\n", -c/b);
if ( a==0 && b==0 && c!=0)
printf("No solutions !\n");
if ( a==0 && b==0 && c==0 )
printf("Set of solutions is R\n");
if (a!=0 && b==0 & c!=0) {
x = -c/a;
if(x>=0)
printf("Two soltions x = %f et -x = %f\n", sqrt(x),-sqrt(x));
else{
printf("No solutions !\n");
}
}
if (a!=0 && b==0 && c==0)
printf("One unique x = 0\n");
}
One small optimization: use else if instead of all raw ifs. This will avoid unnecessary comparisons after one if condition is matched.
You can also experiment with the order of the if statements. If any conditions are more often to be true for your use cases, then they should be first.
Since you are basically building a state machine, let's actually do so:
int state = (a == 0) ? 0 : 1;
state |= (b == 0) ? 0 : 2;
state |= (c == 0) ? 0 : 4;
switch(state)
{
case 0: // All co-efficents 0 Domain R print
break;
case 1: // Only a coefficient: 0 case
break;
case 2: // Only b coefficient 0 case.
break;
case 3: // a and b coefficient case - one root 0, other linear.
break;
case 4: // Only c case - no solutions
break;
case 5: // a and c case
break;
case 6: // b and c case (linear)
break;
case 7: // a,b,c all here - do full quadratic solve.
break;
default:
// This should never happen - assert and exit.
break;
}
This way, all your cases are explicitly defined. Each case could also then call a function. Or, one step further, an array of function pointers for each case, fully and properly named.
1) Some of the parts of calculations are being repeated. Break the calculations into smaller pieces, store the results in variables, and use them to build your needed results.
2) You can avoid the special handling of the case a!=0 && b==0 & c!=0 entirely (albeit you need to change some of the other tests).
3) Some operations (e.g. prompting and reading) are repeated. Do these in a function which takes an argument (e.g. a string for prompt).
4) The first line where you are printing "No solutions" there are actually complex or imaginary solutions. The second place is another type of solution.
5) Possibly break some of the repeated calculations (point 1) into separate functions too.
6) Slightly advanced: your code will not deal well with a user who enters rubbish (non-numeric) input.
You can use this example to optimise your code:
#include <stdio.h>
#include <math.h>
int main()
{
double a, b, c, determinant, root1,root2, realPart, imaginaryPart;
printf("Enter coefficients a, b and c: ");
scanf("%lf %lf %lf",&a, &b, &c);
if(a==0 && b!=0 && c!=0){
root1 = -c/b;
printf("linear equation root = -c/b = %.2lf", root1);
}else{
determinant = b*b-4*a*c;
// condition for real and different roots
if (determinant > 0)
{
// sqrt() function returns square root
root1 = (-b+sqrt(determinant))/(2*a);
root2 = (-b-sqrt(determinant))/(2*a);
printf("root1 = %.2lf and root2 = %.2lf",root1 , root2);
}
//condition for real and equal roots
else if (determinant == 0)
{
root1 = root2 = -b/(2*a);
printf("root1 = root2 = %.2lf;", root1);
}
// if roots are not real
else
{
realPart = -b/(2*a);
imaginaryPart = sqrt(-determinant)/(2*a);
printf("root1 = %.2lf+%.2lfi and root2 = %.2f-%.2fi", realPart, imaginaryPart, realPart, imaginaryPart);
}
}
return 0;
}
If determinant is greater than 0, the roots are real and different.
If determinant is equal to 0, the roots are real and equal.
If determinant is less than 0, the roots are complex and different.
So,
Sample image

Resources