Хочу выразить Вам огромную благодарность за Вашу деятельность, это просто титанический труд! Я врач - невролог, год назад начал изучать питон ради одного научного проекта, теперь программирование для меня стало хобби, не могу остановиться учиться по Вашим видео, вот теперь добрался до Си. Очень меня улыбнуло имя функции per_rect(), не смог удержаться, чтоб не написать про это комментарий))
@РусланКарнеенко10 ай бұрын
Спасибо, Сергей. Как всегда на высоте!!!
@alexdubkov6998 Жыл бұрын
Супер! Огромное спасибо за курс!
@kolobroadgh8532 Жыл бұрын
Если кого-то заинтересовало как передать в функцию напрямую массив коллбеков то это выглядит так // Функция, принимающая массив указателей на функции и их количество void callFunctions(void (**functions)(), int count) { for (int i = 0; i < count; i++) { functions[i](); // Вызов функции по указателю } }
@КириллЧе-я5ы10 ай бұрын
Главное, не забыть потом эти указатели слить в правильном месте, шоб не утекли🥴
@jhonlauder273611 ай бұрын
Добрый день, уважаемы Сергей! Очень понятная подача материала, с максимальным сжатым объяснением. Профессиональная подача, видна учительская способность, отличная дикция. Сергей, прошу добавить тему или разобрать массив указателей функций и прокомментировать следующую задачу кода. Куда можно применить такой код и как часто он используется? Type in a code to call the functions pointed by the funcs array. Введите код для вызова функций, на которые указывает массив funcs. // suppose f1, f2, and f3 are declared void (*funcs[3])() = {f1, f2, f3}; for (int ix = 0; ix < _____ _____; ix++) { ______[ix](); } B вот пояснение. В сухом остатке. Массив указателей функций может заменять switch или оператор if для выбора действия, как в следующей программе: #include int add(int num1, int num2); int subtract(int num1, int num2); int multiply(int num1, int num2); int divide(int num1, int num2); int main() { int x, y, choice, result; int (*op[4])(int, int); op[0] = add; op[1] = subtract; op[2] = multiply; op[3] = divide; printf("Enter two integers: "); scanf("%d%d", &x, &y); printf("Enter 0 to add, 1 to subtract, 2 to multiply, or 3 to divide: "); scanf("%d", &choice); result = op[choice](x, y); printf("%d", result); return 0; } int add(int x, int y) { return(x + y); } Комментарий к коду. Оператор int (*op[4])(int, int); объявляет массив указателей функций. Каждый элемент массива должен иметь одинаковые параметры и тип возвращаемого значения. В этом случае функции, назначенные массиву, имеют два параметра int и возвращают int. Оператор result = op[choice](x, y); выполняет соответствующую функцию на основе выбора пользователя. Ранее введенные целые числа являются аргументами, передаваемыми в функцию. Запустите код и посмотрите, как он работает! Что тут значит - int (*op[4])(int, int); с точки зрения адресной арифметики? Заранее благодарен за пояснение.
@andredru427811 ай бұрын
Спасибо. Ого! похоже на декораторы. Крышесносно!
@catsaur5991 Жыл бұрын
Вот это прям оч круто, очень полезно. Спасибо)
@ДмитрийКузнецов-т6щ4 ай бұрын
Спасибо большое за науку! Тема указателей способна вызвать взрыв мозга, на первый взгляд и на второй тоже. Так и подмывает процитировать строки из книги Стивена Прата "Выразительность языка С в сочетании с богатством его операций делает возможным написание кода, который исключительно сложно понять. Конечно, вы отнюдь не обязаны писать неясный код, но такая возможность имеется. В конце концов, для какого еще языка устраивается ежегодный конкурс на самый запутанный код?"
@donfedor007 Жыл бұрын
Спасибо Вам! Очень круто!
@КириллЧе-я5ы10 ай бұрын
Колбеки - тема интересная. В плюсах неск способов их сотворить. И выбрать, что же лучше, весьма непростое дело🥴
@Ordinary_man20499 ай бұрын
Спасибо за уроки, Сергей! Не пойму, для чего при инициализации указателя на функцию пишем int *(ptr_name) в скобках имя указателя. Это для читабельности или без скобок никак не обойтись? Для чего они?
@selfedu_rus9 ай бұрын
это синтаксис такой, просто нужно запомнить
@olegkomlev3 ай бұрын
В int ☆(ptr_name) скобки не нужны, а вот для "int (☆ptr_name) (int,int)" скобки обязательны. Читать такие определения нужно с имени идентификатора, двигаясь вправо насколько это позволяют скобки. При встрече непарной скобки ) нужно двигаться влево до соответствующей открывающейся скобки, после чего опять идти вправо до конца или до непарной скобки ). В данном случае читаем в таком порядке: 9int 4( 3☆ 1ptr_name 2) 5( 6int, 7int 8) 1) "идентификатор ptr_name - это есть..." 2) При движении вправо встретили "2)", значит идем влево, 3) "где натыкаемся на "3☆" - признак указателя , поэтому говорим "...это есть указатель на...". 4) встретили скобку "4(", которая парная для "2)", поэтому продолжаем движение вправо 5) опять идем вправо по непрочитанному месту - там "5(", что означает функцию, поэтому "...указатель на функцию с параметрами" 6,7) "с параметрами целое и целое..." 8) список параметров кончился "8)", дальше ничего нет, поэтому возвращаемся влево 9) А там осталось "9int". Поэтому продолжаем "..., которая возвращает значение int" Итого для "int (☆ptr_name) (int,int)" получили " ptr_name - это указатель на функцию с двумя целыми параметрами, которая возвращает целое". А вот без скобок "int ☆ptr_name (int,int)" мы бы двигались вправо до конца, а только потом влево и "7int 6☆ 1ptr_name 2( 3int, 4int 5) " прочитали бы так " ptr_name - это функция с двумя целыми параметрами, которая возвращает указатель на целое". Added: заменил звездочку на пятиконечную, иначе воспринималось как жирный шрифт.
@Ordinary_man20493 ай бұрын
@@olegkomlev спасибо за такой развернутый ответ
@AlexRootx Жыл бұрын
Как обычно, зачетно!!! Лайк за работу!!! По идее, последние функции должны возвращать "bool"?
@selfedu_rus Жыл бұрын
В языке Си (равно, как и во многих других) можно возвращать не ноль для True и 0 - для False. Тем более, что в базовом Си как такового типа bool все равно нет.
@AlexRootx Жыл бұрын
@@selfedu_rus полностью согласен. Я имел ввиду, с точки зрения логики функций...
@selfedu_rus Жыл бұрын
@@AlexRootx без разницы ))
@МагомедИбрагимов-с8ъ Жыл бұрын
данный курс будет на степике?
@wonty331024 күн бұрын
@Gvinbleid Жыл бұрын
Извините, что не в тему, но есть ли у вас уроки по git?
@selfedu_rus Жыл бұрын
нет, этого не делал
@Gvinbleid Жыл бұрын
@@selfedu_rus Я думаю, это было бы многим полезно, одна из самых важных тем, как мне кажется. Я уже вроде бы немного разобрался, но думаю с вашим структурированным подходом к подаваемому материалу многим было бы намного проще въехать в эту тему. Еще один вопрос не по теме, если можно - является ли в питоне экземпляр класса хешируемым объектом, если у него не определен метод __hash__? Меня интересует возможность использовать экземпляр класса в качестве ключа словаря. Чатгпт говорит, что нет, он не является хешируемым без определения, и что его нельзя использовать в качестве ключа для словаря, но я пробовал использовать и вполне успешно, в том плане, что компилятор не ругается и я получаю по этому же экземпляру класса корректное значение из словаря. Также hasattr показывает, что у него есть __hash__, и также функция hash выводит хеш, но почему тогда чат говорит, что нельзя, может этот хеш у него меняется если он не определен, или еще что-то и поведение станет в какой-то момент некорректным? Или чат использует какую-то древнюю информацию и сейчас это изменилось, как например то, что словарь стал упорядоченной коллекцией, о чем чат также не знает, пока у него намеренно не спросишь об этом изменении. Не могли бы вы прояснить этот момент?
@selfedu_rus Жыл бұрын
@@Gvinbleid Спасибо! Экземпляры классов в Python можно использовать в качестве ключей, только метод hash() в них лучше переопределить. Подробнее, как все работает здесь proproprogs.ru/python_oop/magicheskie-metody-eq-hash
@weekendshow7567 Жыл бұрын
как можно получить доступ к 17 скрытым видео???
@selfedu_rus Жыл бұрын
они открываются постепенно
@weekendshow7567 Жыл бұрын
@@selfedu_rus спасибо
@sbs1993 Жыл бұрын
Извиняюсь если вы уже отвечали, но будет ли курс по Си на степике?
@selfedu_rus Жыл бұрын
пока не планирую
@Al-en6nj Жыл бұрын
я чуть не умер когда в книге увидел char (*(*x[3])())[5] - массив [3] указателей на функцию, возвращающую указатель на массив [5] типа char . Такое действительно используют в коде? как это вообще можно разобрать?
@КириллЧе-я5ы10 ай бұрын
Почти как [](){[](){[](){}}}…
@olegkomlev3 ай бұрын
Разбирать надо с идентификатора, двигаясь вправо до конца или до непарной закрывающейся скобки, а затем влево до парной открывающейся. Например для "Kchar ( H* ( E* Ax B[ C3 ] D)F() G) I [ J5] " разбираем так: А) "х - это есть... В)"массив из ..." С) "трех ..." D) встретили скобку, поэтому идем влево до парной ей Е) "указателей на ...". Парную скобку "(" нашли ,поэтому продолжаем вправо F) "...функцию, возвращающую..." G) встретили скобку, поэтому идем влево до парной ей Н) "указатель на..." I) "массив " J) "из пяти элементов" .Справа все кончилось, продолжаем влево по непрочитанному К) "типа char"
@borsuk7617Ай бұрын
@selfedu_rus Почему на 4:05 результат функции print_hi интерпретирован как 0?
@Eh_Vasya10 күн бұрын
Говорят что функция неявно возвращает 0 в случае успешного выполнения. Даже если возвращаемый тип не указан (void)