-2
int main() {
    int marks;
    printf("enter the marks :");
    scanf(" %d", &marks);

    switch (marks) {
      case (marks >= 90):
        printf("Excellent");
        break;
      case (marks < 90 && marks >= 75):
        printf("very good");
        break;
      case (marks < 40):
        printf("poor");
        break;
      default:
        printf("no marks available");
    }
    return 0;
}

I recently started learning C and while running the switch statement I just ran into this case label error.

Please someone fix this?

chqrlie
  • 131,814
  • 10
  • 121
  • 189

3 Answers3

1

The case must be constant. case (marks>=90): does not employ a constant.

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" §6.8.4.2 3

Example:

switch (grade) {
  case 'A': printf("Excellent"); break;
  case 'B': printf("very good"); break;
  case 'C': // fall though (no break)
  case 'D': printf("poor"); break;
  default: printf("Hmmm");
}

OP's code would be better served with if(), else if(), else

// switch(marks){
// case (marks>=90):
if (marks>=90) {
    printf("Excellent");
} else if (marks>=75) {
    printf("very good");
} else if (marks < 40){  // Perhaps OP wants (marks > 40) here
    printf("poor");
} else {
    printf("no marks available");
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
1

To "fix" this, you would have to write

switch( marks )  // branch to the label corresponding to the value stored in marks
{
  case 100:
  case  99:
  // repeat with cases 98 through 91.  
  case  90: 
    printf( "Excellent!\n" );
    break;

  case 89:
  case 88:
  // repeat with cases 87 through 76
  case 75:
    printf( "very good\n" );
    break;

  // pattern should be obvious from here
}

case labels must be integer constant expressions, basically something that can be evaluated at compile time. Relational expressions like marks >= 90 don't count as constant expressions.

A switch branches to the label corresponding to the value of marks; IOW, if you want to execute an action when the value of marks is anywhere from 90 to 100, then you a separate label for each value as above.

You would normally not use a switch statement where ranges of values are involved like this; this is better done with an if-else statement.

Edit

For reference, the following may be used as case labels:

  • An integer literal (decimal, hex, or octal format);
  • A character constant (such as 'A', '?', '\n', etc.);
  • An enumeration constant;
  • An arithmetic expression composed of any of the previous expressions;
  • A macro that expands to any of the previous expressions;

A const-qualified variable is not a constant expression as far as C is concerned, so you can't do something like this:

const int foo = 10;
...
switch( bar )
{
  case foo: ... // compiler will yell at you here

You can't branch on strings in a switch; however, you can compute an integer hash for a string, and branch based on that:

#define FOO_HASH 0xb887389 // result of running hash function on "foo"
#define BAR_HASH 0xb8860ba // result of running hash function on "bar"

/**
 * djb2 is a popular hash function
 * see http://www.cse.yorku.ca/~oz/hash.html for others
 */
unsigned long hash( const char *text )
{
  const unsigned char *str = (const unsigned char *) text;
  unsigned long hash = 5381;
  int c;

  while (c = *str++)
      hash = ((hash << 5) + hash) + c; /* hash * 33 + c */

  return hash;
}

char text[SIZE];
if ( !fgets( text, sizeof text, stdin ) )
  // bail on input error

// remove newline from text somehow

switch( hash( text ) )
{
  case FOO_HASH: 
    // do something
    break;

  case BAR_HASH: 
    // do something else
    break;
}
John Bode
  • 119,563
  • 19
  • 122
  • 198
  • Good explanation. In researching this it seems code like `case INT_MAX/2: ...` is OK too. As I see it. `case UINTMAX_MAX: ...` is OK too, although using wider that `int` is not something I have done in production code. – chux - Reinstate Monica Sep 19 '17 at 21:01
0

you can't put a condition under a case. from https://www.tutorialspoint.com/cprogramming/switch_statement_in_c.htm:

The constant-expression for a case must be the same data type as the variable in the switch, and it must be a constant or a literal.

Shlomi Agiv
  • 1,183
  • 7
  • 17