Форум программистов, компьютерный форум CyberForum.ru

C++

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 22, средняя оценка - 4.77
Evg
Эксперт CАвтор FAQ
17387 / 5625 / 351
Регистрация: 30.03.2009
Сообщений: 15,406
Записей в блоге: 26
#1

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

12.04.2009, 20:45. Просмотров 2643. Ответов 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;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.04.2009, 20:45     Проверьте себя. А хорошо ли вы знакомы со switch'ом?
Посмотрите здесь:

C++ Глобальные указатели. Плохо или хорошо?
C++ реализация класса в .h файле хорошо или плохо?
C++ Сделать хорошо на других компах программу консоль?
Хорошо написанный код C++
C++ WinAPI Есть работа для человека хорошо знающего C++
C++ Хорошо ли использовать библиотеку fstream?
STL Вектор Копирование элемнтов себя из себя C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ZeroIce
6 / 6 / 0
Регистрация: 28.03.2009
Сообщений: 29
12.04.2009, 20:55     Проверьте себя. А хорошо ли вы знакомы со switch'ом? #2
просто мало кто задумывается на тему "что такое switch?". Это простой враппер для goto.
Evg
Эксперт CАвтор FAQ
17387 / 5625 / 351
Регистрация: 30.03.2009
Сообщений: 15,406
Записей в блоге: 26
12.04.2009, 20:56  [ТС]     Проверьте себя. А хорошо ли вы знакомы со switch'ом? #3
Цитата Сообщение от ZeroIce Посмотреть сообщение
просто мало кто задумывается на тему "что такое switch?". Это простой враппер для goto.
Но во многих учебниках его объясняют несколько не так. Да и многие преподаватели его тоже понимают не так
Vourhey
Почетный модератор
6474 / 2249 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
13.04.2009, 00:47     Проверьте себя. А хорошо ли вы знакомы со switch'ом? #4
Ну написать код, который покажется ошибочным есть очень много способов. Я и покруче видел ). А switch - обычный jump table. Поэтому при нормальном компилировании скорость перехода к любой ветви не зависит от количества этих самых ветвей. А вообще все фигня )
ZeroIce
6 / 6 / 0
Регистрация: 28.03.2009
Сообщений: 29
13.04.2009, 08:54     Проверьте себя. А хорошо ли вы знакомы со switch'ом? #5
Цитата Сообщение от Evg Посмотреть сообщение
Но во многих учебниках его объясняют несколько не так. Да и многие преподаватели его тоже понимают не так
Надо просто показать преподавателю дизасм или асм листинг if () goto и switch. И пусть скажет где из них кто.

Добавлено через 1 минуту 50 секунд
Цитата Сообщение от Vourhey Посмотреть сообщение
Ну написать код, который покажется ошибочным есть очень много способов. Я и покруче видел ). А switch - обычный jump table. Поэтому при нормальном компилировании скорость перехода к любой ветви не зависит от количества этих самых ветвей. А вообще все фигня )
Скорость перехода зависит от числа ветвей - там простой перебор значений (cmp). Другое дело - скорости сейчас такие что этим можно пренебречь и switch в пару тысяч case встечается редко (и это скорее будет ошибка архитектуры).
Humanitis
172 / 164 / 6
Регистрация: 12.01.2009
Сообщений: 430
13.04.2009, 09:57     Проверьте себя. А хорошо ли вы знакомы со switch'ом? #6
Цитата Сообщение от ZeroIce Посмотреть сообщение
там простой перебор значений (cmp)
Не всегда. Компилятор при определенных условиях создает либо таблицу переходов, либо набор условных переходов.Все зависит от компилятора.
Evg
Эксперт CАвтор FAQ
17387 / 5625 / 351
Регистрация: 30.03.2009
Сообщений: 15,406
Записей в блоге: 26
13.04.2009, 12:17  [ТС]     Проверьте себя. А хорошо ли вы знакомы со switch'ом? #7
Цитата Сообщение от ZeroIce Посмотреть сообщение
Надо просто показать преподавателю дизасм или асм листинг if () goto и switch. И пусть скажет где из них кто.
Если зачёт тебе ещё не поставлен - я бы не рекомендовал показывать такие вещи этим самым некоторым А то чего доброго назначат тебя козлом отпущения

Цитата Сообщение от ZeroIce Посмотреть сообщение
Скорость перехода зависит от числа ветвей - там простой перебор значений (cmp). Другое дело - скорости сейчас такие что этим можно пренебречь и switch в пару тысяч case встечается редко (и это скорее будет ошибка архитектуры).
Современные компиляторы строят switch на переходах только в случае слишком маленького числа альтернатив. Для большого числа альтернатив строится табличка с адресами переходов, а аргумент switch'а по сути является ключом в эту табличку. И теперь скокрость работы кода не зависит от количества альтернатив. Косвенным образом всё-таки зависит, т.к. изменение числа альтернатив ведёт к изменению размера таблицы, что влечёт за собой изменения при работе кэша данных, однако промышленные компиляторы в "боевых" режимах это не учитывают. Исключение составляют случаи, когда публикуются цифры производительности - в этом случае разработчики как правило не стесняются использовать кучу нечестных способов, при этом внешне всё должно выглядеть так, как будто бы это фича
Humanitis
172 / 164 / 6
Регистрация: 12.01.2009
Сообщений: 430
13.04.2009, 13:16     Проверьте себя. А хорошо ли вы знакомы со switch'ом? #8
Цитата Сообщение от 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 байта
Evg
Эксперт CАвтор FAQ
17387 / 5625 / 351
Регистрация: 30.03.2009
Сообщений: 15,406
Записей в блоге: 26
13.04.2009, 13:44  [ТС]     Проверьте себя. А хорошо ли вы знакомы со switch'ом? #9
Верно подметил. Я в своём объяснении упустил фразу "объяснение на пальцах". Реально же там миллион вариаций может быть. В твоём случае по каким-либо опциями пиковой производительности может так же построиться таблица - памяти нынче много (особенно когда это дело касается публикации цифр производительности). В твоём втором примере компилятор может "левую" альтернативу 1666 сделать на переходе, а на оставшиеся 12-15 сделать табличку.
Alexiski
Любитель давать советы
338 / 130 / 2
Регистрация: 12.01.2009
Сообщений: 511
13.04.2009, 16:05     Проверьте себя. А хорошо ли вы знакомы со switch'ом? #10
Интересный пример. Сам придумал или где-то подсмотрел?
ZeroIce
6 / 6 / 0
Регистрация: 28.03.2009
Сообщений: 29
13.04.2009, 16:19     Проверьте себя. А хорошо ли вы знакомы со switch'ом? #11
Цитата Сообщение от 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 смысла не несут)
Evg
Эксперт CАвтор FAQ
17387 / 5625 / 351
Регистрация: 30.03.2009
Сообщений: 15,406
Записей в блоге: 26
13.04.2009, 16:50  [ТС]     Проверьте себя. А хорошо ли вы знакомы со switch'ом? #12
Цитата Сообщение от 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;
Evg
Эксперт CАвтор FAQ
17387 / 5625 / 351
Регистрация: 30.03.2009
Сообщений: 15,406
Записей в блоге: 26
09.06.2009, 22:02  [ТС]     Проверьте себя. А хорошо ли вы знакомы со switch'ом? #13
Цитата Сообщение от Alexiski Посмотреть сообщение
Интересный пример. Сам придумал или где-то подсмотрел?
Тогда не заметил вопрос. А зачем подсматривать, если понятна логика работы - проще придумать

Для истории. Чтобы не копипэйстить - семантику работы switch'а описал тут
Patch
2276 / 491 / 11
Регистрация: 01.04.2009
Сообщений: 2,178
10.06.2009, 06:50     Проверьте себя. А хорошо ли вы знакомы со switch'ом? #14
Evg, ты пишешь как ДОЛЖЕН работать switch по логике, а не как он работает в реальных компиляторах.
просто программисты компиляторов все случаи предусмотреть не могут, и, в итоге, нередко все работает совсем не так как задумано.
могу подкинуть еще идею все интересующимя:
попробуйте разработать код(алгоритм) с минимальным числом переходов.
посмотрим, что у вас получится.
потом напишу, что делал я.
Eternal-Thunder
0 / 0 / 0
Регистрация: 10.06.2009
Сообщений: 19
10.06.2009, 11:02     Проверьте себя. А хорошо ли вы знакомы со switch'ом? #15
Evg, интересно было бы, для себя, увидеть код с отступами или {}. Проверить как бы, правильно ли я понял.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.06.2009, 11:38     Проверьте себя. А хорошо ли вы знакомы со switch'ом?
Еще ссылки по теме:

На олимпиаду прибыло N человек. Некоторые из них знакомы между собой C++
Статические функции-члены - хорошо или плохо? C++
у кого хорошо с C++ ?! C++
C++ Указатель: всегда ли использование указателей хорошо?
Все ли хорошо в этом коде C++

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

Или воспользуйтесь поиском по форуму:
Evg
Эксперт CАвтор FAQ
17387 / 5625 / 351
Регистрация: 30.03.2009
Сообщений: 15,406
Записей в блоге: 26
10.06.2009, 11:38  [ТС]     Проверьте себя. А хорошо ли вы знакомы со switch'ом? #16
Цитата Сообщение от 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;
}
Yandex
Объявления
10.06.2009, 11:38     Проверьте себя. А хорошо ли вы знакомы со switch'ом?
Ответ Создать тему
Опции темы

Текущее время: 21:16. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru