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

  Рет қаралды 32,303

Тимофей Хирьянов

Тимофей Хирьянов

5 жыл бұрын

Оператор goto и прыжки на метки.
Аргументы против goto.
Блок-схема, которую нельзя сделать на циклах.
Ветвление switch и почему нужен break.

Пікірлер: 53
@UFO26
@UFO26 4 жыл бұрын
позвольте позвольте, Тимофей, за урок всё равно лайк, но... При выполнении свича, процессор вычисляет (достаёт из памяти) переменную икс в скобках switch (x) один раз, а далее делает варп прыжок к нужному варианту как в стартреке. А каскадный IF - как импульсный двигатель. Перебирает каждый вариант и в каждом вложенном IF вычисляет икс заново. Каждый фанат стартрека знает, что варп быстрее импульса.
@vasiliysokolov7045
@vasiliysokolov7045 5 жыл бұрын
В защиту оператора 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 жыл бұрын
Да все норм со свитчем на самом деле. Главное не забывать про брейк и дефолт! Работать с перечислениями крайне удобно. IDE предупредит, если какое-либо из перечислений не упомянуто в выборе. Да и точка с запятой в самом конце оператора вовсе не обязательна...
@shanewalsch
@shanewalsch 7 ай бұрын
Switch ещё и намного быстрее чем if else
@user-nw2vi8bf7b
@user-nw2vi8bf7b 5 жыл бұрын
Тимофей, вы умница. Вы мой виртуальный сенсей..
@splr11
@splr11 5 жыл бұрын
Для оператора goto есть вполне четкие правила корректного использования. В университетах этому почему-то не учат. Однако в реальных проектах, причем крайне серьёзных, goto таки широко используется.
@shanewalsch
@shanewalsch 7 ай бұрын
​@@serjoberst6322выход из вписанного цикла
@alxlavr
@alxlavr 5 ай бұрын
Спасибо за Вашу работу. Могу от себя добавить, что я switch прекрасно использую с перечислениями enum. Например, при обработке ошибок или каких либо автоматов и приходящих с портов связи символов. Иногда даже при правильной конфигурации кода можно обходиться без break и исполнять сразу две "метки" при необходимости. Хотя в некоторых случаях и if else также обрабатывается очень гибко - можно на ходу изменить условие и попасть в нужную точку кода за один проход цикла. Всё зависит от необходимости. Про goto даже не вспоминаю.
@AxGxP
@AxGxP 4 жыл бұрын
При дизассемблировании прошивок не раз натыкался на конструкции вида(условно) "jmp x+n", а по адресу "x" находятся целые простыни "jmp". Подозреваю, что это компилятор какой-то "switch-case" умеет в такое дело собирать, я прав? Тогда с точки зрения быстродействия и размера кода, ничего круче switch не придумаешь! Всего три безусловных перехода, вместо горы сравнений и прыжков, на большинстве из которых придется ещё и из памяти подгружать значения в регистры. Не пойму, чем не угодил SWITCH? P.S. вопрос не риторический, жду ответа...
@Kokurorokuko
@Kokurorokuko 2 жыл бұрын
У меня была задача на определение кол-ва гласных букв в словах. Через switch она очень элегантно решалась, без дополнительных библиотек. Я просто выбирал в слове char x и делал switch (x), а далее так: case 'a': case 'o': case 'u': case 'e': case 'i': ... break; default: ... break; Тогда я не знал, что можно кейсы писать через запятую, но сути это не меняет. На это намного проще смотреть, чем на 5 if'ов и потом else.
@avr_stm_pro2955
@avr_stm_pro2955 4 жыл бұрын
Спасибо дружище за работу!!!
@travelerbetweenstrings8089
@travelerbetweenstrings8089 4 жыл бұрын
Да, были сложности с метками и с блоками switch, плевался этой не понятке, теперь понятно почему! СПАСИБО!
@AV1ch
@AV1ch 2 жыл бұрын
Примеры реального использования "goto" из практики (не профессионал, пишу для себя): 1. Из ветки "if" прыгнуть в ветку "else". Понадобилось при обработке кодовой страницы Турецкого алфавита, где знак "I" в строчный переводится по-особому, а все остальные совпадают с латиницей (ASCII). 2. Если где-то нужен повтор действий при строго определённых условиях, а по логике цикл не подходит и вообще не думаешь про данную задачу как про цикл. И ещё, метку можно писать вполне читаемо: .... код код метка: код код код ... Так что да, таки этот оператор ещё переживёт всех.
@Andy111182
@Andy111182 4 жыл бұрын
Как вы любите нелепо искажать простой код с помощью операторов goto, а потом рассказывать: "смотрите как это усложняет код! нельзя так делать". Конечно, нельзя так делать! Показали бы пример элегантного решения, когда у вас есть три (или более) вложенных циклов, и вам нужно выходить из наиболее вложенного цикла на -1, -2 или -3 в зависимости от значения некоторых переменных. Решения без goto получаются настолько путанные и сложные, что использование goto будет выглядеть как статуя свободы.
@NoName-di1ug
@NoName-di1ug 4 жыл бұрын
Очень надеюсь, вы будете выкладывать все свои лекции.
@380307
@380307 5 жыл бұрын
Пишите с толком, аккуратней Чем больше goto тем приятней...
@SolderingIronMen
@SolderingIronMen 11 ай бұрын
Спасибо за видео, но Вы абсолютно не отбили желание использовать оператор switch. Считаю, что он выглядит намного элегантнее каскадного if-else. Кроме того, отмечу пару ошибок в видео. 1. Точка с запятой не обязательна после закрывающей скобки switch. 2. После ключевого слова case нельзя пересислять варианты через запятую.
@user-sv2gm3vk6k
@user-sv2gm3vk6k 4 жыл бұрын
Во-первых, то, что Си в 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 3 жыл бұрын
@@w.t.2905 switch нет в питоне?
@w.t.2905
@w.t.2905 3 жыл бұрын
@@programer8 в классическом понимании нет
@Piter_Pain
@Piter_Pain 5 жыл бұрын
Великолепно! Стивен Прата нервно курит в уголке.
@izzzanaaami
@izzzanaaami 2 жыл бұрын
Смотрел это видео 4 месяца назад, но вернулся опять, потому что сейчас читаю книгу "чистая архитектура" и там он упоминает в структурном программирование Дейкстру. А в моем подсознании где-то осталось воспоминание про то, как Тимофей Кирьянов тоже ругает go to
@user-yg8yp8kx5e
@user-yg8yp8kx5e Жыл бұрын
Можно писать if{} else if{} else if{} else{}. Но есть проблема. В отличие от питона и баша здесь нет одного слова elif, здесь именно два идущих друг за другом else if. И есть компилятор, который очень любит оптимизировать код. Достаточно часто я хочу сделать if {if{}else{}}else{if{}else{}}. Т.е. в зависимости от двух переменных выбрать один из 4 путей. И обычно это работает. Но в редких случаях нет. Каким-то боком при правильном количестве и порядке скобок одна из 4 веток кода становится недостижимой при исполнении. Я просто беру эти два bool, один из них умножаю на 2, складываю их. И дальше через switch выбираю нужный вариант. Это работает всегда. Главное не забудь ставить break и один из вариантов выбрать в качестве default
@zvalmontz
@zvalmontz 3 жыл бұрын
по switch не согласен, удобная вещь в некоторых моментах. Switch работает с отдельными символами массива типа char.
@user-er6zr1tm3i
@user-er6zr1tm3i 4 жыл бұрын
Дейкстра писал совсем о другом! Дейкстра против goto в "фортранном" стиле, против "макаронного" кода. Как без goto сделать выход из вложенных циклов в НУЖНОЕ! место? Только не надо пихать в меня (декомпозировать) методы и ф-ии.
@spolyr
@spolyr 2 жыл бұрын
я конечно только начал изучать си, после ассемблера. Там без "jmp" разного вида и "cmp" никак, тем более если взять дос, то максимум между командами перехода и меткой 128 байт, вот веселье когда нужно больше приходится писать дополнительный блок для прыгания). Про Си : Правда мне кажется если в языке есть что то значит его можно использовать, и каждый програмист сам волен придумывать свой алгоритм программы. Дело в том что вероятно алгортим он видел таким а другой видел это решение по другому, главное чтоб работало как задуманно, и все.
@ilyaantipov1620
@ilyaantipov1620 5 жыл бұрын
9:24 а почему ; обязательна после закрывающей } в switch ?
@sorinrusu5311
@sorinrusu5311 5 жыл бұрын
Как-то сложилось что я С и С++ пропустил и считал это своим недочетом. Благодоря вашим урокам я понял что он мне вовсе и не нужен. Геморойный он. Для утилит мне вполне подходит Crystal (компилирумый Ruby). А если когда либо и понадобится программа с ручным управлением памяти, то лучше сразу Rust использовать. Да и для Web разработки (мой профиль) лучше пока оставаться на интерпретируемых ЯП.
@borislapikov3070
@borislapikov3070 4 жыл бұрын
Вот потому и говорят, что интерпертатор, Руст, Кристал для быдлокодеров.
@DiamondSane
@DiamondSane 4 жыл бұрын
@@serjoberst6322 нет, не пришло. Народ будет хавать и покупать 16ядерные процессоры и кучу плашек оперативной памяти. И будут статусность игры оценивать по тому насколько много она жрёт ресурсов.
@user-dv9fk1hd3s
@user-dv9fk1hd3s 4 жыл бұрын
Эдсгер Дейкстра "Аргументы против goto" Том 1
@yonyonson6986
@yonyonson6986 9 ай бұрын
Лайк за видео, но с содержимым я не согласен!
@O_Hat
@O_Hat 2 жыл бұрын
На доске ситуация, где кружочек и ниже кружочек, там циклы как-то петляют. Как на счет рекурсии?
@ZedusUA
@ZedusUA 2 жыл бұрын
Абсолютно не согласен с кейсом свича (звучит, однако:)). ну и с гоу ту далеко не 2 варианта его условного использования без "криминала". благо, это пока единственные 2 момента, с которыми я не согласен за 10 видео. спасибо за труды
@adminroot1345
@adminroot1345 3 жыл бұрын
Никогда не говори никогда.
@user-br7vc8nc2x
@user-br7vc8nc2x 2 жыл бұрын
При всём уважении , но данный ролик с самого начала и до самого конца ,начинающих "специалистов" вводит в заблуждение. Как говорится делай всё так , как говорю , только наоборот. Что goto , что swith облегчают в разы написание программы.
@user-kw6sb1rt5b
@user-kw6sb1rt5b Жыл бұрын
goto рудимент оставшийся с тех времен
@user-ms3id7jv7v
@user-ms3id7jv7v 4 ай бұрын
точка с запятой после фигурных скобок не обязательна
@Kirik516
@Kirik516 Жыл бұрын
Не, Свитч отличная тема. Зря так хают его. Энумчики перебирать самое то.
@fish9370
@fish9370 5 жыл бұрын
Честно говоря говорить такое про 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 жыл бұрын
P.S. В исходниках Python 3.7.3 я насчитал 4729 goto!
@vfxenthusiast1244
@vfxenthusiast1244 5 жыл бұрын
Умник тебе ли говорить о "некомпетентности"
@user-mg8ie2px7s
@user-mg8ie2px7s Жыл бұрын
в где-то прочитанной книжке была приведена статистика, что в весьма уважаемом коде ОС линукс goto встречается в среднем в каждой 83 или 85 строке. а лектор слегка пижонит. Молодой еще.
@robbarret9568
@robbarret9568 2 жыл бұрын
Что-то я не понял по ; в самом конце оператора switch
@korvet348
@korvet348 3 жыл бұрын
Итальянские программисты шутят - Я приду к тебе домой и сначала переломаю все твои спагетти, а потом перепишу все циклы через go to.
@sergeystal15
@sergeystal15 4 жыл бұрын
все круто кроме посыла о языке
@ostrov11
@ostrov11 4 жыл бұрын
Так цикл и ветвления это и есть goto
@jeckkaban
@jeckkaban 7 ай бұрын
go to go to go to
@isorport32
@isorport32 Жыл бұрын
А ничего, что любой оператор ветвления это тоже переход по меткам? Никогда не понимал этих анти готистов и анти свичистов, ну не нравится, не пользуйся (тем более если не умеешь))
@amurlamur3125
@amurlamur3125 5 жыл бұрын
Ну блин, хвостик(
@Roman-bp1cu
@Roman-bp1cu 4 жыл бұрын
Amur Lamur и че?
@syrengoogle
@syrengoogle 9 ай бұрын
не хочу вас разочаровывать, но вы слишком много лишней работы сделали с 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; }
Управление циклом в Си: break, continue
15:25
Тимофей Хирьянов
Рет қаралды 34 М.
Техника безопасности при работе с памятью в Си
19:25
Тимофей Хирьянов
Рет қаралды 34 М.
THEY made a RAINBOW M&M 🤩😳 LeoNata family #shorts
00:49
LeoNata Family
Рет қаралды 12 МЛН
THEY WANTED TO TAKE ALL HIS GOODIES 🍫🥤🍟😂
00:17
OKUNJATA
Рет қаралды 14 МЛН
МАМА И STANDOFF 2 😳 !FAKE GUN! #shorts
00:34
INNA SERG
Рет қаралды 4,3 МЛН
Оператор if и организация ветвления в Си
15:00
Тимофей Хирьянов
Рет қаралды 41 М.
Зачем нужны указатели в C++?
8:14
Dima
Рет қаралды 1,9 М.
Функции в языке Си
27:17
Тимофей Хирьянов
Рет қаралды 44 М.
Адреса и указатели в Си. Адресная арифметика
27:47
Тимофей Хирьянов
Рет қаралды 160 М.
Ошибки и предупреждения при компиляции на Си
18:15
Тимофей Хирьянов
Рет қаралды 93 М.
Добро пожаловать в C++
16:08
Winderton
Рет қаралды 449 М.
why is it illegal to use "goto"?
5:23
Low Level Learning
Рет қаралды 244 М.
Двумерные массивы в Си: обычные и динамические
21:49
Тимофей Хирьянов
Рет қаралды 71 М.
Рекурсия. Репка и матрёшка
18:37
Тимофей Хирьянов
Рет қаралды 116 М.
THEY made a RAINBOW M&M 🤩😳 LeoNata family #shorts
00:49
LeoNata Family
Рет қаралды 12 МЛН