Re[8]: семантика switch/case
От: Sheridan Россия  
Дата: 22.12.15 11:15
Оценка:
Здравствуйте, Privalov, Вы писали:


P>Напиши "черный список" для Nokia 3710, а то у меня руки не доходят. Там памяти, правда, чуть побольше, чем в микроконтроллере.

Не, для антиквариата неохота писать...
Matrix has you...
Re[9]: семантика switch/case
От: Privalov  
Дата: 22.12.15 12:25
Оценка:
Здравствуйте, Sheridan, Вы писали:

P>>Напиши "черный список" для Nokia 3710, а то у меня руки не доходят.

S>Не, для антиквариата неохота писать...


Так и скажи: лень. Я пойму.
У меня этот антиквариат отлично работает. Ему бы черный список, и больше ничего не надо.
Re[5]: семантика switch/case
От: Дрободан Фрилич СССР  
Дата: 22.12.15 13:07
Оценка:
_hum_:

__>так поэтому я и обратил на эту штуку внимание только сейчас, после долгих лет знакомства,

Не верится чего-то в долгия лета знакомства с сями...
Модератор-националист Kerk преследует оппонентов по политическим мотивам.
Re[10]: семантика switch/case
От: Sheridan Россия  
Дата: 22.12.15 14:26
Оценка:
Здравствуйте, Privalov, Вы писали:


P>Так и скажи: лень. Я пойму.

Да, лень

P>У меня этот антиквариат отлично работает. Ему бы черный список, и больше ничего не надо.

Жена пару лет назад ездила в тайланд с семьёй сестры, ей было задание — привезти самый дешевый новый телефон, который сможет найти. Купила чтото рублей за триста, лежит щас упакованный пылится на всякий случай
Matrix has you...
Re[6]: семантика switch/case
От: утпутуук  
Дата: 23.12.15 10:16
Оценка: :))
Здравствуйте, B0FEE664, Вы писали:

__>>2) нигде в литературе я не видел, чтобы кто-то обращал на это внимание (соответственно, я только теперь столкнулся с этим)

BFE>Значит вы не читали Страуструпа.

Поправил

Ну точно, как я в первом семестре. Пропустил лекцию, там где рассказывали про обращение к полям структуры по указателю, и весь семестр
// вместо
p->member = N;
// писал
T tmp = *p;
tmp.member = N;
*p = tmp;


Отредактировано 23.12.2015 10:19 утпутуук . Предыдущая версия .
Re: семантика switch/case
От: maxluzin Европа  
Дата: 30.12.15 07:38
Оценка:
Здравствуйте, _hum_, Вы писали:

__>Всегда полагал, что семантика switch/case/case/... аналогична if/if/if/... без break-а и if/else if/else if/... c break-ом. А тут решил не ставить break "в конце ветки выбора", и опля — сюрприз. Так что, товарищи, кто еще так же, как и я, заблуждался, будьте внимательны:

// ...
__>p.s. Вопрос к знатокам — зачем такая неочевидная и "техническая" семантика?

В известной книжке отцов-основателей языка "С" Кернигана и Ритчи в главе 3.4 приводится такой пример:
#include <stdio.h>
main() /* подсчет цифр, символов-разделителей и прочих символов */
{
    int c, i, nwhite, nother, ndigit[10];
    nwhite = nother = 0;
    for (i = 0; i < 10; i++)
        ndigit[i] = 0;
    while ((с = getchar()) != EOF) {
        switch (c) {
        case '0' : case '1' : case '2' : case '3' : case '4' :
        case '5' : case '6' : case '7' : case '8' : case '9' :
            ndigit[c - '0']++;
            break;
        case ' ':
        case '\n':
        case '\t':
            nwhite++;
            break;
        default:
            nother++;
            break;
        }
    }
    printf ("цифр =");
    for (i = 0; i < 10; i++)
        printf (" %d", ndigit[i]);
    printf(", символов-разделителей = %d, прочих = %d\n",
            nwhite, nother);
    return 0;
}

...как альтернатива той же самой программы, но с использованием if...then в первой главе:

#include <stdio.h>

/* подсчет цифр, символов-разделителей и прочих символов */
main()
{
    int с, i, nwhite, nother;
    int ndigit[10];

    nwhite = nother = 0;
    for (i = 0; i < 10, ++i)
        ndigit[i]= 0;
    while ((c = getchar()) != EOF)
        if (c >='0' && с <= '9')
            ++ndigit[c – '0'];
        else if (c == ' ' || c == '\n' || c == '\t')
            ++nwhite;
        else 
            ++nother;

    printf(“цифры =“);
    for (i = 0; i < 10; ++i)
        printf(“%d”, ndigit[i]);
    printf(“, символы-разделители =%d, прочие =%d\n”, nwhite, nother);
}


Там же они сами и дают комментарий на этот счёт:

"Сквозное" выполнение ветвей case вызывает смешанные чувства. С одной стороны, это хорошо, поскольку позволяет несколько ветвей case объединить в одну, как мы и поступили с цифрами в нашем примере. Но с другой — это означает, что в конце почти каждой ветви придется ставить break, чтобы избежать перехода к следующей. Последовательный проход по ветвям — вещь ненадежная, это чревато ошибками, особенно при изменении программы. За исключением случая с несколькими метками для одного вычисления, старайтесь по возможности реже пользоваться сквозным проходом, но если уж вы его применяете, обязательно комментируйте эти особые места.

Добрый вам совет: даже в конце последней ветви (после default в нашем примере) помещайте инструкцию break, хотя с точки зрения логики в ней нет никакой необходимости. Но эта маленькая предосторожность спасет вас, когда однажды вам потребуется добавить в конец еще одну ветвь case.


Где-то в другом месте в интервью (которое я уже не найду) они сказали про switch...case, что так было проще и естественнее реализовывать компилятор с "С" на скудных ресурсах PDP-11 (кажется), т.к. компилятор с "С" является однопроходным и это тогда выставлялось его огромным преимуществом, т.к. программы компилировались значительно быстрее, чем на двух-проходных... Отмазка, короче...
Отредактировано 30.12.2015 8:00 maxluzin . Предыдущая версия .
Re[2]: семантика switch/case
От: AlexRK  
Дата: 30.12.15 07:58
Оценка: +2
Здравствуйте, maxluzin, Вы писали:

M>В известной книжке отцов-основателей языка "С" Кернигана и Ритчи в главе 3.4 приводится такой пример:


Вот не понимаю, почему нельзя было сделать так, без этих break-костылей (разумеется, это не валидная программа на C):

#include <stdio.h>
main() /* подсчет цифр, символов-разделителей и прочих символов */
{
    int c, i, nwhite, nother, ndigit[10];
    nwhite = nother = 0;
    for (i = 0; i < 10; i++)
        ndigit[i] = 0;
    while ((с = getchar()) != EOF) {
        switch (c) {
        case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
            ndigit[c - '0']++;
        case ' ', '\n', '\t':
            nwhite++;
        default:
            nother++;
        }
    }
    printf ("цифр =");
    for (i = 0; i < 10; i++)
        printf (" %d", ndigit[i]);
    printf(", символов-разделителей = %d, прочих = %d\n",
            nwhite, nother);
    return 0;
}


Проще, короче, нагляднее, безопаснее.
Если обработчики веток совпадают лишь частично, внутри таких веток можно уже разрулить if-ами.
Паттерн-матчинг, конечно, круче, но про него в контексте Ц говорить, наверное, не очень уместно.
Re[3]: семантика switch/case
От: maxluzin Европа  
Дата: 30.12.15 10:01
Оценка: +1
Здравствуйте, AlexRK, Вы писали:

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


M>>В известной книжке отцов-основателей языка "С" Кернигана и Ритчи в главе 3.4 приводится такой пример:


ARK>Вот не понимаю, почему нельзя было сделать так, без этих break-костылей (разумеется, это не валидная программа на C):


ARK>
ARK>    // ...
ARK>


Если честно, то не знаю — я не автор языка и какими принципами авторы "С" руководствовались, мне не ведомо... Как уже сказал, на задворках памяти всплывает одно интервью об истории создания "С" толи Томсона, толи Кернигана, толи самого Денниса Ритчи, которое было лет 25 назад в каком-то бумажном компьютерном журнале. Там был и вопрос про switch..case и про другие "странности" реализации, например, про необходимость header-файлов... Ответ уже точно не вспомню, но точно помню, как уже сказал, что ссылались на скудность ресурсов PDP-11 и на реализацию однопроходного компилятора. А по-моему, просто им было некогда думать о будущих дискуссиях и так проще было реализовать примитивную рекурсивную функцию по константным значениям в таблице поиска по единственному ключу. Надо смотреть в исходники самого компилятора "С", чтобы точно ответить на этот вопрос, но я этим точно заниматься не буду... Думаю, всё проще! Компилятор был однопроходный, создавал таблицу символов без глубокого анализа и поиска зависимостей, надо было сделать что-то получше, чем просто батарею длинных GOTO-блоков Фортрана. Ввели switch...case, как более удобную замену фортрановским GOTO-блокам, без всяких задней мыслей...

ARK>Проще, короче, нагляднее, безопаснее.

ARK>Если обработчики веток совпадают лишь частично, внутри таких веток можно уже разрулить if-ами.
ARK>Паттерн-матчинг, конечно, круче, но про него в контексте Ц говорить, наверное, не очень уместно.

Думаю, что с "колокольни" 2015-ого гораздо проще "тыкать ухоженными пальчиками с розовыми ноготками" в бородатых авторов языка от 1972-ого года рождения для машины с 64К оперативной памяти...

Хрен знает! Так получилось! Что ж теперь делать...

З.Ы. Я вот, например, по-привычке "обволакиваю" case-блоки в {}-скобки, хотя это и необязательно. Но так мне "синтаксически юниформно"...
Отредактировано 30.12.2015 10:11 maxluzin . Предыдущая версия .
Re[13]: семантика switch/case
От: maxluzin Европа  
Дата: 30.12.15 10:27
Оценка:
Здравствуйте, _hum_, Вы писали:

//...

__>речь шла о человечности семантики для случая без break


О какой "человеческой семантике" можно говорить, когда язык создавался как можно ближе к ассемблеру по функциональности и быстродействию откомпиллированных программ?
Re[3]: семантика switch/case
От: maxluzin Европа  
Дата: 30.12.15 10:31
Оценка:
Здравствуйте, AlexRK, Вы писали:

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


M>>В известной книжке отцов-основателей языка "С" Кернигана и Ритчи в главе 3.4 приводится такой пример:


ARK>Вот не понимаю, почему нельзя было сделать так, без этих break-костылей (разумеется, это не валидная программа на C):


ARK>
ARK>        case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
ARK>


Кстати, потому что это выражение по семантике "С" будет равно '9', как результат выражений через запятую... Может поэтому?
Re[4]: семантика switch/case
От: watchmaker  
Дата: 30.12.15 11:45
Оценка:
Здравствуйте, maxluzin, Вы писали:

ARK>>
ARK>>        case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
ARK>>


M>Кстати, потому что это выражение по семантике "С" будет равно '9', как результат выражений через запятую... Может поэтому?


Повторюсь: нет, не поэтому
Автор: watchmaker
Дата: 16.12.15
. В языках C и C++ запятая в этом контексте не является оператором — об этом достаточно явно сказано в грамматике.
Так что если в новом стандарте будет введено правило, позволяющее трактовать такую конструкцию как множественный выбор, то это не сломает совместимости с предыдущими версиями или со старым кодом. Кстати говоря, в gcc и clang для таких случаев уже давным-давно есть расширение case ranges, правда оставшиеся только расширениями. Судя по всему, все неоднократные попытки изменить switch (убрать неявный fallthrough и/или добавить множественный выбор) в комитете так и не получили полной поддержки.
Re[4]: семантика switch/case
От: AlexRK  
Дата: 30.12.15 12:11
Оценка:
Здравствуйте, maxluzin, Вы писали:

M>Кстати, потому что это выражение по семантике "С" будет равно '9', как результат выражений через запятую... Может поэтому?


Ну другой оператор можно вместо запятой.
Re[3]: семантика switch/case
От: ononim  
Дата: 30.12.15 15:29
Оценка:
ARK>Вот не понимаю, почему нельзя было сделать так, без этих break-костылей (разумеется, это не валидная программа на C):
Потому что вот этот вот код будет более громоздко выглядеть
Автор: ononim
Дата: 17.12.15

Поймите, break — это абстракция более высокого уровня нежели возможность перечисления case'ов подряд, которая сама по себе является лишь маленьким частным случаем возможности пихать брейк в switch'е куда угодно и сколько угодно раз.
Как много веселых ребят, и все делают велосипед...
Re[5]: семантика switch/case
От: maxluzin Европа  
Дата: 30.12.15 15:37
Оценка: :)
Здравствуйте, watchmaker, Вы писали:

W>Повторюсь: нет, не поэтому
Автор: watchmaker
Дата: 16.12.15
. В языках C и C++ запятая в этом контексте не является оператором — об этом достаточно явно сказано в грамматике.

W>Так что если в новом стандарте будет введено правило, позволяющее трактовать такую конструкцию как множественный выбор, то это не сломает совместимости с предыдущими версиями или со старым кодом. Кстати говоря, в gcc и clang для таких случаев уже давным-давно есть расширение case ranges, правда оставшиеся только расширениями. Судя по всему, все неоднократные попытки изменить switch (убрать неявный fallthrough и/или добавить множественный выбор) в комитете так и не получили полной поддержки.

Ну хорошо, а как вы будете бороться с такой ситуацией?:

/** nonsence.h **/

#if defined(_ONE_)

#    define CONST_A  (1)
// ...
#    define CONST_B  (2)
#    define CONST_C  (3)
// ...
#    define CONST_D  (1)   /* Hello ! */

#else

#    define CONST_A  (1)
// ...
#    define CONST_B  (2)
#    define CONST_C  (3)
// ...
#    define CONST_D  (4)   /* OK */

#endif


#include "nonsence.h"

int main()
{
    //...
    switch (X)
    {
        case (CONST_A, CONST_B):    // 1 or 2
            foo();
            break;
        case (CONST_C, CONST_D):    // 3 or 1
            bar();
            break;
        case ((CONST_A & CONST_B) | (CONST_C & CONST_D) ):
            blah_blah();
            break;
        default:
            //...
    }
    // ...
    return (0);
}


И чё делать компилятору, когда возникает такая неоднозначность? Просто обругать и выкинуть ошибку? А если так задумано, что CONST_x могут принимать различные значения? И не добавит ли нам ещё больше головной боли такая "вольность", чем простая "switch-board" по одному константному значению?

За что боремся-то? Не понимаю...
Re[4]: семантика switch/case
От: AlexRK  
Дата: 30.12.15 19:14
Оценка:
Здравствуйте, ononim, Вы писали:

ARK>>Вот не понимаю, почему нельзя было сделать так, без этих break-костылей (разумеется, это не валидная программа на C):

O>Потому что вот этот вот код будет более громоздко выглядеть
Автор: ononim
Дата: 17.12.15


Этот код плох и провоцирует ошибки при модификации, его необходимо переписать на функциях.

O>Поймите, break — это абстракция более высокого уровня


Да, я действительно не понимаю, почему goto, добавленный в оператор выбора, делает его абстракцией более высокого уровня. Ну и потребности в такой абстракции (если ее можно так назвать) я пока не вижу. Примеры типа приведенного выше иллюстрируют, по моему скромному мнению, скорее вред этой "высокоуровневой абстракции".
Re[5]: семантика switch/case
От: ononim  
Дата: 30.12.15 19:34
Оценка:
ARK>>>Вот не понимаю, почему нельзя было сделать так, без этих break-костылей (разумеется, это не валидная программа на C):
O>>Потому что вот этот вот код будет более громоздко выглядеть
Автор: ononim
Дата: 17.12.15

ARK>Этот код плох и провоцирует ошибки при модификации, его необходимо переписать на функциях.
Это при модификации теми, кто привык к pascal-style switch'у. Ну так привыкли — и оставайтесь на нем, незачем ходить гулять в С-лес, ведь известно что там обезъяны, кашалоты ииии зеленый попугай

O>>Поймите, break — это абстракция более высокого уровня

ARK> Да, я действительно не понимаю, почему goto, добавленный в оператор выбора, делает его абстракцией более высокого уровня. Ну и потребности в такой абстракции (если ее можно так назвать) я пока не вижу. Примеры типа приведенного выше иллюстрируют, по моему скромному мнению, скорее вред этой "высокоуровневой абстракции".
Потому что goto, работающий сключительно сверху вниз не так уж и плох. Вот если бы можно было сделать так (надо сказать я в свое время был удивлен и немного подавлен от того что так делать нельзя, ну да ладно, идеальной симметрии в этом мире не найти):
switch (v)
{
case 1:
foo1();
break;

case 2:
foo2();
break;

case 3:
foo3();
goto case 1: //hehehe
}

Вот тогда это был бы "плохой" goto. А учитывая навязанный порядок исполнения сверху вниз — эти goto ничуть не хуже чем goto реализованные скажем обычным вашим "высокоурвневым" (без-break-ововым) switch'ем, код в кейсах которого склонен кидаться исключениями (чуть менее чем любой продакшен код). Ну так брейки хоть видно то сразу..
Как много веселых ребят, и все делают велосипед...
Отредактировано 30.12.2015 19:36 ononim . Предыдущая версия .
Re[6]: семантика switch/case
От: AlexRK  
Дата: 30.12.15 20:11
Оценка: +1
Здравствуйте, ononim, Вы писали:

O>Потому что goto, работающий сключительно сверху вниз не так уж и плох. Вот если бы можно было сделать так (надо сказать я в свое время был удивлен и немного подавлен от того что так делать нельзя, ну да ладно, идеальной симметрии в этом мире не найти):


Кстати да, это мне тоже непонятно. Какой смысл защищать ущербный гото (полноценный еще ладно бы). Вот вы реализуете алгоритм на проваливаниях в свитче, а что будете делать, если при модификации существующего кода в одном месте возникнет потребность скакнуть слегка не туда, куда дозволено? (К примеру, с OVERWRITE надо будет сразу идти в POSTPONE.) Вся прекрасная высокоуровневоабстрактная картина развалится и переходим к старым добрым паскалевым кейсам и функциям?
Re[7]: семантика switch/case
От: ononim  
Дата: 30.12.15 20:19
Оценка:
O>>Потому что goto, работающий сключительно сверху вниз не так уж и плох. Вот если бы можно было сделать так (надо сказать я в свое время был удивлен и немного подавлен от того что так делать нельзя, ну да ладно, идеальной симметрии в этом мире не найти):
ARK>Кстати да, это мне тоже непонятно. Какой смысл защищать ущербный гото (полноценный еще ладно бы). Вот вы реализуете алгоритм на проваливаниях в свитче, а что будете делать, если при модификации существующего кода в одном месте возникнет потребность скакнуть слегка не туда, куда дозволено? (К примеру, с OVERWRITE надо будет сразу идти в POSTPONE.) Вся прекрасная высокоуровневоабстрактная картина развалится и переходим к старым добрым паскалевым кейсам и функциям?
Да, нет в жизни счастья. Паскаль-стайл свич — это набор кирпичиков, сишный — это кусок глины. Глины, а не кваркового супа, которым является асм Кому что нравится — тот там и пасется.
Как много веселых ребят, и все делают велосипед...
Re[7]: семантика switch/case
От: enji  
Дата: 08.01.16 08:24
Оценка:
Здравствуйте, Sheridan, Вы писали:


S>На самом деле руки чешутся чтото вот такое пописать, но задач таких нет. А чешется не так сильно, чтобы придумывать себе задачу и закупаться оборудованием


купи ардуинку, там 32к ПЗУ и 2 по моему ОЗУ Цена вопроса на алиэкспресс ~400 р
Re[8]: семантика switch/case
От: Sheridan Россия  
Дата: 08.01.16 09:21
Оценка:
Здравствуйте, enji, Вы писали:

S>>На самом деле руки чешутся чтото вот такое пописать, но задач таких нет. А чешется не так сильно, чтобы придумывать себе задачу и закупаться оборудованием

E>купи ардуинку, там 32к ПЗУ и 2 по моему ОЗУ Цена вопроса на алиэкспресс ~400 р
А обвязка? Ну, БП, интерфейсы. К компу надо ж подключить....
Matrix has you...
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.