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.
asked Dec 28, 2012 at 12:41
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 thesizeof
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 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
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 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
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
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
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
★
(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(). Проект не большой, просто учусь писать и использовать классы.
★
(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».
★
(06.11.09 23:37:58 MSK)
- Показать ответы
- Ссылка
[c++][switch] как юзать свитч для char *?
В case ведь могут быть только константы.
- Ссылка
[c++][switch] как юзать свитч для char *?
>Хотел как damage_type указывать не номера, а слова, например «ar2».
Enum для этого и сделан
- Ссылка
[c++][switch] как юзать свитч для char *?
> Хотел как damage_type указывать не номера, а слова, например «ar2».
это неправильное желание
★★★★
(06.11.09 23:41:44 MSK)
- Показать ответы
- Ссылка
[c++][switch] как юзать свитч для char *?
Хватит быдлокодить. На самом деле в c++ switch для char не нужен.
madcore ★★★★★
(06.11.09 23:46:42 MSK)
- Ссылка
[c++][switch] как юзать свитч для char *?
>это неправильное желание
Почему? ИМХО, так было бы легче юзать класс.
★
(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 | ||
|
Добавлено через 43 минуты
Упс, в конце какой-то мусор. Вот нормальный код:
C | ||
|
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
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
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!
Проблема со 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.
- Переместить
- Удалить
- Выделить ветку
Пока на собственное сообщение не было ответов, его можно удалить.