С Новым годом! Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/18: Рейтинг темы: голосов - 18, средняя оценка - 4.89
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30

Проверьте себя. А хорошо ли вы знакомы со switch'ом?

12.04.2009, 20:45. Показов 3747. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
В первую очередь смысл задачи не в том, что же там напечатается, а в том, что многие увидят несколько непривычный для себя код, который на первый взгляд даже покажется синтаксически ошибочным. А потому просьба к специалистам - не спешите сразу писать решение или пояснения - кому-то может оказаться интересным подумать над задачей. По этим же соображениям пропускаю отступы

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
#include <stdio.h>
 
int main (void)
{
  int i,j;
 
  for (i = 0; i < 5; i++)
  {
    j=0;
 
    switch (i)
    if (i != 1)
    j = 11;
    else
    default:
    if (i != 2)
    case 1:
    j = 22;
    else
    case 2:
    if (i != 3)
    case 3:
    break;
    else
    case 4:
    j = 33;
 
    printf ("i=%d, j=%d\n", i, j);
  }
 
  return 0;
}
1
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
12.04.2009, 20:45
Ответы с готовыми решениями:

Проверьте себя
Думаешь, ты знаешь Си?

загрузите у себя, проверьте на ошибку
прога должна показать сост. винча загружаем ком тыкаем контрол плюс S прога резидентная должна выгрузиться по нажатия сntrl + x ...

Проверьте является ли число простым (делится только на 1 или само на себя)
/** * * @param {number} number * * @returns {boolean} */ function isPrime(number) { // write code here }

15
6 / 6 / 0
Регистрация: 28.03.2009
Сообщений: 29
12.04.2009, 20:55
просто мало кто задумывается на тему "что такое switch?". Это простой враппер для goto.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
12.04.2009, 20:56  [ТС]
Цитата Сообщение от ZeroIce Посмотреть сообщение
просто мало кто задумывается на тему "что такое switch?". Это простой враппер для goto.
Но во многих учебниках его объясняют несколько не так. Да и многие преподаватели его тоже понимают не так
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
13.04.2009, 00:47
Ну написать код, который покажется ошибочным есть очень много способов. Я и покруче видел ). А switch - обычный jump table. Поэтому при нормальном компилировании скорость перехода к любой ветви не зависит от количества этих самых ветвей. А вообще все фигня )
0
6 / 6 / 0
Регистрация: 28.03.2009
Сообщений: 29
13.04.2009, 08:54
Цитата Сообщение от Evg Посмотреть сообщение
Но во многих учебниках его объясняют несколько не так. Да и многие преподаватели его тоже понимают не так
Надо просто показать преподавателю дизасм или асм листинг if () goto и switch. И пусть скажет где из них кто.

Добавлено через 1 минуту 50 секунд
Цитата Сообщение от Vourhey Посмотреть сообщение
Ну написать код, который покажется ошибочным есть очень много способов. Я и покруче видел ). А switch - обычный jump table. Поэтому при нормальном компилировании скорость перехода к любой ветви не зависит от количества этих самых ветвей. А вообще все фигня )
Скорость перехода зависит от числа ветвей - там простой перебор значений (cmp). Другое дело - скорости сейчас такие что этим можно пренебречь и switch в пару тысяч case встечается редко (и это скорее будет ошибка архитектуры).
0
 Аватар для Humanitis
176 / 168 / 27
Регистрация: 12.01.2009
Сообщений: 430
13.04.2009, 09:57
Цитата Сообщение от ZeroIce Посмотреть сообщение
там простой перебор значений (cmp)
Не всегда. Компилятор при определенных условиях создает либо таблицу переходов, либо набор условных переходов.Все зависит от компилятора.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
13.04.2009, 12:17  [ТС]
Цитата Сообщение от ZeroIce Посмотреть сообщение
Надо просто показать преподавателю дизасм или асм листинг if () goto и switch. И пусть скажет где из них кто.
Если зачёт тебе ещё не поставлен - я бы не рекомендовал показывать такие вещи этим самым некоторым А то чего доброго назначат тебя козлом отпущения

Цитата Сообщение от ZeroIce Посмотреть сообщение
Скорость перехода зависит от числа ветвей - там простой перебор значений (cmp). Другое дело - скорости сейчас такие что этим можно пренебречь и switch в пару тысяч case встечается редко (и это скорее будет ошибка архитектуры).
Современные компиляторы строят switch на переходах только в случае слишком маленького числа альтернатив. Для большого числа альтернатив строится табличка с адресами переходов, а аргумент switch'а по сути является ключом в эту табличку. И теперь скокрость работы кода не зависит от количества альтернатив. Косвенным образом всё-таки зависит, т.к. изменение числа альтернатив ведёт к изменению размера таблицы, что влечёт за собой изменения при работе кэша данных, однако промышленные компиляторы в "боевых" режимах это не учитывают. Исключение составляют случаи, когда публикуются цифры производительности - в этом случае разработчики как правило не стесняются использовать кучу нечестных способов, при этом внешне всё должно выглядеть так, как будто бы это фича
0
 Аватар для Humanitis
176 / 168 / 27
Регистрация: 12.01.2009
Сообщений: 430
13.04.2009, 13:16
Цитата Сообщение от Evg Посмотреть сообщение
Современные компиляторы строят switch на переходах только в случае слишком маленького числа альтернатив.
Ну не совсем верно,от количества-да,но еще надо брать в расчет размер таблицы которая будет генерироваться.
т.е. если я напишу
C++
1
2
3
4
5
6
7
8
    switch(i)
    {
    case(12):i=23;
        case(13):i=233;
            case(14):i=25;
                case(15):i=26;
                    case(16):i=27;
    }
таблица будет сгенирирована,
а если чуть подправлю
C++
1
2
3
4
5
6
7
8
    switch(i)
    {
    case(12):i=23;
        case(13):i=233;
            case(14):i=25;
                case(15):i=26;
                    case(1666):i=27;//вот тут
    }
то уже нет. Так как компилятор не станет генерить таблицу в 1654 байта
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
13.04.2009, 13:44  [ТС]
Верно подметил. Я в своём объяснении упустил фразу "объяснение на пальцах". Реально же там миллион вариаций может быть. В твоём случае по каким-либо опциями пиковой производительности может так же построиться таблица - памяти нынче много (особенно когда это дело касается публикации цифр производительности). В твоём втором примере компилятор может "левую" альтернативу 1666 сделать на переходе, а на оставшиеся 12-15 сделать табличку.
0
Любитель давать советы
 Аватар для Alexiski
342 / 135 / 14
Регистрация: 12.01.2009
Сообщений: 511
13.04.2009, 16:05
Интересный пример. Сам придумал или где-то подсмотрел?
0
6 / 6 / 0
Регистрация: 28.03.2009
Сообщений: 29
13.04.2009, 16:19
Цитата Сообщение от Evg Посмотреть сообщение
Если зачёт тебе ещё не поставлен - я бы не рекомендовал показывать такие вещи этим самым некоторым А то чего доброго назначат тебя козлом отпущения



Современные компиляторы строят switch на переходах только в случае слишком маленького числа альтернатив. Для большого числа альтернатив строится табличка с адресами переходов, а аргумент switch'а по сути является ключом в эту табличку. И теперь скокрость работы кода не зависит от количества альтернатив. Косвенным образом всё-таки зависит, т.к. изменение числа альтернатив ведёт к изменению размера таблицы, что влечёт за собой изменения при работе кэша данных, однако промышленные компиляторы в "боевых" режимах это не учитывают. Исключение составляют случаи, когда публикуются цифры производительности - в этом случае разработчики как правило не стесняются использовать кучу нечестных способов, при этом внешне всё должно выглядеть так, как будто бы это фича
про преподов - все зависит от адекватности человека (некоторые люди уверены что при увеличении int число обратится в 0, а не в минус).

Про компиллеры - о каком речь? Хочу потестить.

Добавлено через 2 минуты 10 секунд
Цитата Сообщение от Humanitis Посмотреть сообщение
Ну не совсем верно,от количества-да,но еще надо брать в расчет размер таблицы которая будет генерироваться.
т.е. если я напишу
C++
1
2
3
4
5
6
7
8
    switch(i)
    {
    case(12):i=23;
        case(13):i=233;
            case(14):i=25;
                case(15):i=26;
                    case(16):i=27;
    }
таблица будет сгенирирована,
а если чуть подправлю
C++
1
2
3
4
5
6
7
8
    switch(i)
    {
    case(12):i=23;
        case(13):i=233;
            case(14):i=25;
                case(15):i=26;
                    case(1666):i=27;//вот тут
    }
то уже нет. Так как компилятор не станет генерить таблицу в 1654 байта
без brake возможно компиллер просто оптимизирует и сведет все к case(1666):i=27; (12, 13, etc смысла не несут)
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
13.04.2009, 16:50  [ТС]
Цитата Сообщение от ZeroIce Посмотреть сообщение
про преподов - все зависит от адекватности человека (некоторые люди уверены что при увеличении int число обратится в 0, а не в минус).
Конечно всё от человека зависит. Непомню, в какой-то книже предисловие от автора читал: "мне 70 лет, я никогда в жизни не был программистом и подозревал, что учиться в 70 лет уже поздно. Но тут я увидел борланд ц, он мне настолько понравился, что я сейчас вас всех научу программированию". Конечно, не такими словами, но вот с приблизительным смыслом

Цитата Сообщение от ZeroIce Посмотреть сообщение
Про компиллеры - о каком речь? Хочу потестить.
О любом. Если есть возможность - смотри gcc, из консоли мне кажется это дело проще увидеть. 'gcc t.c -S' - в резудьтате создастся ассемблерный текст t.s. Можешь добавить опцию оптимизации типа -O2, чтобы лишних пересылок и мусорного кода не было. Но в этом случае программу пиши так, чтобы мёртвый код в ней не удалился (напрмер, используй глобальные переменные вместо локальных)

Цитата Сообщение от ZeroIce Посмотреть сообщение
без brake возможно компиллер просто оптимизирует и сведет все к case(1666):i=27; (12, 13, etc смысла не несут)
Не совсем так. Если i равно 12, 13, 14, 15, то мы тоже должны попасть на строку i=27, но если изначально i, к примеру, было равно 100, то мы не попадём никуда

Т.е. в резудьтате оптимизации код сведётся к
C++
1
2
3
4
5
6
7
8
9
switch(i)
{
  case(12):
  case(13):
  case(14):
  case(15):
  case(1666):
    i=27;
}
или, что более вероятно в виду маленького количества альтернатив

C++
1
2
if ((i>=12 && i <=15) || i==1666)
  i=27;
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
09.06.2009, 22:02  [ТС]
Цитата Сообщение от Alexiski Посмотреть сообщение
Интересный пример. Сам придумал или где-то подсмотрел?
Тогда не заметил вопрос. А зачем подсматривать, если понятна логика работы - проще придумать

Для истории. Чтобы не копипэйстить - семантику работы switch'а описал тут
0
2343 / 499 / 22
Регистрация: 01.04.2009
Сообщений: 2,200
10.06.2009, 06:50
Evg, ты пишешь как ДОЛЖЕН работать switch по логике, а не как он работает в реальных компиляторах.
просто программисты компиляторов все случаи предусмотреть не могут, и, в итоге, нередко все работает совсем не так как задумано.
могу подкинуть еще идею все интересующимя:
попробуйте разработать код(алгоритм) с минимальным числом переходов.
посмотрим, что у вас получится.
потом напишу, что делал я.
0
0 / 0 / 0
Регистрация: 10.06.2009
Сообщений: 19
10.06.2009, 11:02
Evg, интересно было бы, для себя, увидеть код с отступами или {}. Проверить как бы, правильно ли я понял.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
10.06.2009, 11:38  [ТС]
Цитата Сообщение от Patch Посмотреть сообщение
Evg, ты пишешь как ДОЛЖЕН работать switch по логике, а не как он работает в реальных компиляторах.
Поясни конкретнее, что ты имеешь ввиду. Как ДОЛЖЕН работать switch написано в стандарте. Если ты имеешь в виду, что я пишу, как должен строить код switch'а компилятор, но я не пишу, что компилятор обязан что-то делать, а пишу о том, как хороший компилятор должен строит switch, чтобы он рабоал эффективно

Цитата Сообщение от Patch Посмотреть сообщение
просто программисты компиляторов все случаи предусмотреть не могут, и, в итоге, нередко все работает совсем не так как задумано.
Опять-таки, в хорошем компиляторе должно быть предусмотрено 99% случаев. Есть граничные случаи (например, 5 альтернатив, где более эффективным оказывается не тот вариант, где просчитано математическое количество операций, а тот, где состояние кэша команд или кэша данных в конкретный момент исполнения более способствует быстрому исполнению). "Хорошие" варианты (большое количество альтернатив, лежащих плотно), нормальный компилятор построит на таблице переходов

Цитата Сообщение от Patch Посмотреть сообщение
могу подкинуть еще идею все интересующимя:
попробуйте разработать код(алгоритм) с минимальным числом переходов.
посмотрим, что у вас получится.
потом напишу, что делал я.
Опять-таки, алгоритм чего?

Добавлено через 48 секунд
Цитата Сообщение от Eternal-Thunder Посмотреть сообщение
Evg, интересно было бы, для себя, увидеть код с отступами или {}. Проверить как бы, правильно ли я понял.
Здесь тоже вопроса не осилил

Добавлено через 25 минут 50 секунд
Eternal-Thunder, долшло, что ты имел ввиду. Вот такой код. При этом считай, что case'ы и default - это обычные метки, а операция switch - это динамический goto на одну из этих меток

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
37
38
39
40
41
42
43
#include <stdio.h>
 
int main (void)
{
  int i,j;
 
  for (i = 0; i < 5; i++)
  {
    j=0;
 
    switch (i)
    {
      if (i != 1)
      {
        j = 11;
      } else
      {
    default:
        if (i != 2)
        {
    case 1:
          j = 22;
        } else
        {
    case 2:
          if (i != 3)
          {
    case 3:
            break;
          } else
          {
    case 4:
            j = 33;
          }
        }
      }
    }
 
    printf ("i=%d, j=%d\n", i, j);
  }
 
  return 0;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
10.06.2009, 11:38
Помогаю со студенческими работами здесь

На олимпиаду прибыло N человек. Некоторые из них знакомы между собой
Добрый вечер. На олимпиаду прибыло N человек. Некоторые из них знакомы между собой. Разработать и реализовать алгоритм, определяющий,...

Прыгающий пинг на ноуте + потеря до 10% по WiFi. По проводу все хорошо, со 2 ноута все хорошо (провод + wifi)
Пинг до гугла. Ответ от 173.194.113.210: число байт=32 время=120мс TTL=56 Ответ от 173.194.113.210: число байт=32 время=154мс TTL=56 ...

Нужно, чтобы форма распечатала сама себя, или только часть себя
Помогите, плиз! Нужно, чтобы форма (для этого имеется кнопка на форме) распечатала сама себя, или только часть себя. Как это сделать?...

STL Вектор Копирование элемнтов себя из себя
Смысл такой, вектор содержит несколько чисел 1,2,3,4,5,6,7 Я хочу на алгоритмах скопировать некоторый блок элементов. например ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Old Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru