Error case label does not reduce to an integer constant

int value; const int signalmin = some_function(); switch(value) { case signalmin: break; } I read the value of some_function and use that int value to do a switch case on. The C99 compiler...
int value;

const int signalmin = some_function();

switch(value)
{
   case signalmin:
   break;
}

I read the value of some_function and use that int value to do a switch case on. The C99 compiler gives back:

error: case label does not reduce to an integer constant

But I cannot use a #define because the int value is being read before the switch executes.

Gabriel Staples's user avatar

asked Dec 28, 2012 at 12:41

Jim Clermonts's user avatar

Jim ClermontsJim Clermonts

1,5608 gold badges35 silver badges88 bronze badges

switch labels must be constant expressions, they have to be evaluated at compile time. If you want to branch on run-time values, you must use an if.

A const-qualified variable is not a constant expression, it is merely a value you are not allowed to modify.

The form of integer constant expressions is detailed in 6.6 (6) [C99 and the n1570 draft of the C2011 standard]:

6 An integer constant expression shall have integer type and shall only have operands
that are integer constants, enumeration constants, character constants, sizeof
expressions whose results are integer constants, _Alignof expressions, and floating
constants that are the immediate operands of casts. Cast operators in an integer constant
expression shall only convert arithmetic types to integer types, except as part of an
operand to the sizeof or _Alignof operator.

The restriction that only sizeof expressions whose result is an integer constant are allowed rules out sizeof expressions whose operand is a variable length array.

answered Dec 28, 2012 at 12:45

Daniel Fischer's user avatar

Daniel FischerDaniel Fischer

181k16 gold badges308 silver badges429 bronze badges

4

Let me chip in with an example. The following was tested on gcc version 4.6.3 with the flags -std=c99 -pedantic set:

#define SOME_HARDCODED_CONSTANT 0 //good
int foo(int i, int b){
    const int c=0; //bad
    int a=0; //bad

    switch(i){
        case c:     //compile error
        case a:     //compile error.
        case (b+a): //compile error
        case SOME_HARDCODED_CONSTANT: //all good
        case 5: //all good
    }
}

As others have noted, case arguments cannot be evaluated at runtime. Use an if-else block to do that.

answered Dec 3, 2013 at 10:09

rath's user avatar

2

In C. all case labels must be compile time constants. In C, the const qualifier does not create a compile-time constant, it merely designates that a run-time variable is read-only.

A switch is not the appropriate control structure for what you’re trying to do.

answered Dec 28, 2012 at 12:45

John Bode's user avatar

John BodeJohn Bode

117k18 gold badges116 silver badges194 bronze badges

I am using this Below code and it is working fine

case «+»: i.e. with double-quote I am getting an error
so try writing

case ‘+’: in single quote

#include <stdio.h>

int main() {
    // Write C code here
    char x;
    int a=20,b=10;
    scanf("%c",&x);
    switch(x)
    {
        
    case '+':
            printf("%d",a+b);
            break;
    case '-':
            printf("%d",a-b);
            break;
    case '*':
            printf("%d",a*b);
            break;
    case '/':
            printf("%d",a/b);
            break;
    default:
            printf("sorry");
    }
    
    return 0;
}

answered Jul 30, 2021 at 2:58

purushottam rawat's user avatar

In C, variables aren’t to be used in the switch case labels instead constant expressions are only allowed there.

answered Dec 28, 2012 at 12:48

MajorBetaVictory's user avatar

On OSX, clang seems to take constants as case labels without complaints.

#include <stdio.h>

#define SOME_HARDCODED_CONSTANT 0 //good for sure
int foo(int i, int b){ 
    const int c=1; //no problem!!!

    switch(i){
        case SOME_HARDCODED_CONSTANT: //all good
            printf("case SOME_HARDCODED_CONSTANTn"); break;
        case c:     //no compile error for clang
            printf("case cn"); break;
        case 5: //all good
            printf("case 5n"); break;
    }   
    return i+b;
}

int main() {
    printf("test foo(1,3): %dn", foo(1,3));
}

Output:

$> cc test.c -o test; ./test 
case c
test foo(1,3): 4

answered Sep 1, 2014 at 0:37

Farley's user avatar

FarleyFarley

1,1601 gold badge10 silver badges16 bronze badges

5

Home »
C programs »
C common errors programs

Here, we will learn why an error case label does not reduce to an integer constant in C language occurred and how to fix it?

Submitted by IncludeHelp, on September 01, 2018

This is an example of switch case in C programming language, switch case is used to check/jump on matched case value and then it executes given statement in the case block.

In the switch case statement, a case can only have integral constant values i.e. integer or character type constant value. We cannot use any variable as case value.

In this example, we are using case b: and b is a variable. Thus, error case label does not reduce to an integer constant occurs.

Example:

#include <stdio.h>

int main()
{
    int a,b;
    
    a=2;
    b=2;
    
    switch(a){
        case 1:
            printf("Case 1n");
            break;
        
        case b:
            printf("Case 2n");
            break;
    }
    
	return 0;
}

Output

prog.c: In function ‘main’:
prog.c:15:9: error: case label does not reduce to an integer constant
         case b:
         ^~~~
prog.c:5:11: warning: variable ‘b’ set but not used [-Wunused-but-set-variable]
     int a,b;
           ^

How to fix?

To fix the error case label does not reduce to an integer constant, use value 2 instead of variable b. The correct statement will be case 2:

Correct code:

#include <stdio.h>

int main()
{
    int a,b;
    
    a=2;
    b=2;
    
    switch(a){
        case 1:
            printf("Case 1n");
            break;
        
        case 2:
            printf("Case 2n");
            break;
    }
    
	return 0;
}

Output

Case 2

C Common Errors Programs »


[c++][switch] как юзать свитч для char *?

Коротко — никак. Только для фундаментальных вроде int/char/enum можно.

  • Ссылка

[c++][switch] как юзать свитч для char *?

switch(*a){

Ага, пробуем скомпилить:

#include <iostream>
using namespace std;

int main(){
const char *a = "b";


switch(*a){

    case "a":
        cout << "a = a" << endl; break;
    case "b":
        cout << "a = b" << endl; break;
    }
}

Получаем ошибки:
switch.cpp:10: error: case label does not reduce to an integer constant
switch.cpp:12: error: case label does not reduce to an integer constant

ShTH

(06.11.09 23:26:25 MSK)

  • Показать ответ
  • Ссылка

[c++][switch] как юзать свитч для char *?

А если строки нужно сравнивать, то можно по хешам свитч делать.

  • Ссылка

[c++][switch] как юзать свитч для char *?

> хешики сравнивай

Плохой совет. Хорошим может быть использование кодогенерации на темплейтах.

  • Показать ответы
  • Ссылка

[c++][switch] как юзать свитч для char *?

>Хорошим может быть использование кодогенерации на темплейтах

вот и займись этим

jtootf ★★★★★

(06.11.09 23:32:34 MSK)

  • Показать ответ
  • Ссылка

[c++][switch] как юзать свитч для char *?

Самое интересное, что в макроаасемблерах обычно больше можно было, и со сладким синтаксисисом.

madcore ★★★★★

(06.11.09 23:33:08 MSK)

  • Показать ответ
  • Ссылка

[c++][switch] как юзать свитч для char *?

>> хешики сравнивай


>Плохой совет. Хорошим может быть использование кодогенерации на темплейтах.

Темплейты со стрингами не работают. Вообще, насколько я понимаю оптимально тут каким-то макаром интернить строки чтобы сравнивать их указатели.

Absurd ★★★

(06.11.09 23:33:19 MSK)

  • Показать ответы
  • Ссылка

Re: [c++][switch] как юзать свитч для char *?

собственно компилятор тебе все говорит правильно

  • Ссылка

[c++][switch] как юзать свитч для char *?

Ладно, буду использовать нагромождения из конструкций if(), else if(). Проект не большой, просто учусь писать и использовать классы.

ShTH

(06.11.09 23:34:59 MSK)

  • Показать ответы
  • Ссылка

[c++][switch] как юзать свитч для char *?

Да нет, тебе просто паскаль понравился :)

madcore ★★★★★

(06.11.09 23:36:27 MSK)

  • Ссылка

[c++][switch] как юзать свитч для char *?

    void Npc::damage(int damage_type, int damage_sum){


    switch(damage_type){
        case 1:
        cout << "Урон SMG. Одно попадание забирает 5 очков. Попаданий:" << damage_sum  << endl;
        health -= (5 * damage_sum);
        break;

        case 2:
        cout << "Урон AR2. Одно попадание забирает 9 очков. Попаданий:" << damage_sum << endl;
        health -= (9 * damage_sum);
        break;

        default:
            cerr << "!!!!|       Оружие не известно! Ошибка" << endl << endl;
        break;
        }

}

Хотел как damage_type указывать не номера, а слова, например «ar2».

ShTH

(06.11.09 23:37:58 MSK)

  • Показать ответы
  • Ссылка

[c++][switch] как юзать свитч для char *?

В case ведь могут быть только константы.

  • Ссылка

[c++][switch] как юзать свитч для char *?

>Хотел как damage_type указывать не номера, а слова, например «ar2».

Enum для этого и сделан

  • Ссылка

[c++][switch] как юзать свитч для char *?

> Хотел как damage_type указывать не номера, а слова, например «ar2».

это неправильное желание

lester

★★★★

(06.11.09 23:41:44 MSK)

  • Показать ответы
  • Ссылка

[c++][switch] как юзать свитч для char *?

Хватит быдлокодить. На самом деле в c++ switch для char не нужен.

madcore ★★★★★

(06.11.09 23:46:42 MSK)

  • Ссылка

[c++][switch] как юзать свитч для char *?

>это неправильное желание
Почему? ИМХО, так было бы легче юзать класс.

ShTH

(06.11.09 23:46:48 MSK)

  • Показать ответ
  • Ссылка

[c++][switch] как юзать свитч для char *?

switch не нужен. Юзай полиморфизм или ассоциативные контейнеры

yoghurt ★★★★★

(07.11.09 00:31:53 MSK)

  • Ссылка

[c++][switch] как юзать свитч для char *?

>> Хотел как damage_type указывать не номера, а слова, например «ar2».


>это неправильное желание

В Qt вроде бы по такому принципу сигналы диспатчатся.

Absurd ★★★

(07.11.09 00:35:12 MSK)

  • Показать ответ
  • Ссылка

[c++][switch] как юзать свитч для char *?

Диспатч он вообще всегда так работает. Сравниением строк…

Xellos ★★★★★

(07.11.09 00:43:10 MSK)

  • Ссылка

[c++][switch] как юзать свитч для char *?

Потому что это сравнение строк. Которое требует дофига операций. Когда строки будут символов под сто, а условий будет под сотню, а вызовов в секунду будет…

Xellos ★★★★★

(07.11.09 00:44:31 MSK)

  • Ссылка

[c++][switch] как юзать свитч для char *?

Я не понял, а что, с одинарными кавычками не прокатит?

  • Показать ответ
  • Ссылка

Re: [c++][switch] как юзать свитч для char *?

>Ладно, буду использовать нагромождения из конструкций if(), else if(). Проект не большой, просто учусь писать и использовать классы.

Не совсем ясна задача.

Если на входе слова из известного словаря и требуется очень быстрая обработка, то следует использовать любую библиотеку вычисления perfect hash.

Если требования по скорости более низкие или словарь заранее неизвестен, то можно использовать дерево поиска.

Если требований по скорости нет вообще — то можно использовать последовательный перебор строк. Например, можно хранить нужные слова в массиве вместе с указателеми на функцию обработки.

sign

(07.11.09 01:44:52 MSK)

  • Ссылка

[c++][switch] как юзать свитч для char *?

прочитал

тяжелый случай у 70%

нафиг так мучать С++

namezys ★★★★

(07.11.09 01:54:29 MSK)

  • Показать ответ
  • Ссылка

[c++][switch] как юзать свитч для char *?

Поясню. Как такая конструкция:

switch(a%4) {

case 0:

do_smth;

{

case 2:

do_smt2;

{

case 4:

do_smt3;

}

}

}

Имхо в этом и проблема понимая switch.

namezys ★★★★

(07.11.09 01:59:00 MSK)

  • Показать ответ
  • Ссылка

[c++][switch] как юзать свитч для char *?

Вариант: взять дистанцию левенштейна, и свитч делать уже по ней :)

dannie

(07.11.09 03:47:32 MSK)

  • Ссылка

[c++][switch] как юзать свитч для char *?

Это development

svu ★★★★★

(07.11.09 04:19:08 MSK)

  • Ссылка

[c++][switch] как юзать свитч для char *?

По теме. В жабке такую фичу (свитч по строкам) обещают добавить в 1.7

svu ★★★★★

(07.11.09 04:20:25 MSK)

  • Показать ответ
  • Ссылка

[c++][switch] как юзать свитч для char *?

>Как такая конструкция

мне вот просто интересно — а что ты, собственно, хотел этой конструкцией сказать? что switch — это такой goto? что в нём можно забыть написать break? или что-то третье?

jtootf ★★★★★

(07.11.09 04:33:52 MSK)

  • Ссылка

[c++][switch] как юзать свитч для char *?

вот и займись этим

Заколебали. Вот идея. Именно этот код не тестировал, но рабочая 100%:

#include <boost/mpl/vector.hpp>
#include <boost/mpl/begin.hpp
#include <boost/mpl/deref.hpp>

#define ADDCASE(Name, Label, Function) 
class Name
{
public:
String label_;
Name() : label_(Label){}
void execute() { Function(); return true; }
};

Потом в коде:

void function1()
{ printf("Hello from switch"); }

ADDCASE(CASEBLOCK1, "label1" , function1)

И так — сколько нужно кейсов.

Потом кладем кейсы в контейнер:

typedef boost::mpl::vector<CASEBLOCK1, CASEBLOCK2, CASEBLOCK3> CASES;

Сам свитч:

template <class Begin, class End>
struct SWITCH
{
static bool doswitch(const String& s)
{
  typedef typename boost::mpl::deref<Begin>::type deref;
  dereft ex;
  if( ex.label_ == s )
    return ex.execute();
  else
    return Iteratorhelper<typename boost::mpl::next<Begin>::type, End >::doswitch(s); 
}
};

template <class End>
struct SWITCH<End, End>
{
static  bool doswitch(const String& s)
{
  bool false;
}
};

template<typename Container>
static QString PERFORMSWITCH(const String& s)
{
return SWITCH<typename boost::mpl::begin<Container>::type, typename boost::mpl::end<Container>::type>::switch(s);
}

Как пользоваться:

PERFORMSWITCH<CASES>("blabla");

Теперь компилятор сгенерит нам статическую функцию PERFORMSWITCH<CASES>, которая будет то же самое, что много if/else,
но куда проще для расширения, доработки, создания новых кейсов.

  • Показать ответ
  • Ссылка

[c++][switch] как юзать свитч для char *?

>которая будет то же самое

что и сравнение по хешикам, с той лишь разницей, что ты их считаешь статически (рукми объявляешь все CASEBLOCK’и). расширяемость, читаемость (как реализации так и использования), зависимости — всё на уровне плинтуса. вопорос дня: а в чём профит-то?

jtootf ★★★★★

(07.11.09 08:24:58 MSK)

  • Показать ответ
  • Ссылка

[c++][switch] как юзать свитч для char *?

что и сравнение по хешикам

Нет, в данном случае будет вызываться оператор сравнения для строки. Можно и хэши сделать (если постараться, то и статические). В doswitch можно делать все, что хочешь.

Читаемость отличная. Профит в том, что компилятор напишет за тебя очень много кода (и сделает это оптимально), скорости, расширяемости. Сам свитч можно вынести в отдельный хидер. Тогда для написания новых свитчей тебе достаточно сделать

void function1() { printf("Hello from switch"); }
void function2() { printf("Hello from switch"); }

ADDCASE(CASEBLOCK1, "label1" , function1) 
ADDCASE(CASEBLOCK2, "label2" , function1) 
ADDCASE(CASEBLOCK3, "label3" , function2) 

void test( )
{
...
typedef boost::mpl::vector<CASEBLOCK1, CASEBLOCK2, CASEBLOCK3> CASES2;
String mystr("label3");
PERFORMSWITCH<CASES2>(mystr);
...
}

Отличная читаемость, отличная расширяемость. И самое главное — это только идея, можно очень красиво ее доработать.

  • Показать ответ
  • Ссылка

[c++][switch] как юзать свитч для char *?

Это как? Так?

(defgeneric switch-test (switch-case value)
            (:method (x y) (equal x y))
            (:method ((switch-case (eql T)) value) T))

(defmacro switch (value &rest cases)
  (let ((value-var (gensym)))
    (labels ((process-switch (cases)
               (if (null cases)
                 nil
                 (destructuring-bind
                   ((current-case &body body) &rest cases) cases
                   `(if (switch-test ,current-case ,value-var)
                      (progn ,@body)
                      ,(process-switch cases))))))
      `(let ((,value-var ,value))
         ,(process-switch cases)))))

(use-package :cl-ppcre)

(defstruct regex (pattern ".*" :type string))

(set-dispatch-macro-character
  ## #" (lambda (s c n)
            (declare (ignore n))
            (unread-char c s)
            `(make-regex :pattern ,(read s t nil t))))

(defmethod switch-test ((case-of regex) (value string))
  (cl-ppcre:scan (regex-pattern case-of) value))

(defun main (s)
  (switch s
    (#"(?i)[A-Z]" (format t "String contains letters~%"))
    (#"[0-9]" (format t "String contains at least one digit and no letters~%"))
    (T (format t "The value is not a string"))))
  • Показать ответ
  • Ссылка

[c++][switch] как юзать свитч для char *?

между вторым и третьим случаями туда неплохо бы «(#».*» (format t «String contains no letters or digits»))», но суть и так понятна, думаю :)

  • Ссылка

[c++][switch] как юзать свитч для char *?

если один символ, то

#include <iostream> 

using namespace std;

int main() 
{ 
    const char *a = "b";

    switch(*a) {                  /* или a[0] вместо *a */
      case 'a': 
        cout << "a = a" << endl; 
        break; 
      
      case 'b': 
        cout << "a = b" << endl; 
        break; 
    } 
}

ono

(07.11.09 09:48:04 MSK)

  • Ссылка

[c++][switch] как юзать свитч для char *?

> Отличная читаемость, отличная расширяемость.

Уййййоооооо…

kemm

(07.11.09 10:10:30 MSK)

  • Показать ответ
  • Ссылка

[c++][switch] как юзать свитч для char *?

Оптимально построить finite state machine по данным строкам на этапе компиляции. Она будет небольшой, и поиск будет занимать O(N) (N — длина входной строки) или даже меньше.

  • Показать ответы
  • Ссылка

[c++][switch] как юзать свитч для char *?

> Уййййоооооо…

Что не так?

Вдогонку: вместо
[code]
return Iteratorhelper<typename boost::mpl::next<Begin>::type, End >::doswitch(s);
[/code]
следует читать
[code]
return SWITCH<typename boost::mpl::next<Begin>::type, End >::doswitch(s);
[/code]

  • Ссылка

[c++][switch] как юзать свитч для char *?

> Оптимально построить finite state machine

Какие мы умные. Конечно можно, но делать ты это будешь приблизительно так же. Только добавится еще функция, возвращающая указатель на себя же.

  • Показать ответ
  • Ссылка

[c++][switch] как юзать свитч для char *?

Как я понимаю, вариант в Tcl-е делает то же самое, ибо от правильных регулярных выражений производительность не пострадает.

  • Показать ответ
  • Ссылка

[c++][switch] как юзать свитч для char *?

В лиспе можно сделать при желании примерно так:

(case (var)
  ("abc[de]+f" 'first-string)
  ("abc[fg]" 'second-string)
  (else 'third))

В С++ без препроцессора я бы не стал этого делать вообще (если только не очень жётские требования к производительности). В D можно сделать.

А говорить про твоё нагромождение капслока, что оно отлично читается — нельзя.

  • Показать ответ
  • Ссылка

[c++][switch] как юзать свитч для char *?

Не путай интерпретацию с компиляцией, ладно?

  • Показать ответ
  • Ссылка

[c++][switch] как юзать свитч для char *?

Капслок здесь необязателен, препроцессор для удобства. Это вообще демонстрация идеи. И неоптимальная, за счет создания временного объекта.

  • Ссылка

[c++][switch] как юзать свитч для char *?

Не смотрел реализацию тикля, но мой комментарий относился не конкретно к тиклю, и компиляции там ничего не мешает. Вообще реализация case-а по строкам с использованием FSM идеологически очень похожа на реализацию case-а с использованием таблицы переходов.

  • Ссылка

[c++][switch] как юзать свитч для char *?

В полку индусов прибыло. Зачем вы за этот switch зацепились. Нагородите всяких макросов, шаблонами все обложите, и тот кто будет разбирать ваш код после вас, будет яростно писать кипятком. Чем плох такой вариант?

inline bool _IsEqu(const char* s1,const char* s2) { return (strcmp(s1,s2)==0); };

void Process(const char* text)
{
	if(_IsEqu(text,"aaa"))
	{
		//do some ...
	}
	else if(_IsEqu(text,"bbb"))
	{
		//do some ...
	}
	else if(_IsEqu(text,"ccc"))
	{
		//do some ...
	}
	else
	{
		pAnIc();
	}
}

З.Ы. Без _IsEqu можно было обойтись, но мне кажется, что так легче читается, а назначение этой функции можно понять из названия.

  • Показать ответы
  • Ссылка

[c++][switch] как юзать свитч для char *?

>Чем плох такой вариант?

void Process(const char* text)
{
if(_IsEqu(text,»aaa»))
{
//do some …
}
else if(_IsEqu(text,»bbb»))
{
//do some …
}
else if(_IsEqu(text,»ccc»))
{
//do some …
}
else if(_IsEqu(text,»ccc»))
{
//do some …
}
else if(_IsEqu(text,»ccc»))
{
//do some …
} else if(_IsEqu(text,»ccc»))
{
//do some …
} else if(_IsEqu(text,»ccc»))
{
//do some …
} else if(_IsEqu(text,»ccc»))
{
//do some …
} else if(_IsEqu(text,»ccc»))
{
//do some …
} else if(_IsEqu(text,»ccc»))
{
//do some …
} else if(_IsEqu(text,»ccc»))
{
//do some …
} else if(_IsEqu(text,»ccc»))
{
//do some …
} else if(_IsEqu(text,»ccc»))
{
//do some …
} else if(_IsEqu(text,»ccc»))
{
//do some …
} else if(_IsEqu(text,»ccc»))
{
//do some …
} else if(_IsEqu(text,»ccc»))
{
//do some …
} else if(_IsEqu(text,»ccc»))
{
//do some …
} else if(_IsEqu(text,»ccc»))
{
//do some …
} else if(_IsEqu(text,»ccc»))
{
//do some …
} else if(_IsEqu(text,»ccc»))
{
//do some …
} else if(_IsEqu(text,»ccc»))
{
//do some …
} else if(_IsEqu(text,»ccc»))
{
//do some …
} else if(_IsEqu(text,»ccc»))
{
//do some …
} else if(_IsEqu(text,»ccc»))
{
//do some …
} else if(_IsEqu(text,»ccc»))
{
//do some …
} else if(_IsEqu(text,»ccc»))
{
//do some …
} else if(_IsEqu(text,»ccc»))
{
//do some …
} else if(_IsEqu(text,»ccc»))
{
//do some …
} else if(_IsEqu(text,»ccc»))
{
//do some …
}
{
//do some …
} else if(_IsEqu(text,»ccc»))
{
//do some …
}
else
{
pAnIc();
}
}

madcore ★★★★★

(07.11.09 15:24:47 MSK)

  • Ссылка

Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.

0 / 0 / 0

Регистрация: 24.04.2020

Сообщений: 19

1

09.06.2020, 11:08. Показов 5759. Ответов 3


Такая проблема: нужно сделать программу, которая из вводимых значений «неудовлетворительно»,»удовлетворительно» и т.д. будет делать числа. Т.е. просто переводить из оценки письменной в численные 2,3,4,5.
Но делать это всё надо с оператором Switch.
И тут я споткнулся об ошибку «Case label does not redus to an integer constant» в , собственно, строке 13 — «switch ( mark )», из-за отсутствия по сути опыта. Может кто-нибудь, пожалуйста, пояснить, что тут не так?

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <stdio.h>
#include <locale.h>
int main()
{
setlocale(LC_ALL, "Russian");
 
char mark[30];
 
printf( "Введите оценку: " );
 
fgets( mark, 100, stdin ); // считываем из потока ввода строку
 
switch ( mark )
{
case "Неудовлетворительно":
  Printf(2);
  break;
case "Удовлетворительно":
  /*этот код выполнится, если variable будет равна const2*/
  Printf(3);
  break;
case "Хорошо":
   printf(4):
   break;
case "Отлично":
   printf(5);
   break;
default:
   prinf("Вы ошиблись при вводе");
  break;
}
 
printf( "Вы ввели следующую строку: %s", mark );
 
getchar();
}

Добавлено через 43 минуты
Упс, в конце какой-то мусор. Вот нормальный код:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <stdio.h>
#include <locale.h>
int main()
{
setlocale(LC_ALL, "Russian");
 
char mark[30];
 
printf( "Введите оценку: " );
 
fgets( mark, 100, stdin ); // считываем из потока ввода строку
 
switch ( mark )
{
case "Неудовлетворительно":
  Printf(2);
  break;
case "Удовлетворительно":
  /*этот код выполнится, если variable будет равна const2*/
  Printf(3);
  break;
case "Хорошо":
   printf(4):
   break;
case "Отлично":
   printf(5);
   break;
default:
   prinf("Вы ошиблись при вводе");
  break;
}
 
return(0);
}

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



Ezoic

The switch case statement in C programming is a multi-way decision that tests whether an expression matches one of a number of constant integer values, and branches accordingly. Two keywords are used in the program:- switch and case.

Syntax of switch case in C

switch(expression)
{
  case constant1:
      Statements-1;
  case constant2:
      Statements-2;
  case constant3:
      Statements-3;
  case constant3:
      Statements-4;
      .
      .
      .
  default:
      Statements-3;
}

The value of the expression is evaluated first and the value
of the expression is compared with the case constants.
When a match is found, the statement sequence associated with that
case is executed until the break statement or the end of the switch
statement is reached. The default statement is executed if no matches
are found. When the break is encountered in a switch case,
then program execution jumps to the end of the switch case.

The switch statement is often used to process keyword commands, such as a menu section.

Flowchart of switch case in C

flowchart of switch case in c

switch case in c

Sample program on switch case in C

 #include<stdio.h>
 int main()
 {
   int a = 3;
   switch(a)
   {
     case 1:
         printf("Hello");
         break;
     case 2:
         printf("Hi");
         break;
     case 3:
         printf("Welcome to C programming");
         break;
     default:
         printf("Welcome to programming world");
   }
   return 0;
 }

Output:-

Welcome to C programming

In this program, the expression is variable a and its value is 3. So, compiler search case with 3, when the match is found then the statements of the case executed. If the match is not found then the default statement will be executed.

Program:- Write a C program for arithmetic operations additions, subtractions, multiplication, and division of two numbers. The user should have the option to choose the operation.

 #include<stdio.h>
 int main()
 {
   int a, b;
   char ch;

   printf("Enter two number: ");
   scanf("%d %d",&a, &b);

   printf("Enter one operator (+,-,*,/): ");
   // give a space before %c in the below scanf
   scanf(" %c",&ch);

   switch(ch)
   {
     case '+':
       printf("The sum of %d and %d is = %d", a, b, a+b);
       break;
     case '-':
       printf("The subtraction of %d and %d is = %d", a, b, a-b);
       break;
     case '*':
       printf("The multiplication of %d and %d is = %d", a, b, a*b);
       break;
     case '/':
       printf("The division of %d and %d is = %d", a, b, a/b);
       break;
     default:
       printf("Invalid operator.");
   }

   return 0;
 }

Output for the different test-cases:-

Enter two number: 10 20
Enter one operator (+,-,*,/):+
The sum of 10 and 20 is = 30

Enter two number: 20 5
Enter one operator (+,-,*,/): –
The subtraction of 20 and 5 is = 15

Enter two number: 2 5
Enter one operator (+,-,*,/): *
The multiplication of 2 and 5 is = 10

Enter two number: 100 5
Enter one operator (+,-,*,/): /
The division of 100 and 5 is = 20

Read more:- Use scanf correctly with char

Special points on switch case in C

The default statement is optional

In the switch case in C, the default statement is optional. If we don’t give any default statement and also the match is not found then any case statements will not be executed. But it is good programming practice to use the default statement in the switch case.

Find the output of the below two programs program-1 and program-2.

// program-1
#include<stdio.h>
int main()
{
  int a = 3;
  switch(a)
  {
    case 1: printf("xn"); break;
    case 2: printf("yn"); break;
    default: printf("zn");
  }
  printf("Execution completed.");
  return 0;
}
 // program-2
#include<stdio.h>
int main()
{
  int a = 3;
  switch(a)
  {
    case 1: printf("xn"); break;
    case 2: printf("yn"); break;
  }
  printf("Execution completed.");
  return 0;
}

In program1 there is a default statement, here the expression doesn’t match with any case so finally default statement is executed.

In program2 there is no default statement is there. Since there is no match for expression with the case so no statement is executed from the switch case block.

The output of program-1:-

z
Execution completed.

The output of program-2:-

Execution completed.

The order of case statements

The order of case statements doesn’t create any difference in the output. Similarly, the default statement can be anywhere in the program.

 #include<stdio.h>
 int main()
 {
   int a = 1;
   switch(a)
   {
     case 2: printf("a"); break;
     case 1: printf("b"); break;
     case 3: printf("c"); break;
     default: printf("d");
   }
   return 0;
 }

Output:-

b

We can write the case statements in any order. Generally, we write case constants in increasing order as 1, then 2, 3, 4 and so on, by this way it is easier for other programmers to understand the code.

 #include<stdio.h>
 int main()
 {
   int a = 5;
   switch(a)
   {
     default: printf("C programming"); break;
     case 1: printf("C++ programming"); break;
     case 2: printf("Java programming");
   }
   return 0;
 }

Output:-

C programming

Generally, in switch cases, we write default statements at last, but we can write it anywhere in the switch case.

Break is optional

In the switch case, we always use break statement but it optional. But if we are not using a break statement then we may get unexpected output.

 #include<stdio.h>
 int main()
 {
   int a = 2;
   switch(a)
   {
     case 1: printf("a");
     case 2: printf("b");
     case 3: printf("c");
     default: printf("d");
   }
   return 0;
 }

Output:-

bcd

Why this output came? In switch case, the expression is matched with constant 2 so, it is executed as displayed ‘b’ to the screen. Now, there is no break statement so, the next case statement is also executed and displayed ‘c’ to the screen. Similarly, the default statement also executed and displayed ‘d’ to the screen. Finally, we got bcd as output.

To overcome the above problem we should use the break statement. Generally, we use break statement in every case except for the last one. The last one may be case or default. Break stop the execution of the switch case and control came out of the switch case, in the last statement no remaining statements are there for execution so it doesn’t create any difference.

The expression and constant in switch case

The expression must evaluate to a character or integer value. The floating-point expressions are not allowed.

The constants following the case keywords should be an integer or character type. They can be either constants or constants expressions. The constants must be different from one another.

Floating-point numbers as expression or constant

Switch case doesn’t work on floating-point numbers. Floating-point numbers are not allowed either as an expression or constant in the switch case statement in C. If we use them then we will get a compile-time error.

Find the output of the below programs.

 #include<stdio.h>
 int main()
 {
   float a = 2;
   switch(a)
   {
     case 1: printf("a"); break;
     case 2: printf("b"); break;
     default: printf("c");
   }
   return 0;
 }

In this program we are using a floating-point number as an expression so, we got the error: “switch quantity not an integer”. Floating-point as an expression is not allowed in the switch case.

 #include<stdio.h>
 int main()
 {
   int a = 2;
   switch(a)
   {
     case 1.0: printf("a"); break;
     case 2.0: printf("b"); break;
     default: printf("c");
   }
   return 0;
 }

In this program constants are floating-point so we got the error: case label does not reduce to an integer constant.

Constant expressions as constant or expression in switch case

Constant expressions are allowed as expression. Similarly, constant expressions are also allowed as constant for the switch case but The constants must be different from one/another. If duplicate constants are found in the program then compiler gives the compile-time error.

 #include<stdio.h>
 int main()
 {
   switch(3)
   {
     case 1: printf("x"); break;
     case 2: printf("y"); break;
     default: printf("z");
   }
   return 0;
 }

Output:-

z

The constant 3 is directly used as an expression in the above program. In switch case in C, it is allowed. Hence, the program executed successfully.

 #include<stdio.h>
 int main()
 {
   switch(3)
   {
     case 1: printf("x"); break;
     case 1+0: printf("y"); break;
     default: printf("z");
   }
   return 0;
 }

Two cases are similar in this program, so we got an error: duplicate case value.

 #include<stdio.h>
 int main()
 {
   int i=1, j=2;
   switch(3)
   {
     case i: printf("x"); break;
     case j: printf("y"); break;
     case i+j: printf("z");
   }
   return 0;
 }

We used variables as constant in the above program so we got an error: case label does not reduce to an integer constant.

 #include<stdio.h>
 int main()
 {
   switch(9)
   {
     case 3+3: printf("a"); break;
     case 3-3: printf("b"); break;
     case 3*3: printf("c"); break;
     case 3/3: printf("d");
   }
   return 0;
 }

Output:-

c

What will be the output of the below program?

 #include<stdio.h>
 int main()
 {
   int y = 1;
   switch(y)
   {
     y = y+5;
     case 1: printf("a"); break;
     case 5: printf("b"); break;
     default: printf("c");
   }
   return 0;
 }

Output:-

a

In this program, the statement “y = y+5;” will never be executed.

Character as constant or expression

Find the output of the below program.

 #include<stdio.h>
 int main()
 {
   char ch = 'a';
   switch(ch)
   {
     case 'a': printf("Hi"); break;
     case 'b': printf("Hello"); break;
     case 'c': printf("How are you?"); break;
     default: printf("Bye");
   }
   return 0;
 }

Output:-

Hi

Generally, we use only one associated value with a case label in the switch statement. But the case can ranges. The syntax of the case range is,

case lower_value ... upper_value :

Values of lower and upper must be valid integer constant expressions.

Program: C program to check character is Alphabet, Digit, White Space or Other

 #include<stdio.h>
 int main()
 {
   char c;

   printf("Enter any Character: ");
   scanf("%c",&c);
   
   switch(c)
   {
     case 'a'…'z':
     case 'A'…'Z':
           printf("Alphabetn");
           break;
     case '0'…'9':
           printf("Digitsn");
           break;
     case ' ':
     case 'n':
     case 't':
     case 'v':
     case 'r':
          printf("White Spacen");
          break;
     default:
          printf("Othern");
          break;
   }
   
   return 0;
 }

Output:-

Enter any Character: V
Alphabet

Enter any Character: 3
Digits

Enter any Character:
White Space

Enter any Character:?
Other

If the value of the lower is greater than the upper than the compiler will give an error.

case '9'…'0':  //empty range specified

When the value of lower and upper is equal than the range specifies only the one value.

case '0'…'0':   //it is equal to case '0':

If the value of a case label falls within a case range that has already used in the switch statement, the compiler will give an error.

case '0'…'9':
case '5':  //error

When the case ranges overlap, then compiler rejects the code with an error message.

case 'a'…'z':
case 'a'…'Z': //error

Note that if an endpoint of a case range is a numeric literal, leave white-space around the ellipsis (…) to avoid one of the dots being treated as a decimal point.

case 0…4:   // error
case 5 … 9: // ok

Program: read month number and display days in that month

Program:- Write a C program that will read the month number of the year and displays the total number of the days in that month.

When the month number is 2 i.e. February then it may have 29 or 28 days. For this we need to check year is a leap year or not, if the year is a leap year then a month has 29 days else month has 28 days.

The months having month numbers 1, 3, 5, 7, 8, 10, and 12 have always 31 days. Similarly, the remaining months have 30 days in the month.

 #include<stdio.h>
 int main()
 {
   int month;

   printf("Enter month number of the year: ");
   scanf("%d", &month);

   switch (month) {
     case 1:
     case 3:
     case 5:
     case 7:
     case 8:
     case 10:
     case 12:
       printf("Month has 31 days");
       break;
     case 2:
       {
         int year;
         printf("Enter year number: ");
         scanf("%d",&year);
         if( year%4==0 && (year %100!=0 || year % 400 == 0))
         printf("Month has 29 days.");
         else
         printf("Month has 28 days");
       }
       break;
     case 4:
     case 6:
     case 9:
     case 11:
       printf("Month has 30 days");
       break;
     default:
       printf("Invalid month number");
   }
   return 0;
 }

Output:-

Enter month number of the year: 3
The month has 31 days

Enter month number of the year: 11
The month has 30 days

Enter month number of the year: 2
Enter year number: 2022
The month has 28 days

Difference between nested if else and switch case in C

The if statement is the single-selection structure, the if-else is the double selection structure and the nested if-else and switch-case are the multi-selection control structures.

  • The switch statement is often faster than nested if-else statements (but not always).
  • The syntax of the switch case statement is cleaner and easy to understand.
  • The switch can only test for equality, but if statement can evaluate any type of relational or logical expression.
  • It is easier to add new cases to a switch statement than to a nested if-else structure.
  • The switch case evaluates only character and integer value but if else evaluates integer, character, floating-point, boolean, and pointer values.
  • In a nested if-else statement, only one statement will be executed but after matching a case, the switch case executes until the break does not appear or the switch statement is reached.

Summary

  • A switch-case statement enables one to choose one action from the set of actions, based on the result of an integer expression.
  • The case label can be in any order and it must be constant.
  • The two case labels can’t have the same value.
  • The default statement in the switch case is optional and we can put it anywhere in the switch case statement.
  • The case constant must be integer or character constants. The expression must evaluate to an integral type.
  • The break statement is optional. If the break statement is omitted in any case of a switch statement, the program flow is followed through the next case label.
  • The C89 specifies that a switch can have at least 257 case statements. The C99 requires that at least 1023 case statements be supported. The case can’t exist by itself, outside a switch.

If you enjoyed this post, share it with your friends. Do you want to share more information about the topic discussed above or do you find anything incorrect? Let us know in the comments. Thank you!

Ezoic


Проблема со switch и case

От:

kvser

 
Дата:  20.10.06 04:52
Оценка:

компилирую следующее:

//file 1.c
const int i = 3;

int j() {return 5;}

main()
{
switch(j())
{
case i: j(); break;
}
}

Watcom 10.6
expression must be constant

cc
gcc
1.c:9: error: case label does not reduce to an integer constant

g++
все ок

Borland (Builder 6)
все ок

В С и в С++ написано, что выражение при case должно быть константным.
Кто может сказать как ведут себя компиляторы(трансляторы) C и С++?


Re: Проблема со switch и case

От:

Bell

Россия

 
Дата:  20.10.06 06:23
Оценка:

Здравствуйте, kvser, Вы писали:

K>компилирую следующее:


K>//file 1.c

K>const int i = 3;

K>int j() {return 5;}


K>main()

K>{
K> switch(j())
K> {
K> case i: j(); break;
K> }
K>}

K>Watcom 10.6

K>expression must be constant

K>cc

K>gcc
K>1.c:9: error: case label does not reduce to an integer constant

K>g++

K>все ок

K>Borland (Builder 6)

K>все ок

K>В С и в С++ написано, что выражение при case должно быть константным.

K>Кто может сказать как ведут себя компиляторы(трансляторы) C и С++?
VC6 — ok
VC7.1 — ok
Comeau — ok

Любите книгу — источник знаний (с) М.Горький


Re: Проблема со switch и case

От:

elcste

 
Дата:  20.10.06 06:53
Оценка:

Здравствуйте, kvser, Вы писали:

K>компилирую следующее:

K>//file 1.c
K>const int i = 3;

K>int j() {return 5;}

K>main()
K>{
K>  switch(j())
K>  {
K>    case i: j(); break;
K>  }
K>}

Этот код некорректен для C, но он будет корректен для C++, если перед main добавить int.


Re[2]: Проблема со switch и case

От:

kvser

 
Дата:  20.10.06 07:10
Оценка:

Здравствуйте, elcste, Вы писали:

E>Этот код некорректен для C, но он будет корректен для C++, если перед main добавить int.

это как-то относится к выражению для case?

вопрос в том, как компилятор С относится к этому случаю (именно константное выражении для case) и как компилятор C++

факты разного поведения на лицо (см. мое предыдущее сообщение)


Re[2]: Проблема со switch и case

От:

Bell

Россия

 
Дата:  20.10.06 07:16
Оценка:

Здравствуйте, Bell, Вы писали:

B>VC6 — ok

B>VC7.1 — ok
B>Comeau — ok

Это относилось к компиляции С++ кода.
В случае С все эти компиляторы выдали ошибку.

Любите книгу — источник знаний (с) М.Горький


Re[2]: Проблема со switch и case

От:

kvser

 
Дата:  20.10.06 07:24
Оценка:

B>VC6 — ok
B>VC7.1 — ok
B>Comeau — ok

Используемый компилятор для языка C или С++?

K>>Кто может сказать как ведут себя компиляторы(трансляторы) C и С++?

ведут в смысле, при поялении след. текста какие решения принимает компилятор С, а какие C++?


Re: Проблема со switch и case

От: Аноним

 
Дата:  20.10.06 07:30
Оценка:

В C не было const


Re[3]: Проблема со switch и case

От:

elcste

 
Дата:  20.10.06 08:05
Оценка:

6 (2)

Здравствуйте, kvser, Вы писали:

E>>Этот код некорректен для C, но он будет корректен для C++, если перед main добавить int.


K>это как-то относится к выражению для case?

Скорее это относится к тому, что считается (а что не считается) integer constant expression в C и integral constant-expression в C++.

Для C:

ISO/IEC 9899:1999, 6.6/6: An integer constant expression shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, and floating constants that are the immediate operands of casts. Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to the sizeof operator.

Для C++:

ISO/IEC 14882:2003, 5.19/1: An integral constant-expression can involve only literals (2.13), enumerators, const variables or static data members of integral or enumeration types initialized with constant expressions (8.5), non-type template parameters of integral or enumeration types, and sizeof expressions. Floating literals (2.13.3) can appear only if they are cast to integral or enumeration types. Only type conversions to integral or enumeration types can be used. In particular, except in sizeof expressions, functions, class objects, pointers, or references shall not be used, and assignment, increment, decrement, function-call, or comma operators shall not be used.


Re[4]: Проблема со switch и case

От:

kvser

 
Дата:  20.10.06 09:12
Оценка:

все ясно

благодарю за разъяснение


Re[2]: Проблема со switch и case

От:

Lorenzo_LAMAS

 
Дата:  20.10.06 11:30
Оценка:

Здравствуйте, Аноним, Вы писали:

А>В C не было const

В каком С? Когда не было? Сейчас в С99 (и в С89) есть.

Of course, the code must be complete enough to compile and link.

Подождите ...

Wait...

  • Переместить
  • Удалить
  • Выделить ветку

Пока на собственное сообщение не было ответов, его можно удалить.

Понравилась статья? Поделить с друзьями:

Читайте также:

  • Error car invalid argument 1 wrong type not a pair
  • Error code 0x0000007e
  • Error code 0x0000007b
  • Error code 0x0000005d при установке windows 7
  • Error code 0x0000005c при установке windows

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии