Последние новости

YoungCoder теперь и на Stepikе. Записывайтесь: https://vk.cc/75rISy

Чтобы записаться на курс, необходимо зарегистрироваться на Степике: https://vk.cc/75rIC4

Это моя личная ссылка-приглашение на Stepik для вас. Регистрируясь по этой ссылке, записываясь на курсы и решая задачи, Вы помогаете автору данного сайта принять участие в конкурсе платформы Stepik! Подробности конкурса здесь: https://vk.cc/75rKuS

воскресенье, 6 ноября 2011 г.

Занятие 6. Оператор множественного выбора switch. Уроки программирования для чайников.Язык Си.

Прочитайте улучшенную версию этого урока "Оператор выбора switch".

В новой версии:

  • Ещё более доступное объяснение
  • Дополнительные материалы
  • Задачи с автоматической проверкой решения

Добрый день друзья.
Вот и подошло время очередного занятия. Оно будет посвящено инструкции switch.  Это еще одна из инструкций управления программой. В качестве вступления вспомним опять пример с дорогами. Представьте, что у нас развилка не из двух, а из трех дорог. Тут уже одной конструкцией if-else не отделаешься. Можно конечно использовать несколько конструкций if-else, но представьте если у нас будет 10 вариантов, например, для каждой цифры от 0 до 9 нужно выполнять какое-то своё действие? Тогда нам придется написать несколько вложенных конструкций if-else, но это не очень удобно. Для этих целей и служит инструкция switch, о которой мы и поговорим в сегодняшнем занятии.

Инструкция switch.
Как уже упоминалось выше, данная инструкция служит для выбора одного из многих путей. Рассмотрим её формат.
Листинг 6.1
switch (выражение) {
    case констное выражение: операторы
    case констное выражение: операторы
    default: операторы
}

Как видите, инструкция switch состоит из двух частей: заголовок switch, тело инструкции, записанное в составном операторе (фигурных скобках). В заголовке нас интересует только выражение в скобках. Именно от значения этого выражения зависит, какая из ветвей программы будет выполняться. Для этого выражения существует одно ограничение.
  • Там может быть записана любое выражение, или переменная символьного или целочисленного типа.

Ниже приведены примеры правильного и неправильного заголовков.

Листинг 6.2.
int c,a;
char s;
double g;

switch (c)        //Правильно (целая переменная)
switch ((a+c)+2)  //Правильно (выражение целого типа)
switch (g)        //Неправильно (вещественная переменная)
switch (s)        //Правильно (символьная переменная)

 В фигурных скобках записаны несколько (не обязательно две) ветвей case. Каждая такая ветка соответствует одному из вариантов выбора. Каждая из таких веток состоит из слова case, после которого через пробел записано константное выражении, или другими словами одно из значений выражения в заголовке. Именно с этим выражением сравнивается выражение в заголовке оператора switch (инструкция и оператор это одно и то же, поэтому не удивляйтесь, что иногда я пишу инструкция switch, а иногда оператор switch). Как только выражение в заголовке совпадает с одним из константных выражений в какой-либо ветке  case, начинает выполнять операторы следующие в данной ветке после двоеточия. 
  • Тут тоже есть ограничение,  константные выражения каждой из ветки case должны быть разными между собой.

 Т.е. следующий пример ошибочен (так как для двух веток (первой и третей) константные выражения совпадают :
Листинг 6.3
{
case 10: a+10; break;
case 34: a+34; break;
case 10: a-23; break;
}

В теле оператора switch может быть еще одна ветка default. Она необязательна. Её операторы выполняются, если выражение в заголовке оператора switch не совпало ни с одним из константных выражений в ветках  case. Если же такой ветки не будет, а ни одно из константных выражений не подходит, то просто ничего не будет делаться. И программа продолжит свое выполнение.

Обобщим вышесказанное. Оператор switch, в первом приближении, работает следующим образом. Сначала вычисляется выражение в заголовке, далее оно сравнивается с каждым из константных выражений внутри тела оператора. Если оно совпадает с одним из них, то выполняются операторы этой ветки, если совпадений нет, то выполняется ветка default, если она имеется, если ветки default нет, то выполнение оператора заканчивается. И программа продолжает работать дальше.

Для лучшего усвоения понимая работы оператора switch, и иллюстрации некоторых особенностей, давайте напишем программу которая реализует управление в какой-то гипотетической игре, потом при изучении циклов и функций мы переделаем это меню. Оно будет оболочкой для всех остальных программ. А пока, что примем следующие клавиши управления: W – вперед, A – влево, S – вниз, D – вправо.  Так как это символы для их хранения потребуется переменная типа char.

Листинг 6.4
#include <stdio.h>

int main(void) {
      char c;

      printf("Vvedite komandu: ");
      c=getchar();

      switch (c) {
            case 'w': printf("\nVpered\n");
            case 'a': printf("\nVlevo\n");
            case 's': printf("\nVniz\n");
            case 'd': printf("\nVpravo\n");
            default: printf("\nNeizvestnaya komanda\n");
      }
      return (0);
}

На рисунке ниже вы видите, как работает программа при нажатии клавиши a.

Рис. 6.1 Иллюстрация сквозного выполнения инструкции switch.

Как видите, на экране появилось, не то, что предполагалось. Эта программа иллюстрирует одну из особенностей инструкции switch – сквозное выполнение. Т.е. после того, как нашлось совпадение в одном из case, если явно не указан выход из оператора switch, то программа выполняет последовательно все остальные ветки записанные ниже той, с которой выполнено совпадение, пока не закончится оператор switch или пока не будет явно указан выход из оператора. В нашем случае мы нажали  клавишу a, программа выполнила ветку с выражение a, и продолжила выполнять последовательно все ветки, которые записаны в коде после этой, т.е. ветки s,d,w и ветку default. Эта особенность может играть как  отрицательную роль, как в нашем случае, так и положительную (мы применим её чуть позже). 
Для выхода из оператора switch используется оператор безусловного выхода break. Он так же применяется и в других конструкциях, например, в циклах, но об этом мы еще будем говорить. Как только программа встретит данный оператор, она закончит выполнение инструкции switch. Поэтому, нам нужно в каждую веточку дописать этот оператор выхода. Я настоятельно рекомендую писать break  во все без исключения  ветки. С учетом внесенных изменений программа примет следующий вид:

Листинг 6.5
#include <stdio.h>

int main(void) {
      char c;

      printf("Vvedite komandu: ");
      c=getchar();

      switch (c) {
            case 'w': printf("\nVpered\n"); break;
            case 'a': printf("\nVlevo\n"); break;
            case 's': printf("\nVniz\n"); break;
            case 'd': printf("\nVpravo\n"); break;
            default: printf("\nNeizvestnaya komanda\n"); break;
      }
      return (0);
}
Теперь если запустить программу она будет работать  так, как и предполагалось.
Сейчас поговорим об еще одной особенности оператора switch. Внутри тела оператора, порядок написания case и default не важен. Т.е. Сначала можно написать ветку default, а затем ветки case. Или же ветку default можно пометить между других веток case. Программа Листинг 6.6  работает так же как и программа Листинг 6.5:

Листинг 6.5
#include <stdio.h>

int main(void) {
      char c;

      printf("Vvedite komandu: ");
      c=getchar();

      switch (c) {
            case 'w': printf("\nVpered\n"); break;
            case 'a': printf("\nVlevo\n"); break;
            default: printf("\nNeizvestnaya komanda\n"); break;
            case 's': printf("\nVniz\n"); break;
            case 'd': printf("\nVpravo\n"); break;
      }
      return (0);
}  
Теперь разберемся с ситуацией когда сквозное выполнение оператора switch играет полезную роль. Представим ситуацию,  что у пользователя нажата клавиша Caps Lock. Поэтому все вводимы буквы будут в верхнем регистре. Но компьютер различает буквы в верхнем и нижнем регистре, и поэтому если в нашей программе написать W, то мы увидим на экране надпись о неизвестной команде.  Для того чтобы исправить эту оплошность, надо добавить еще 4 ветки case. Перепишем программу.

Листинг 6.7
#include <stdio.h>

int main(void) {
      char c;

      printf("Vvedite komandu: ");
      c=getchar();

      switch (c) {
            case 'W': printf("\nVpered\n"); break;              
            case 'w': printf("\nVpered\n"); break;
            case 'A': printf("\nVlevo\n"); break;
            case 'a': printf("\nVlevo\n"); break;
            case 'S': printf("\nVniz\n"); break;
            case 's': printf("\nVniz\n"); break;
            case 'D': printf("\nVpravo\n"); break;
            case 'd': printf("\nVpravo\n"); break;
            default: printf("\nNeizvestnaya komanda\n"); break;
      }
      return (0);
}
Сейчас она будет работать так, как надо. А вот теперь вспомним о сквозном выполнении оператора switch. Рассмотрим на примере команды «Вперед».
Имеем^

Листинг 6.8
case 'W': printf("\nVpered\n"); break;              
case 'w': printf("\nVpered\n"); break;

Если в верхней строчке Листинг 6.8 убрать оператор break, то из-за свойства сквозного выполнения, выполнится сначала одна функция printf, а затем вторая из ветки с маленькой w. Потом программа встретит break и закончит выполнение оператора. Теперь уберем первую функцию printf.

Листинг 6.9
case 'W':              
case 'w': printf("\nVpered\n"); break;

Теперь программа будет работать независимо от того в каком регистре введена буква. Т.е. мы как бы для одной ветки сделали два условия. Если какое-либо из них выполнится, то эта ветка выполнится. Т.е. если мы нажмем W то программа выполнит сначала операторы ветки W. Там их нет и оператор break отсутствует,  программа начнет выполнять следующую ветку w. И потом встретив оператор break выйдет из инструкции switch. Таким же образом поступим с остальными ветками. Программа приобретет следующий вид:

Листинг 6.10
#include <stdio.h>

int main(void) {
      char c;

      printf("Vvedite komandu: ");
      c=getchar();

      switch (c) {
            case 'W':        
            case 'w': printf("\nVpered\n"); break;
            case 'A':
            case 'a': printf("\nVlevo\n"); break;
            case 'S':
            case 's': printf("\nVniz\n"); break;
            case 'D':
            case 'd': printf("\nVpravo\n"); break;
            default: printf("\nNeizvestnaya komanda\n"); break;
      }
      return (0);
}

Теперь немножко о преимуществах и  недостатках оператора switch.
Инструкция switch наглядно показывает ветвление на несколько вариантов. Но она имеет один существенный недостаток. Если в инструкции if мы могли использовать некоторые условия и логические операторы, то в операторе swith это невозможно. Нам необходимо заранее для каждого значения написать конкретный набор действий. Т.е. выражение в заголовке является критерием выбора, причем оно должно быть строго, либо целого типа, либо символьного. И в зависимости от этого критерия выбирается ветка. Поэтому не во всех случаях мы сможем использовать данную инструкцию. В таких случаях приходится использовать несколько инструкций if-else.
 На  этом мы завершим сегодняшнее занятие.

Резюме урока:
  • Узнали об операторе множественного выбора switch
  • Разобрались с нюансами его работы.
  • Научились использовать оператор безусловного выхода break.
  • Поговорили о области применимости инструкций switch и if-else.


Задание для практической работы:
      Написать программу простейший  калькулятор для следующих действий  +,-,*,/. На вход программе подается два числа и знак действия. Например: 4 23.5 *. Программа должна вывести результат арифметического действия. При недопустимой арифметической команде вывести ERROR.


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

96 комментариев :

  1. Я пророк и знаю, что if != switch

    ОтветитьУдалить
  2. #include "stdio.h"

    int main(void)
    {
    float a,b,d;
    char s;

    printf("Vvedite dva chisla i znak deistviya: ");
    scanf("%f %f %c", &a,&b,&s);

    switch (s)
    {
    case '+': d=a+b, printf("\n%f+%f=%f\n ",a,b,d); break;
    case '-': d=a-b, printf("\n%f-%f=%f\n ",a,b,d); break;
    case '*': d=a*b, printf("\n%f*%f=%f\n ",a,b,d); break;
    case '/': d=a/b, printf("\n%f/%f=%f\n ",a,b,d); break;
    default: printf("\nERROR\n"); break;
    }
    return (0);
    }

    ОтветитьУдалить
  3. Dispose, хорошо, только соблюдайте формат вывода. В данном случае надо вывести только результат операции, а не полную её запись.

    ОтветитьУдалить
  4. #include
    int main(void)
    {
    float a,b,c;
    char s;
    printf("primer vvoda:2*2\n");
    scanf("%f %c %f",&a,&s,&b);
    switch (s){
    case '+':printf("=%f\n",c=a+b);break;
    case '-':printf("=%f\n",c=a-b);break;
    case '/':printf("=%f\n",c=a/b);break;
    case '*':printf("=%f\n",c=a*b);break;
    default:printf("unknown command\n");break;
    }
    return(0);

    ОтветитьУдалить
  5. Добрый день Камиль. Неправильно. Соблюдайте формат входных и выходных данных.

    ОтветитьУдалить
  6. #include "stdio.h"
    int main(void)
    {
    float a,b;
    char s;
    scanf("%f %f %c",&a,&b,&s);
    switch(s){
    case'+':printf("=%f\n",a+b);break;
    case'-':printf("=%f\n",a-b);break;
    case'*':printf("=%f\n",a*b);break;
    case'/':printf("=%f\n",a/b);break;
    default:printf("ERROR\n");break;
    }
    return(0);
    }

    ОтветитьУдалить
  7. а как можно начать обучение?

    ОтветитьУдалить
    Ответы
    1. Читайте уроки с первого, разбирайтесь. Если что-то непонятно спрашивайте. Постараюсь помочь.=)

      Удалить
  8. /*спасибо за хорошие уроки)))
    P.S от Сергея*/

    #include "stdio.h"
    int main(void)
    {
    int a,b;
    char s;
    printf("\n\n\n");
    printf ("\t\t\t|==================================|\n");
    printf ("\t\t\t|nvvedite operaciyu i nahmite Enter|\n");
    printf ("\t\t\t| |\n\t\t\t\t\t");
    scanf("%d%c%d",&a,&s,&b);
    switch(s)
    {
    case'+':printf ("\n\t\t\t| =%d |\n\t\t\t",a+b);
    printf ("|==================================|\n\t\t\t");break;
    case'-':printf ("\t\t\t| =%d |\n\t\t\t",a-b);
    printf ("|==================================|\n\t\t\t");break;
    case'*':printf ("\t\t\t| =%d |\n\t\t\t",a*b);
    printf ("|==================================|\n\t\t\t");break;
    case'/':printf ("\t\t\t| =%d |\n\t\t\t",a/b);
    printf ("|==================================|\n\t\t\t");break;
    default:printf ("\t\t\t| ERROR |\n\t\t\t");
    printf ("|==================================|\n\t\t\t");break;
    }
    return(0);
    }

    ОтветитьУдалить
    Ответы
    1. Нет, не верно. Соблюдайте формат входных и выходных данных. =)

      Удалить
  9. Спасибо за отличные уроки! =)

    float a,b;
    char c;

    printf("\nvvedite dva 4isla i znak deistvia\n");
    scanf("%f %f %c", &a,&b,&c);

    switch (c)
    {
    case '-' : printf("\n%f\n", a-b); break;
    case '+' : printf("\n%f\n", a+b); break;
    case '*' : printf("\n%f\n", a*b); break;
    case '/' : printf("\n%f\n", a/b); break;
    default: printf("\nERROR\n");
    return(0);
    }

    ОтветитьУдалить
  10. #include

    int main() {
    float a,c;
    char b;
    printf("Vvedite dannue i dejstvie: ");
    scanf("%f%f%c", &a, &c, &b);

    switch (b) {
    case '+': printf("\nRavno:", a+c); break;
    case '-': printf("\nRavno:", a-c); break;
    case '*': printf("\nRavno:", a*c); break;
    case '/': printf("\nRavno:", a/c); break;
    default: printf("\nERROR - Neverhue dannue"); break;
    }
    return (0);
    }

    ОтветитьУдалить
    Ответы
    1. Работает верно, но неправильный формат.Учитесь делать то, что вас просят. =)

      Удалить
  11. Спасибо за уроки, очень хорошо все изложенно.
    Почему-то текст программы сбивается в кашу при попыке выложить его на стну ((

    ОтветитьУдалить
    Ответы
    1. Странно. У всех же нормально получается.

      Удалить
    2. Порой испытываю те же проблемы...Приходится скидывать код по частям(((

      Удалить
  12. #include
    #include

    int main(int argc, char** argv) {
    float a, b;
    char c;
    printf("Enter A: ");
    scanf("%f", &a);
    printf("Enter B: ");
    scanf("%f", &b);
    printf("Enter Znak: ");
    do
    c = getchar();
    while (c == 10);
    switch (c)
    {
    case '+': printf("A %c B = %f", c, a + b); break;
    case '-': printf("A %c B = %f", c, a - b); break;
    case '/': printf("A %c B = %f", c, a / b); break;
    case '*': printf("A %c B = %f", c, a * b); break;
    default: printf("Error"); break;
    }
    return (EXIT_SUCCESS);
    }

    ОтветитьУдалить
  13. #include
    int main(void)
    {
    float a,b,x;
    char c;
    printf("Vvedite komandu: ");
    scanf("%f %f %c", &a,&b,&c);
    switch (c) {
    case '+': x=a+b; printf("x=%.2f\n", x);break;
    case '-': x=a-b; printf("x=%.2f\n",x);break;
    case '*': x=a*b; printf("x=%.2f\n",x);break;
    case '/': x=a/b; printf("x=%.2f\n",x);break;
    default: printf("ERROR");
    }

    return(0);
    }

    ОтветитьУдалить
    Ответы
    1. Верно. НО прошу вас, соблюдайте формат. И переменная х тут лишняя, можно и без неё. =)

      Удалить
  14. Спасибо вам "Автор" за такой хорошо изложенный материл...лучше этого я НЕ встречал...вы молодец... спасибо вам большое, и всего самого лучшего...
    Георгий.

    ОтветитьУдалить
    Ответы
    1. Пожалуйста. Стараюсь. Спасибо за добрые слова. Мне очень приятно, что всё не зря.=)

      Удалить
  15. У Камиля понравилось решение(без переменной x - case '/': printf("\n%f\n",a/b); break;), не знал, что на месте данных для вода, можно слаживать переменные, так код получается проще, а я думал, что должно быть только, как у вас описано во втором уроке:"Количество специальных формат-символов должно совпадать с количеством переменных, которые находяться после кавычок формат-строки"


    //Урок 6 Задание 1 КАЛЬКУЛЯТОР

    #include
    int main (void)
    {
    float a,b,x;
    char c;

    printf("Vvedite dva chesla i znak deystviya cherez probel:\n\n");
    scanf("%f %f %c",&a,&b,&c);


    switch (c)
    {
    case '+': x=a+b; printf("\n%f\n",x); break;
    case '-': x=a-b; printf("\n%f\n",x); break;
    case '*': x=a*b; printf("\n%f\n",x); break;
    case '/': printf("\n%f\n",a/b); break

    default: printf("\nERROR\n");
    }

    return(0);
    }

    ОтветитьУдалить
  16. Я старался упростить, поэтому написал так. На самом деле, там не обязательно должна быть переменная, а любое выражение, которое дает необходимый нам тип на выходе. Т.е. Камиль вместо переменной вещественного типа, записал сразу выражение, которое в результате дает вещественный тип.

    ОтветитьУдалить
  17. #include
    #include
    int main(void)
    {
    float a,b,c;
    char d;
    printf("Vvedi dva chisla i znak deistviya\n");
    scanf("%f %f %c",&a,&b,&d);
    switch(d) {
    case '+':c=a+b; printf("%f\n",c);break;
    case '-':c=a-b; printf("%f\n",c);break;
    case '/':c=a/b; printf("%f\n",c);break;
    case '*':c=a*b; printf("%f\n",c);break;
    default: printf("ERROR\n");break;
    }
    return(0);

    }

    ОтветитьУдалить
  18. Незнаю, как там ввести 2 цифры и знак в програму КАМИЛЯ и других, чтобы оно что то сосчитало??? Всегда выводит "ERROR", хотя сама программа работает без ошибок.

    ОтветитьУдалить
  19. Почему-то всегда выдает "Неизвестная команда" ?....

    #include "stdio.h"
    int main(void)
    {
    printf("Vvedite cherez probel 2 chisla i komandu ");
    float a,b,x;
    char c;
    scanf("%f%f%c",&a,&b,&c);

    switch (c)
    {
    case '+': x=a+b, printf("\Otvet:%f\n",x); break;
    case '-': x=a-b, printf("\nVlevo\n"); break;
    case '*': x=a*b, printf("\nVniz\n"); break;
    case '/': x=a/b, printf("\nVpravo\n"); break;
    default: printf("\nNeizvestnaya komanda\n"); break;
    }
    return (0);
    }

    ОтветитьУдалить
  20. ой, забыл в скобках дописать на вычитание, умножение, деление. Но сути это не меняет...

    ОтветитьУдалить
  21. double a,b;
    char c;
    printf("pervoe chislo");
    scanf("%f",&a);
    printf("deistvie");
    scanf("%c",&c);
    printf("vtoroe chislo");
    scanf("%f",&b);
    switch (c) {
    case '+': printf("%f",a+b);break;
    case '-': printf ("%f",a-b);break;
    default: printf("Error!");
    }
    return 0;

    что здесь неверно?после ввода первого числа выводится сразу deistvievtoroe chislo и дальше уже независимо от того что будет введено дальше,выйдет Error!
    помогите!!!

    ОтветитьУдалить
  22. Анонимный1 мая 2013 г., 12:01

    #include
    int main()
    {
    float a, b;
    char c;
    printf("Vvedite dva chisla cherez probel i znak deistviya: ");
    scanf("%f%f %c", &a,&b,&c);
    switch(c)
    {
    case '+': printf("\n%f\n", (a+b)); break;
    case '-': printf("\n%f\n", (a-b)); break;
    case '*': printf("\n%f\n", (a*b)); break;
    case '/': printf("\n%f\n", (a/b)); break;
    default: printf("\nERROR\n"); break;
    }
    }

    ОтветитьУдалить
  23. Этот комментарий был удален автором.

    ОтветитьУдалить
  24. Подскажите,пожалуйста,как в операторе множественного выбора задавать вопросы?Мне нужно сделать программу-тест, а я не знаю,как в Switch задавать вопросы вместо выражения

    ОтветитьУдалить
  25. Подскажите ,пожалуйста, что могут значить эти ошибки:
    error C2296: &: недопустимо, левый операнд имеет тип "const char [9]"

    error C2297: &: недопустимо, правый оператор имеет тип "float"

    Вот решение:

    #include
    int main(void)
    {
    float a,b,;
    char d;
    a=getchar();
    b=getchar();
    d=getchar();
    scanf("%f %f %c"&a,&b,&d);
    switch (d){
    case '*': printf ("=%f",a*b);break;
    case '/': printf ("=%f",a/b);break;
    case '-': printf ("=%f",a-b);break;
    case '+': printf ("=%f",a+b);break;
    default :printf("ERROR");
    }

    return(0);
    }

    ОтветитьУдалить
    Ответы
    1. В вашей программе, не порядок в запятых. Вы в одном месте поставили лишнюю, а в другом забыли. Из-за этого и повыскакивали эти ошибки. ))

      Удалить
    2. Да и вообще, много лишнего.

      Удалить
  26. Спасибо большое за Ваши уроки

    #include
    #include

    int main(void)
    {
    float a,b,x;
    char i;
    printf("Vvedite 2 chisla i znak deisviya cherez probel: ");
    scanf("%f %f %c",&a,&b,&i);
    switch (i)
    {
    case '*': x=a*b, printf("\n%f\n",x); break;
    case '+': x=a+b, printf("\n%f\n",x); break;
    case '-': x=a-b, printf("\n%f\n",x); break;
    case '/': x=a/b, printf("\n%f\n",x); break;
    default: printf("\nERROR\n"); break;
    }
    system("pause");

    return (0);
    }

    А как можно зациклить программу чтобы после вывода результата снова вернуться к вводу чисел?
    Валерий.

    ОтветитьУдалить
    Ответы
    1. Добрый день!
      Спасибо, мне приятны хорошие отзывы.
      Код вроде бы правильный, не компилировал. Думаю вы и сами это сделали. Замечаний общих нет.

      Чтобы зациклить программу можно воспользоваться циклом do while. ) Я

      Удалить
  27. #include

    int main(void) {
    int a,b;
    char c;

    printf("Vvedite dva chisla i znak :\n");
    scanf("%d %d %c",&a,&b,&c);

    switch (c) {
    case '+': printf("\n=%d\n",a+b); break;
    case '-': printf("\n=%d\n",a-b); break;
    case '*': printf("\n=%d\n",a*b); break;
    case '/': printf("\n=%d\n",a/b); break;
    default: printf("\nEROREEEEEEEEEEEE\n");
    }
    return (0);
    }


    немного подсмотрел, но патом разобрался что к чему )
    у меня вопрос )
    "char c;

    printf("Vvedite komandu: ");
    c=getchar();

    вот тут получается что мы вводим значения для С, но я не понимаю как это происходит с этой командой, но смысл её то я понял это тоже что и через сканф сделали бы но я не пойму почему именно так" c=getchar(); " ????????

    ОтветитьУдалить
  28. #include
    int main()
    {
    float a,b;
    char x;
    printf("Vvedite trebuemoe deistvie:\nPrimer vvoda: a+b:\n");
    scanf("%f%c%f",&a,&x,&b);
    switch(x)
    {
    case '+':printf("%.4f\n",a+b);break;
    case '-':printf("%.4f\n",a-b);break;
    case '*':printf("%.4f\n",a*b);break;
    case '/':printf("%.4f\n",a/b);break;
    default:printf("Error\n");break;
    }
    return 0;
    }

    ОтветитьУдалить
    Ответы
    1. Как обычно, формат хромает. Вам нужно попробовать порешать задачки с проверяющей системой. Вы бы и одной задачи не решили, с таким подходом. )))

      Удалить
    2. Есть такое...что именно лишнее и чего не хватает?!Буду рад за подсказки)

      Удалить
    3. А где найти такие задачки?!Не знаю как сформировать вопрос в гугл?!

      Удалить
  29. #include

    int main(void) {
    float a,b;
    char c;
    printf("Vvedite dva chisla i znak deistvia:\n ");
    scanf("%f%f%", &a,&b);
    c=getchar();
    switch (c) {
    case '*': printf("\nX=%f\n", a*b);break;
    case '/': printf("\nX=%f\n", a/b);break;
    case '+': printf("\nX=%f\n", (a+b));break;
    case '-': printf("\nX=%f\n", (a-b));break;
    default: printf("\nError\n");break;
    }
    return (0);
    }

    ОтветитьУдалить
    Ответы
    1. Хорошо все, кроме формата вывода.

      Удалить
  30. #include
    int main()
    {
    float a, b;
    char c;

    scanf("%f %c %f", &a, &c, &b);

    if (b==0)
    {
    printf("ERROR\n");
    }
    else
    {
    switch (c)
    {
    case '+' : printf("%f\n", a+b); break;
    case '-' : printf("%f\n", a-b); break;
    case '*' : printf("%f\n", a*b); break;
    case '/' : printf("%f\n", a/b); break;

    default: printf("ERROR\n");
    break;
    }
    }
    return(0);
    }

    ОтветитьУдалить
  31. float a,b,d;
    char s;
    printf("Vvedite 2 cisla \n");
    scanf("%f%f",&a,&b);
    printf("%f %f \n",a,b);

    printf("vvedite znak deystviya (+,-,*,/)\n");
    scanf("%c",&s);
    ...
    Когда делаешь так, то с вводом в самой проге возникают проблемы.
    Вводишь первое число - ентер
    вводишь второе число - ентер
    и scanf("%c",&s) - принимает значение ентер. Хмб ерунда какая-то:(

    ОтветитьУдалить
    Ответы
    1. а вы добавьте в scanf \n ))) Должно помочь.))

      Удалить
  32. #include
    int main(void)
    {
    float a,b;
    char c;
    printf("vvedite dva chisla i znak cherez probel\n");
    scanf("%f %f %c", &a,&b,&c);
    switch (c) {
    case '+': a+=b; printf("% f\n", a); break;
    case '-': a-=b; printf("% f\n", a); break;
    case '*': a*=b; printf("% f\n", a); break;
    case '/': a/=b; printf("% f\n", a); break;
    default: printf("eror\n"); break;
    }
    return (0);
    }

    это работает....
    объясните пожалуйста, почему это не работает?-
    #include
    int main(void)
    {
    float a,b;
    char c;
    printf("vvedite chisla \n");
    scanf("%f %f", &a, &b);
    printf("Vvedite komandu: ");
    c=getchar();
    switch (c) {
    case '+': a+=b; printf("% f\n", a); break;
    case '-': a-=b; printf("% f\n", a); break;
    case '*': a*=b; printf("% f\n", a); break;
    case '/': a/=b; printf("% f\n", a); break;
    default: printf("eror\n"); break;
    }
    return (0);
    }

    ОтветитьУдалить
    Ответы
    1. Смотрите, вы скорее всего вводите так
      4 Энтер 2 энтер
      или так
      4 пробел 2 энтер.

      И у вас сразу пишется введите команду и error.
      Дело вот в чем. Смотрите как выглядит поток stdin для первого примера
      4\n2\n
      это то, что вы введи с клавиатуры. Смотрим что считывает scanf()

      "%f %f"

      т.е. она считает
      4\n2
      а в потоке еще останется последнее \n.
      далее следует команда printf, на экран выводится надпись
      Vvedite komandu:
      дальше выполняется getchar().
      Она читает очередной символ из потока это наш оставшийся там \n т.е. энтер.
      Ну а дальше я думаю уже все понятно. ))) Сможете самостоятельно теперь исправить свой код? ))

      Удалить
  33. Спасибо.С большего доходит...Вот так работает:
    #include ((stdio.h))
    int main(void)
    {
    float a,b;
    char c;
    printf("vvedite chisla i znak cherez probel ili enter\n");
    scanf("%f %f ", &a, &b);
    c=getchar();
    switch (c) {
    case '+': a+=b; printf("% f\n", a); break;
    case '-': a-=b; printf("% f\n", a); break;
    case '*': a*=b; printf("% f\n", a); break;
    case '/': a/=b; printf("% f\n", a); break;
    default: printf("eror\n"); break;
    }
    return (0);
    }

    ОтветитьУдалить
  34. #include "stdio.h"
    #include "iostream"
    int main()
    {
    setlocale(LC_ALL, "Russian");
    int a,b,d;
    char c;
    printf("Введите выражение:\n");
    scanf("%d%c%d",&a,&c,&b);
    switch (c) {
    case '*':d=a*b,printf("%d",d);break;
    case '/':d=a/b,printf("%d",d);break;
    case '+':d=a+b,printf("%d",d);break;
    case '-':d=a-b,printf("%d",d);break;
    default:printf("ERROR");break;
    }
    printf("\n");
    system("pause");
    return 0;
    }

    ОтветитьУдалить
    Ответы
    1. Сначала два числа, потом знак действия!

      Удалить
  35. пожалуйста проверьте)
    #include

    int main(void) {
    float a,b;
    char c;

    printf("Vvedite primer: ");
    scanf("%f %f %c, &a,&b,&c");
    switch (c)
    {
    case '+': printf("\n%f5c%f\n", a+b); break;
    case '-': printf("\n%f%c%f\n", a-b); break;
    case '*': printf("\n%f%c%f\n", a*b); break;
    case '/': printf("\n%f%c%f\n", a/b); break;
    default: printf("\nERROR\n"); break;
    }
    return (0);
    }

    ОтветитьУдалить
    Ответы
    1. Есть ошибка, при считывании данных.

      Удалить
  36. #include
    #include

    int main()
    {
    float a,b,d;
    char c;

    printf("vvedite dva zelih chisla i comandu na vipolnenie\n");
    scanf("%d, %d, %c",&a,&b,&c);


    switch (c)
    {
    case'+': d=a+b; printf("\nsumma ravna %f\n",d); break;
    case'-': d=a-b; printf("\nraznost ravna %f\n",d); break;
    case'*': d=a*b; printf("\nproizvedenie ravno %f\n",d); break;
    case'/': d=a/b; printf("\nchasnoe ravno %f\n",d); break;
    default: printf("\nERROR\n"); break;
    }
    return (0);

    }

    ОтветитьУдалить
  37. Добрый день.
    А так?

    #include
    #include

    int main()
    {
    float a,b,d;
    char c;

    printf("vvedite dva zelih chisla i comandu na vipolnenie\n");
    scanf("%f %f %c",&a,&b,&c);


    switch (c)
    {
    case'+': d=a+b; printf("\nsumma ravna %f\n",d); break;
    case'-': d=a-b; printf("\nraznost ravna %f\n",d); break;
    case'*': d=a*b; printf("\nproizvedenie ravno %f\n",d); break;
    case'/': d=a/b; printf("\nchasnoe ravno %f\n",d); break;
    default: printf("\nERROR\n"); break;
    }
    return (0);

    }

    ОтветитьУдалить
    Ответы
    1. Только формат не соблюдаете, а так все верно. А можете переписать программу так, чтобы не использовалась переменная d?

      Удалить
    2. Добрый день. Вот так.

      int main()
      {
      float a,b;
      char c;

      printf("vvedite dva zelih chisla i comandu na vipolnenie\n");
      scanf("%f %f %c",&a,&b,&c);


      switch (c)
      {
      case'+': printf("\nsumma ravna %f\n",a+b); break;
      case'-': printf("\nraznost ravna %f\n",a-b); break;
      case'*': printf("\nproizvedenie ravno %f\n",a*b); break;
      case'/': printf("\nchasnoe ravno %f\n",a/b); break;
      default: printf("\nERROR\n"); break;
      }
      return (0);

      }

      Удалить
  38. #include
    int main(void)
    {
    float a, b, c;
    char s;
    printf ("\nVevite 2 chisla b znak 2+2\n");
    scanf("%f %c &f",&a,&s,&b);
    switch(s)
    {
    case '+':c=a+b; printf("=%f\n", c);break;
    case '-':c=a-b; printf("=%f\n", c);break;
    case '*':c=a*b; printf("=%f\n", c);break;
    case '/':c=a/b; printf("=%f\n", c);break;
    default:printf("\nERROR\n");break;
    }

    return (0);
    }
    как бы работает но вместо ответа выдает -107374176,000000
    где я ошибся?

    ОтветитьУдалить
    Ответы
    1. scanf("%f %c &f",&a,&s,&b); вот тут. Посмотрите внимательно на формат-строку.)

      Удалить
  39. Так правильно?
    #include

    int main(void) {
    float a,b,d;
    char c;

    printf("Vvedite dva chisla i znak: ");
    scanf("%f %f %c", &a, &b, &c);

    switch (c) {
    case '*':
    d=a*b;
    printf("\nRezyltat %f\n", d); break;
    case '/':
    if(b>0)
    {
    d=a/b;
    printf("\nRezyltat %f\n", d); break;
    }
    else
    printf("\n ERROR \n"); break;
    case '+':
    d=a+b;
    printf("\nRezyltat %f\n", d); break;
    case '-':
    d=a-b;
    printf("\nRezyltat %f\n", d); break;
    default: printf("\n ERROR \n"); break;
    }
    return (0);
    }

    ОтветитьУдалить
    Ответы
    1. Делить нельзя только на нуль, а а отрицательные числа делить можно. А в вашей программе нельзя)

      Удалить
  40. Программу писал не заглядывая в комментарии, но после их просмотра я нигде не увидел проверки в кодах программ на недопустимость арифметических операций. У меня такая проверка есть))
    #include
    #include
    int main(void)
    {
    float a,b;
    char c;
    printf("Vvedite dannye i znak deistviya\n");
    scanf("%f %f %c",&a,&b,&c);

    switch (c)
    {
    case '+':printf("Summa = %f\n",a+b); break;
    case '-':printf("Raznost = %f\n",a-b); break;
    case '*': if ((a!=0)&&(b!=0))
    {printf("Proizvedenie = %f\n",a*b);}
    else
    {printf("ERROR\n\a");}
    break;
    case '/': if ((a!=0)&&(b!=0))
    {printf("Chastnoe = %f\n",a/b);}
    else
    {printf("ERROR\n\a");}
    break;
    }
    return(0);
    }

    ОтветитьУдалить
    Ответы
    1. Неправильно. =)) Хорошо, что вы подумали о делении на ноль. Но что будет, если я введу не знак действия, а что-то другое совсем?
      И чем вам не нравится умножение на нуль?

      Удалить
    2. Исправил как вы сказали) так правильно?)
      #include
      int main(void)
      {
      float a,b;
      char c;
      printf("Vvedite dannye i znak deistviya\n");
      scanf("%f %f %c",&a,&b,&c);
      switch (c)
      {
      case '+':printf("Summa = %f\n",a+b); break;
      case '-':printf("Raznost = %f\n",a-b); break;
      case '*':printf("Proizvedenie = %f\n",a*b); break;
      case '/': if ((a!=0)&&(b!=0))
      {printf("Chastnoe = %f\n",a/b);}
      else
      {printf("ERROR\n\a");}
      break;
      default: printf("ERROR\n\a");
      }
      return(0);
      }

      Удалить
    3. при делении достаточно проверить, чтобы знаменатель не равнялся нулю. Проверка числителя излишняя осторожность. А так все хорошо. )

      Удалить
  41. #include
    int main(void)
    {
    float a,b;
    char c;
    scanf("%f,%f,%c",&a,&b,&c);
    switch (c)
    {
    case '+': printf("%f\n",a+b);break;
    case '-': printf("%f\n",a-b);break;
    case '*': printf("%f\n",a*b);break;
    case '/': printf("%f\n",a/b);break;
    default: printf("\nERROR\n");break;
    }
    return(0);
    }
    Проверьте пожалуйста и скажите где я ошибся) заранее благодарен)

    ОтветитьУдалить
    Ответы
    1. scanf("%f,%f,%c",&a,&b,&c); - не правильно, в запятых быть не должно
      scanf("%f%f%c",&a,&b,&c); - правильно
      Хотя если ты бы написал в условии введите через запятую
      printf("Vvedite chisla i deistvie cherez zapyatuyu, primer 2,9.1,+\n");
      scanf("%f,%f,%c", &a, &b, &c);
      это сработает

      Удалить
  42. #include
    int main(void)
    {
    float a, b;
    char c;
    printf("Vvedite chisla i deistvie, primer 27 901.14 +\n");
    scanf("%f %f %c", &a, &b, &c);
    if (a/b&&b==0)
    printf("ERROR\n");
    else {
    switch (c) {
    case '+': printf("=\n%0.3f\n", a+b); break;
    case '/': printf("=\n%0.3f\n", a/b); break;
    case '-': printf("=\n%0.3f\n", a-b); break;
    case '*': printf("=\n%0.3f\n", a*b); break;
    default: printf("\nERROR\n"); break;
    }
    }
    return (0);
    }

    ОтветитьУдалить
  43. #include

    int main (){
    double a, b;
    char c;
    printf ("Это простой калькулятор\nДействие:");
    scanf ("%c",&c);
    printf ("a:");
    scanf("%lf",&a);
    printf ("b:");
    scanf ("%lf",&b);
    switch (c){
    case '+':printf("%.1lf+%.1lf=%.0lf\nОтвет округлён до целых\n",a, b, a+b);break;
    case '-':printf("%.1lf-%.1lf=%.0lf\nОтвет округлён до целых\n",a, b, a-b);break;
    case '/':printf("%.1lf/%.1lf=%.0lf\nОтвет округлён до целых\n",a, b, a/b);break;
    case '*':printf("%.1lf*%.1lf=%.0lf\nОтвет округлён до целых\n",a, b, a*b);break;
    default :printf("ERROR\n");break;}
    return 0;}

    ОтветитьУдалить
  44. Анонимный21 июня 2014 г., 00:06

    #include
    #include
    int main(void)
    {
    int a, b, c;
    char s;
    printf("Vvedite dva chisla i znak: ");
    scanf("%i %i %c", &a, &b, &s);
    switch (s){
    case '+': printf("\n%i+%i=%i\n", a,b,c); break;
    case '-': printf("\n%i-%i=%i\n", a,b,c); break;
    case '*': printf("\n%i*%i=%i\n", a,b,c); break;
    case '/': if (b!=0) {
    printf("\n%i/%i=%i\n", a,b,c);}
    else {printf("\nNichego ne viidet, glupaya\n"); }
    break;
    default: printf("\nNichego ne viidet, glupaya\n"); break;
    }
    getch();
    return 0;
    }
    Вот, что вышло. И вопрос: что делать с точностью? Например, чтобы считало десятичные дроби без округления, но и при подсчете обычных целочисленных не выдавало кучу ненужных нулей. Помогите девушке, пожалуйста (:

    ОтветитьУдалить
  45. #include
    int main (void)
    {
    float a,b;
    char d;
    printf("Vvedite dva chisla i znak\n");
    scanf_s("%f %f %c",&a,&b,&d);
    switch(d)
    {
    case'+':printf("=%f\n", a+b);break;
    case'-':printf("=%f\n", a-b);break;
    case'*':printf("=%f\n", a*b);break;
    case'/':
    {
    if (b!=0)
    printf("=%f\n", a/b);
    else
    printf("ERROR\n");
    break;
    }
    default: printf("ERROR\n");
    }
    return(0);
    }
    не пойму почему всегда ERROR выводит(((

    ОтветитьУдалить
    Ответы
    1. Странно, написано всё верно. И у меня работает правильно. Я только что проверил. А вы в чем пишете?

      Удалить
    2. microsoft vicual c++ 2008 express edition
      пробовал загонять код Камиля, первый раз нормально прогнал, потом тоже начал ERror выдавать, скорей всего дело в компиляторе, либо не правильно проект создаю(((

      Удалить
    3. Анонимный26 мая 2016 г., 12:54

      Получилось решить проблему?

      Удалить
  46. Почему нет функции math.h в решениях? Разве stdio.h выполняет математические решения ?

    ОтветитьУдалить
  47. Странно, но какой бы из готовых вариантов я не пробовала ничего не выдает. ввожу в консоли "число знак число" нажимаю энтер, но ничего не происходит(((

    ОтветитьУдалить
    Ответы
    1. уже поняла)

      Удалить
    2. Поздравляю, хоть и с опозданием. )))

      Удалить
  48. #include
    #include
    int main (void)
    {
    float a, b;
    char c;
    printf("Vvedite dva chisla u znak deystviya: ");
    scanf("%f %f %c", &a, &b, &c);
    switch (c)
    {
    case '+': printf("\nOtvet %.2f\n", a+b); break;
    case '-': printf("\nOtvet %.2f\n", a-b); break;
    case '*': printf("\nOtvet %.2f\n", a*b); break;
    case '/': printf("\nOtvet %.2f\n", a/b); break;
    default: printf("\nERROR\n"); break;
    }
    return(0);
    }

    ОтветитьУдалить
    Ответы
    1. Добрый вечер, Александр.
      Скажите, а зачем у вас два include? Один stdio.h, а какой второй?

      Удалить
    2. Это с прошлых уроков остался math.h.

      Удалить
  49. Доброго времени суток!!!! Вот собственно и домашнее задание:
    # include ;
    int main (void) {
    float a, b;
    char c;
    printf ("Vvedite chislo A\nVvedite deystvie C\nVvedite chislo B\n");
    scanf ("%f %c %f", &a, &c, &b);

    switch (c) {
    case '*': a=a*b; printf ("\n A= %f \n", a); break;
    case '/': a=a/b; printf ("\n A= %f \n", a); break;
    case '+': a=a+b; printf ("\n A= %f \n", a); break;
    case '-': a=a-b; printf ("\n A= %f \n", a); break;
    default : printf ("\n Error\n"); break;
    }
    return (0); }

    В начале пытался сделать задачу при помощи функции getchar. Знаете еще по прошлым урокам заметил, что частенько пытаюсь применить ее там где она вовсе не нужна. В общем то в ходе размышлений и назрел у меня к вам уважаемый KaDeat вопрос, а можно ли при помощи getchar считать из потока данных дробь? И если можно, хотелось бы увидеть пример, так как пробовал и ничегошеньки у меня вышло.

    ОтветитьУдалить
    Ответы
    1. С помощью getchar можно считать только один символ, и ничего более. Она используется не так часто, но иногда бывает удобна. В основном для ввода данных используют scanf.

      Удалить
  50. #include
    int main (void)
    {
    float a,b,x;
    char c;
    printf("Vvedite dva chisla a,b i znak deistvia cherez probel\n");
    scanf("%f%f%c",&a,&b,&c);
    printf("znachenie a=%f, a b=%f deistvie %c\n",a,b,c);
    c=getchar();
    switch(c)
    {
    case'*':x=a*b;printf("proizvedenie=%f\n",x);break;
    case'/':x=a/b;printf("chastnoe=%f\n",x);break;
    case'+':x=a+b;printf("summa=%f\n",x);break;
    case'-':x=a-b;printf("raznost'=%f\n",x);break;
    default:printf("EROR\n");break;
    }
    return(0);
    }

    ОтветитьУдалить
  51. Этот комментарий был удален автором.

    ОтветитьУдалить
  52. Здравствуйте
    #include "stdio.h"
    int main(void)
    {
    float a,b;
    char s;
    printf ("Vvedite chicla\n");
    scanf("%f %f %c",&a,&b,&s);
    switch(s){
    case'+':printf("=%f\n",a+b);break;
    case'-':printf("=%f\n",a-b);break;
    case'*':printf("=%f\n",a*b);break;
    case'/':printf("=%f\n",a/b);break;
    default:printf("ERROR\n");
    return 0;
    }
    Потом, что бы получить ответ надо ввести два числа,далее знак. Но вот вопрос. Разве мы не должны,писать то , что в скобочка после "case" как было сказано в лекции? И почему мы пишем цифры,а не буквы?

    ОтветитьУдалить
    Ответы
    1. и как работает? у меня при использовании float выдавал постоянно 0, сразу как сменил на int( double ) заработало.

      Удалить
  53. //Практика
    #include
    int main(void)
    {
    int a, b, e;
    char c;
    printf("Vvedite 2 chisla & znak deistvia (+ - / *)\n");
    scanf("%d %d %c",&a, &b, &c);
    switch (c)
    {
    case '+' :
    e=a+b;
    printf("=%d\n",e);break;
    case '-' :
    e=a-b;
    printf("=%d\n",e);break;
    case '*' :
    e=a*b;
    printf("=%d\n",e);break;
    case '/' :
    e=a/b;
    printf("=%d\n",e);break;
    default:
    printf("Neverno vvedeno");
    }
    return(0);
    }

    ОтветитьУдалить

Примечание. Отправлять комментарии могут только участники этого блога.