Метки, оператор goto и оператор switch в Си

Поділитися
Вставка
  • Опубліковано 12 січ 2025

КОМЕНТАРІ • 55

  • @vasiliysokolov7045
    @vasiliysokolov7045 6 років тому +68

    В защиту оператора switch можно сказать следующее:
    1. Хотя в Си, switch действительно работает только с целочисленными переменными, в других более высокоуровневых языках в switch можно передавать практически все что угодно, включая вещественные числа, перечисления и даже строки. Т.е. это ограничение не столько оператора switch сколько конкретного языка программирования, в данном случае Си.
    2. Выбор через switch не запутывает код, а скорее наоборот, делает его нагляднее. Потому что switch это все-таки "плоский" оператор выбора: возможные значения записываются в столбик что позволяет очень быстро понять, какие варианты выбора существуют и как обрабатываются.
    3. В видео прослеживается мысль, что switch использует goto, а goto это плохо. Но for, while и break - это тоже по сути обертки для goto. Т.е. в том, что "за кулисами" используется goto нет ничего плохого.
    4. switch позволяет организовать быстрый переход. Вычислить адрес прыжка по содержимому switch. А вот if-elseif этого сделать не позволяет. Т.е. если нужно выбрать один из 100 вариантов выбора, switch не будет перебирать все предшествующие нужной метки case, а перепрыгнет в нее сразу. Этого у if-elseif нет.
    5. В реальных задачах функции имеют одни и теже проблемы, не зависимо от того, используют они switch или if-ifelse. Каждый вариант обрабатывают множество строк кода, когда вариантов несколько эти функции растут как на дрожжах. Помогает написание отдельных функций обрабатыващих строго конкретный случай, ну и этого порой оказывается не достаточно. Есть более нетривиальные решения противодействующие разрастанию кода, но они уже не зависят ни от if-ifelse ни от switch. Т.е. на определенном уровне использование только if-ifelse или только switch каких-либо преимуществ не дает.

    • @23foundation
      @23foundation 5 років тому +11

      Да все норм со свитчем на самом деле. Главное не забывать про брейк и дефолт! Работать с перечислениями крайне удобно. IDE предупредит, если какое-либо из перечислений не упомянуто в выборе. Да и точка с запятой в самом конце оператора вовсе не обязательна...

    • @shanewalsch
      @shanewalsch Рік тому

      Switch ещё и намного быстрее чем if else

  • @UFO26
    @UFO26 5 років тому +47

    позвольте позвольте, Тимофей, за урок всё равно лайк, но...
    При выполнении свича, процессор вычисляет (достаёт из памяти) переменную икс в скобках switch (x) один раз,
    а далее делает варп прыжок к нужному варианту как в стартреке.
    А каскадный IF - как импульсный двигатель. Перебирает каждый вариант и в каждом вложенном IF вычисляет икс заново.
    Каждый фанат стартрека знает, что варп быстрее импульса.

    • @cp0tyr
      @cp0tyr 3 місяці тому +1

      сравнение супер 😂

  • @splr11
    @splr11 5 років тому +16

    Для оператора goto есть вполне четкие правила корректного использования. В университетах этому почему-то не учат. Однако в реальных проектах, причем крайне серьёзных, goto таки широко используется.

    • @shanewalsch
      @shanewalsch Рік тому

      ​@@serjoberst6322выход из вписанного цикла

  • @ЮрийКулаков-й5с
    @ЮрийКулаков-й5с 6 років тому +7

    Тимофей, вы умница. Вы мой виртуальный сенсей..

  • @Kokurorokuko
    @Kokurorokuko 2 роки тому +3

    У меня была задача на определение кол-ва гласных букв в словах. Через switch она очень элегантно решалась, без дополнительных библиотек. Я просто выбирал в слове char x и делал switch (x), а далее так:
    case 'a': case 'o': case 'u': case 'e': case 'i':
    ...
    break;
    default:
    ...
    break;
    Тогда я не знал, что можно кейсы писать через запятую, но сути это не меняет. На это намного проще смотреть, чем на 5 if'ов и потом else.

  • @AxGxP
    @AxGxP 5 років тому +9

    При дизассемблировании прошивок не раз натыкался на конструкции вида(условно) "jmp x+n", а по адресу "x" находятся целые простыни "jmp". Подозреваю, что это компилятор какой-то "switch-case" умеет в такое дело собирать, я прав? Тогда с точки зрения быстродействия и размера кода, ничего круче switch не придумаешь! Всего три безусловных перехода, вместо горы сравнений и прыжков, на большинстве из которых придется ещё и из памяти подгружать значения в регистры. Не пойму, чем не угодил SWITCH? P.S. вопрос не риторический, жду ответа...

  • @AV1ch
    @AV1ch 3 роки тому +7

    Примеры реального использования "goto" из практики (не профессионал, пишу для себя):
    1. Из ветки "if" прыгнуть в ветку "else". Понадобилось при обработке кодовой страницы Турецкого алфавита, где знак "I" в строчный переводится по-особому, а все остальные совпадают с латиницей (ASCII).
    2. Если где-то нужен повтор действий при строго определённых условиях, а по логике цикл не подходит и вообще не думаешь про данную задачу как про цикл.
    И ещё, метку можно писать вполне читаемо:
    ....
    код
    код
    метка:
    код
    код
    код
    ...
    Так что да, таки этот оператор ещё переживёт всех.

  • @Andy111182
    @Andy111182 4 роки тому +13

    Как вы любите нелепо искажать простой код с помощью операторов goto, а потом рассказывать: "смотрите как это усложняет код! нельзя так делать". Конечно, нельзя так делать!
    Показали бы пример элегантного решения, когда у вас есть три (или более) вложенных циклов, и вам нужно выходить из наиболее вложенного цикла на -1, -2 или -3 в зависимости от значения некоторых переменных. Решения без goto получаются настолько путанные и сложные, что использование goto будет выглядеть как статуя свободы.

  • @380307
    @380307 6 років тому +8

    Пишите с толком, аккуратней
    Чем больше goto тем приятней...

  • @travelerbetweenstrings8089
    @travelerbetweenstrings8089 4 роки тому

    Да, были сложности с метками и с блоками switch, плевался этой не понятке, теперь понятно почему! СПАСИБО!

  • @alxlavr
    @alxlavr 11 місяців тому

    Спасибо за Вашу работу. Могу от себя добавить, что я switch прекрасно использую с перечислениями enum. Например, при обработке ошибок или каких либо автоматов и приходящих с портов связи символов. Иногда даже при правильной конфигурации кода можно обходиться без break и исполнять сразу две "метки" при необходимости. Хотя в некоторых случаях и if else также обрабатывается очень гибко - можно на ходу изменить условие и попасть в нужную точку кода за один проход цикла. Всё зависит от необходимости. Про goto даже не вспоминаю.

  • @NoName-di1ug
    @NoName-di1ug 4 роки тому +1

    Очень надеюсь, вы будете выкладывать все свои лекции.

  • @izzzanaaami
    @izzzanaaami 2 роки тому

    Смотрел это видео 4 месяца назад, но вернулся опять, потому что сейчас читаю книгу "чистая архитектура" и там он упоминает в структурном программирование Дейкстру. А в моем подсознании где-то осталось воспоминание про то, как Тимофей Кирьянов тоже ругает go to

  • @АлинаЛебедева-с4ъ
    @АлинаЛебедева-с4ъ 5 років тому +10

    Во-первых, то, что Си в switch умеет сравнивать числа - это проблема Си, а не switch.
    Во-вторых, не стоит забывать, что char - это целочисленный тип, и этот факт позволил мне очень просто и удобно сделать лексер. Да и в принципе для программ, обрабатывающих строки, конструкция со switch черезвычайно удобно
    В третьих, конструкция if-else-if не может похвастаться возможностью уйти из блока кода без дополнительных меток. Например, при написании лексера часто возникали ситуации, когда break используется не только в самом конце "блока кода". Бывало такое, что в некоторых случаях когда сработало какое-то условие, нужно выйти из блока switch, а через if-else-if пришлось бы пользоваться метками.
    В четвёртых, ты хейтишь switch за то, что он неявно использует goto. Но ведь и if, и while, и особенно for тоже используют для своей работы goto. Ненавидеть их что ли?
    В пятых, goto позволяет программисту сразу видеть, что идёт сравнение какого-то одного числа(символа).
    В шестых, можно воспользоваться такой конструкцией
    case 1:
    case 2:
    case 3:
    /*code*/
    break;
    Через if это можно реализовать так:
    if (x == 1 || x == 2 || x == 3)
    А если переменная называется не 'х', а это какой-то член структуры? Три раза писать какое-то длинное название чисто чтобы сравнить одно число с тремя разными значениями? И ты ещё называешь switch не читаемым? Питонисты жалуются, что нет такой удобной и читаемой конструкции, а ты просто из-за факта работы через goto взял и выкинул это всё в помойку.
    В седьмых, switch работает быстрее. Конечно он не позволяет сравнивать строки, так что большой блок switch не сильно отличается от использования длинной конструкции if-else-if, но в циклах в требовательных программах это может оказаться приятным бонусом к скорости

    • @w.t.2905
      @w.t.2905 4 роки тому

      Насчёт switch case в Python - можно использовать словари. Так что было бы желание, а способ есть.

    • @programer8
      @programer8 4 роки тому

      @@w.t.2905 switch нет в питоне?

    • @w.t.2905
      @w.t.2905 4 роки тому

      @@programer8 в классическом понимании нет

  • @ilyaantipov1620
    @ilyaantipov1620 5 років тому +2

    9:24 а почему ; обязательна после закрывающей } в switch ?

  • @SolderingIronMen
    @SolderingIronMen Рік тому +1

    Спасибо за видео, но Вы абсолютно не отбили желание использовать оператор switch. Считаю, что он выглядит намного элегантнее каскадного if-else.
    Кроме того, отмечу пару ошибок в видео. 1. Точка с запятой не обязательна после закрывающей скобки switch. 2. После ключевого слова case нельзя пересислять варианты через запятую.

  • @avr_stm_pro2955
    @avr_stm_pro2955 5 років тому +1

    Спасибо дружище за работу!!!

  • @Piter_Pain
    @Piter_Pain 6 років тому +4

    Великолепно! Стивен Прата нервно курит в уголке.

  • @СергейЧатов
    @СергейЧатов 3 роки тому +4

    При всём уважении , но данный ролик с самого начала и до самого конца ,начинающих "специалистов" вводит в заблуждение. Как говорится делай всё так , как говорю , только наоборот. Что goto , что swith облегчают в разы написание программы.

  • @ГлебРостов
    @ГлебРостов Рік тому

    Можно писать if{} else if{} else if{} else{}. Но есть проблема. В отличие от питона и баша здесь нет одного слова elif, здесь именно два идущих друг за другом else if. И есть компилятор, который очень любит оптимизировать код. Достаточно часто я хочу сделать if {if{}else{}}else{if{}else{}}. Т.е. в зависимости от двух переменных выбрать один из 4 путей. И обычно это работает. Но в редких случаях нет. Каким-то боком при правильном количестве и порядке скобок одна из 4 веток кода становится недостижимой при исполнении. Я просто беру эти два bool, один из них умножаю на 2, складываю их. И дальше через switch выбираю нужный вариант. Это работает всегда. Главное не забудь ставить break и один из вариантов выбрать в качестве default

    • @SalatikInMyHead
      @SalatikInMyHead 3 місяці тому

      пересмотри урок про логические операции и используй AND 🤦🤦🤦

  • @ИванВоронин-и2м
    @ИванВоронин-и2м 5 років тому +7

    Дейкстра писал совсем о другом!
    Дейкстра против goto в "фортранном" стиле, против "макаронного" кода.
    Как без goto сделать выход из вложенных циклов в НУЖНОЕ! место?
    Только не надо пихать в меня (декомпозировать) методы и ф-ии.

  • @zvalmontz
    @zvalmontz 4 роки тому +2

    по switch не согласен, удобная вещь в некоторых моментах. Switch работает с отдельными символами массива типа char.

  • @СергейПресняков-о4р
    @СергейПресняков-о4р 5 років тому +2

    Эдсгер Дейкстра "Аргументы против goto" Том 1

  • @spolyr
    @spolyr 3 роки тому

    я конечно только начал изучать си, после ассемблера.
    Там без "jmp" разного вида и "cmp" никак, тем более если взять дос, то максимум между командами перехода и меткой 128 байт,
    вот веселье когда нужно больше приходится писать дополнительный блок для прыгания).
    Про Си :
    Правда мне кажется если в языке есть что то значит его можно использовать, и каждый програмист сам волен придумывать свой алгоритм программы.
    Дело в том что вероятно алгортим он видел таким а другой видел это решение по другому, главное чтоб работало как задуманно, и все.

  • @O_Hat
    @O_Hat 3 роки тому

    На доске ситуация, где кружочек и ниже кружочек, там циклы как-то петляют. Как на счет рекурсии?

  • @fish9370
    @fish9370 5 років тому +12

    Честно говоря говорить такое про goto это верх некомпитентности. Сразу видно теоретика. Откройте любой реальный проект на C. Такой как: Ядро Линукс, asterisk, apache, ngingx, да тот же ваш любимый pyton и так далее - любой. И ужаснитесь - в них тонны goto.
    Привожу реальный пример:
    static int load_module(void)
    {
    parking_lot_container = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_MUTEX,
    AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT,
    parking_lot_sort_fn,
    NULL);
    if (!parking_lot_container) {
    goto error;
    }
    if (aco_info_init(&cfg_info)) {
    goto error;
    }
    ... много много кода
    error:
    unload_module();
    return AST_MODULE_LOAD_DECLINE;
    }
    Если вы не сделаете goto, вы не сможете корректно освободить память, выгрузить модуль (как в приведенном примере). Без goto, вам бы пришлось дублировать много кода. Поверьте, goto еще всех нас переживет. Привет Эдгеру Дейкстре, и профессору - за их невежество. Ставлю Дизлайк

    • @fish9370
      @fish9370 5 років тому +2

      P.S. В исходниках Python 3.7.3 я насчитал 4729 goto!

    • @vfxenthusiast1244
      @vfxenthusiast1244 5 років тому +2

      Умник тебе ли говорить о "некомпетентности"

    • @ЯнаХазина
      @ЯнаХазина Рік тому

      в где-то прочитанной книжке была приведена статистика, что в весьма уважаемом коде ОС линукс goto встречается в среднем в каждой 83 или 85 строке.
      а лектор слегка пижонит. Молодой еще.

  • @adminroot1345
    @adminroot1345 3 роки тому +1

    Никогда не говори никогда.

  • @robbarret9568
    @robbarret9568 3 роки тому

    Что-то я не понял по ; в самом конце оператора switch

  • @yonyonson6986
    @yonyonson6986 Рік тому

    Лайк за видео, но с содержимым я не согласен!

  • @ИванКрасноярский-е3я
    @ИванКрасноярский-е3я 10 місяців тому

    точка с запятой после фигурных скобок не обязательна

  • @korvet348
    @korvet348 4 роки тому

    Итальянские программисты шутят -
    Я приду к тебе домой и сначала переломаю все твои спагетти, а потом перепишу все циклы через go to.

  • @ZedusUA
    @ZedusUA 3 роки тому +1

    Абсолютно не согласен с кейсом свича (звучит, однако:)). ну и с гоу ту далеко не 2 варианта его условного использования без "криминала". благо, это пока единственные 2 момента, с которыми я не согласен за 10 видео.
    спасибо за труды

  • @AlexanderLetetski
    @AlexanderLetetski Рік тому

    goto рудимент оставшийся с тех времен

  • @sorinrusu5311
    @sorinrusu5311 5 років тому +1

    Как-то сложилось что я С и С++ пропустил и считал это своим недочетом. Благодоря вашим урокам я понял что он мне вовсе и не нужен. Геморойный он. Для утилит мне вполне подходит Crystal (компилирумый Ruby). А если когда либо и понадобится программа с ручным управлением памяти, то лучше сразу Rust использовать. Да и для Web разработки (мой профиль) лучше пока оставаться на интерпретируемых ЯП.

    • @borislapikov3070
      @borislapikov3070 5 років тому +3

      Вот потому и говорят, что интерпертатор, Руст, Кристал для быдлокодеров.

    • @DiamondSane
      @DiamondSane 5 років тому +4

      @@serjoberst6322 нет, не пришло. Народ будет хавать и покупать 16ядерные процессоры и кучу плашек оперативной памяти. И будут статусность игры оценивать по тому насколько много она жрёт ресурсов.

  • @Kirik516
    @Kirik516 2 роки тому

    Не, Свитч отличная тема. Зря так хают его. Энумчики перебирать самое то.

  • @syrengoogle
    @syrengoogle Рік тому

    не хочу вас разочаровывать, но вы слишком много лишней работы сделали с goto, поэтому ваш код такой ужасный и нечитабельный
    вот как он должен выглядеть на самом деле. И там всего две метки)))
    int main ()
    { int x;
    A: scanf("%d", &x);
    if (x==0) goto B;
    if(x%2==0)
    {
    printf(" число четное
    ");
    gotoA;
    }
    printf(" число нечетное
    ");
    gotoA;
    B:
    return 0;
    }

  • @ostrov11
    @ostrov11 4 роки тому

    Так цикл и ветвления это и есть goto

  • @sergeystal15
    @sergeystal15 5 років тому

    все круто кроме посыла о языке

  • @isorport32
    @isorport32 2 роки тому

    А ничего, что любой оператор ветвления это тоже переход по меткам? Никогда не понимал этих анти готистов и анти свичистов, ну не нравится, не пользуйся (тем более если не умеешь))

  • @jeckkaban
    @jeckkaban Рік тому

    go to go to go to

  • @amurlamur3125
    @amurlamur3125 6 років тому +2

    Ну блин, хвостик(