Switch statement not compiling - c

Hello I've been sitting here for quite some time trying to figure out why this isn't working but I haven't had luck succeeding!
#include <stdio.h>
main(void)
{
int mark;
printf("Please enter the mark\n");
scanf("%d", &mark);
switch(mark){
case (mark <40):
printf("That's a fail");
break;
case (mark >=40 && <60):
printf("That's a pass");
break;
case (mark >=60 && <70):
printf("That's a merit");
break;
case (mark >=70):
printf("That's a distinction");
break;
}
}

For comparisons where the exact value is not known, use if-else blocks. You are trying to use a switch statement like an if-else block, and it does not work properly. A proper switch would look like
switch(mark) {
case 40: //if mark is 40, no more, no less
...
case 60: //same
...
}
Because you don't want to write out 40 lines that all lead to the same statement, just use
if(mark < 40) { ... }
else if(mark < 60) { ... }

From K&R:
"The switch statement is a mult-way decision that tests whether an expression matches one of a number of constant integer values, and branches accordingly."
That is, you can't do what you're trying to do. Each case needs a constant statement, such a simple int or char value.
For what you want to do you'll need if/else. Also, see jaap's answer on correct syntax for your boolean statement.

It's working fine, the compiler is preventing you from compiling something that's not valid C.
The case labels must be actual integer constants, not expressions that do further calculations.
You should use if/else if to check your various conditions.

Related

Why my code doesn't work if i don't put case 0 in switch

I was finding the greatest number using switch case in c. Here if I start the switch with case 0 the program executes perfectly.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a,b;
scanf("%d%d",&a,&b);
switch(a>b)
{
case 0:
printf("%d is maximum",b);
break;
case 1:
printf("%d is maximum",a);
break;
}
return 0;
But when I use case 1 instead of case 2.The program takes the input but doesn't show any result. What's the reason?
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a,b;
scanf("%d%d",&a,&b);
switch(a>b)
{
case 1:
printf("%d is maximum",b);
break;
case 2:
printf("%d is maximum",a);
break;
}
return 0;
The comparison a>b is an expression that will evaluate to either true or false. When representing (or testing) these "Boolean" values in C, false is equivalent to zero and true is equivalent to one.
So, the switch statement in your first code block will do as you expect. However, in your second block, the tested expression can never have the value 2 so, if a is not greater than b, nothing will be printed! (However, if a is larger than b, then the case 1: block will run.)
PS: If the evaluation of the expression in the brackets following the switch does not match any of the given cases inside the switch (...) {} block, then your code will silently ignore that block … unless you add a default: block (traditionally added at the end, but it can go anywhere a case X: could). Maybe you could try this to see for yourself.
For starters in one switch statement there may not two identical case labels. SO this code should not compile
switch(a>b)
{
case 1:
printf("%d is maximum",b);
break;
case 1:
printf("%d is maximum",a);
break;
}
From the C Standard (6.8.4.2 The switch statement)
3 The expression of each case label shall be an integer constant
expression and no two of the case constant expressions in the same
switch statement shall have the same value after conversion. ...
In C the value of a logical expression (as for example, a > b ) can be either integer 0 (false) or integer 1 (true). So the case labels in this switch statement are correct
switch(a>b)
{
case 0:
printf("%d is maximum",b);
break;
case 1:
printf("%d is maximum",a);
break;
}

Why my code which uses a logical expression as a case label throws error?

switch(at){
case (at>0 && at<5) :
printf("Average Time Taken (Hrs)\n%d.0",at);
printf("Your Salary is Rs.%d",pj*1500 + 5000);
break;
rest of the codes are similar. And i'm getting error for this case (at>0 && at<5) :
I'm afraid this is not possible. Quoting C11, chapter §6.8.4.2
The expression of each case label shall be an integer constant expression and no two of
the case constant expressions in the same switch statement shall have the same value
after conversion. [....]
so the case label expression cannot be a runtime-generated value dependent.
You can, use a fall-through syntax to achieve what you want, something like
switch(at){
case 1:
case 2:
case 3:
case 4:
printf("Average Time Taken (Hrs)\n%d.0",at);
printf("Your Salary is Rs.%d",pj*1500 + 5000);
break;
//some other case
Otherwise, if you're ok with using gcc extension, you can use case-range syntax, something like
switch(at){
case 1 ... 4:
printf("Average Time Taken (Hrs)\n%d.0",at);
printf("Your Salary is Rs.%d",pj*1500 + 5000);
break;
The case value in a switch statement must be a compile time constant (such as a literal, or a static const, or a #define to one of those). For what you are trying to do, you need an else if chain:
if (0 < at && at < 5) {
printf("Average Time Taken (Hrs)\n%d.0",at);
printf("Your Salary is Rs.%d",pj*1500 + 5000);
} else if (5 <= at && at < 10) {
// Your code here
Note that I have reversed the arguments to the first comparison (and the direction). If you have multiple comparisons of the same variable, I find it much easier to read if they are all in the same direction.

Single line comparison to several values in C

For example maybe we have an if statement that wants to check if a variable is equal to 4 different values, perhaps something like
if(x == 1,2,3,4){ do something }
what is the proper syntax to do this in C? I know the comma works in some other language, I can not seem to figure how not to have several different if checks. The only other thing I could come up with is having to do
if((x == 1)||(x ==2)
but I will no doubt have more than 4 and that will get annoying fast. I didn't see any other question like this, if you know of it, point me towards it.
I would do it with a switch if the values are constant:
switch(x)
{
case 1:
case 2:
case 3:
case 4:
//do something
break;
}
if the numbers are continuous you can use if (x >= 1 && x <= 4)
First of all, shorthands, as mentioned by mch in the other answer,
if ( (x >= 1 && x <= 4) || (x >= 10 && x <= 40) || ....) //whatever condition
Otherwise, (not a single line comparison) in case you are OK with using gcc extensions, there's a feature called case-range.
There, you can specify a range of values. Something like
case 1 ... 5:
will be valid.
Finally, a fall-through switch case also may come handy, like
switch(val)
{
case 1:
case 2:
case 3:
case 4:
case 5:
break;
case 6:
case 7:
break;
default:
break;
}

how can we use the changeable variable as a switch case label

how can we use the changeable variable as a switch case label.
in other words,
I have a macro defined. But I need to change this value at run time depending on a condition. How can I implement this?
example is given below,
Here , case "FOO" will work?
#define CONDITION (strcmp(str, "hello") == 0)
#define FOO1 (10)
#define FOO2 (20)
#define FOO ((CONDITION) ? (FOO1) : (FOO2))
char *var="hello";
int main()
{
int p = 20;
switch(p) {
case FOO:
printf("\n case FOO");
break;
case 30:
printf("\n case 30");
break;
default:
printf("\n case default");
break;
}
return(0);
}
The switch condition needs to be resolved at compile-time. The case values need to be compile time constant expressions
From your question, you want to use run time condition to change the value of the case, so that is not possible.
One way to achieve run time check is to use if condition.
Your macro #define CONDITION (strcmp(str, "hello") == 0) isn't complete. It doesn't take in any argument.
The compiler will simply say str isn't defined in this scope.
Regardless, the case values are constants, so you won't be able to achieve this since your condition depends on run-time inputs.
It is important to know that most compilers implement the cases via a branch table. This is possible only because the case values are compile-time known (i.e. constants). The compiler will generate code to use your input as an index into this branch table to get to the logic for a particular case.
tl;dr - You can't use switch. Use if-elseif-else instead

How to write "if x equals 5 or 4 or 78 or..." in C

I have a quick question about using logical operators in an if statement.
Currently I have an if statement that checks if x equals to 5 or 4 or 78:
if ((x == 5) || (x == 4) || (x == 78)) {
blah
}
And I was wondering if I could just condense all that to:
if (x == 5 || 4 || 78) {
blah
}
Sorry for such a basic question, I've just started learning C.
There is no shortcut, but you need to fix your equality operator.
if ((x == 5) || (x == 4) || (x == 78)) {
First, you're using assignments not equality tests in your ifs. The first method (with suitable substitutions for equality) is the best way to do the test, though if you have a lot of possible options, there might be better ways. The second way might compile, but it won't do what you want, it will always return true since both 4 and 78 evaluate to true and what you are doing is evaluating whether 5 (the result of assigning 5 to x) or 4 or 78 are true. A switch statement might be one possible alternative.
switch (x) {
case 4:
case 5:
case 78:
blah...
break;
default:
}
There's no shortcut for the if statement, but I suggest considering:
switch (x)
{
case 4:
case 5:
case 78:
/* do stuff */
break;
default:
/* not any of the above... do something different */
}
No you cannot and the test for equality is ==, not =
#uncle brad is spot on, but later you'll probably learn about something called a switch statement. It looks funky but is often used in these sorts of situations (where several possible values of a variable all have the same effect):
switch (x) {
case 4:
case 5:
case 78:
// ...
break;
}
Though you'd only want to use a switch statement when the meaning of an if statement is less clear--most compilers these days are smart enough to generate optimal machine code either way.
It's been answered in the time it took me to log in, but you could use the switch, and break it out into a function
int isValid(int toCheck) {
switch(toCheck) {
case 4:
case 5:
case 78:
return 1;
default:
return 0;
}
}
Then you would just call the method every time you needed to check the int against the established cases.
Admittedly, this example is rather silly, but for a bigger selection of cases, and ones that were evaluated repeatedly, you could do something like this to simplify and reuse some code.
No, sorry, you can't; you have to write all the expressions out. For very long lists of numbers to compare to, you could put the numbers in an array, and loop over the list; but you'd have to have a dozen numbers or so before that started to look like a good idea.
No, you cannot do this in C. Your first code sample is also incorrect. There is an important distinction between assignment (=) and equivalency (==) in C. When you wrote x = 5 in your expression, this will actually compile and evaluate to either 0 or 1 (false or true) before being logically OR'ed with the next part of the expression!
Your second code sample is also valid C, but it does not do what you want it to do. You read the statement as "(x is assigned to 5) or true or true". This is because any non-zero value in C is logically true. Thus, x will contain the value 5, and evaluate to true, making your if condition true. The rest of the expression does not matter since the || operator short-circuits.
One alternate thought: While there's no "shortcut", if you have a lot of numbers it may be easier for code length and typing sanity to put them all into an array and check against the array in a loop. If you have to compare against many numbers more than once, sort them in an array and use binary searching.
For 3 numbers, though, you have to do it the "long" way.
You can do the for loop if it's a long list, how ever that doesn't really handle the logical operators :-...
#include <stdio.h>
int forbiddenList[13] = {5, 4, 78, 34, 23, 56, 4, 7, 6, 4, 33, 2333, 0};
int length = 13;
int main() {
int mysteryNum;
printf("type a number: ");
scanf("%d",&mysteryNum);
int i;
for (i = 0; i <= length; i ++)
{
int target = forbiddenList[i];
if (mysteryNum == target)
{
printf("You have chosen of the forbidden list!\n");
printf("YOU SHALL NOT PASS!!\n");
}
}
return 0;
}
er... haven't done c... ever... you should take C++...
int preconditions[] = { 4,5,78 }; // it should be in most likely order
int i = 0;
for(;i<3;++i) {
if( x == preconditions[i] ) {
// code here.
}
}
The syntax is:
if(condition1 || condition2 || condition3 || ...){
// Do something
} else {
// Do something
}
Answer to your question:
if( (x == 5) || (x == 4) || (x == 78) ){
//do something
} else {
//do something
}

Resources