Практика языка C (МФТИ, 2023-2024). Интермедия: командная строка, файлы и вариабельные аргументы.

preview_player
Показать описание
Практические занятия по языку C на первом курсе МФТИ. Кафедра информатики.

На этом занятии мы поговорим о файлах и всём что естественно затронуть вокруг них, в частности про аргументы командной строки и про функции с вариабельным числом аргументов.

Семинарист: Константин Владимиров.
Дата: 17 ноября 2023 года.
Съёмка: Марк Гончаров.
Звук: Юлий Тарасов.

Timeline
00:00 Аргументы функции main
09:15 Поиск в файлах: первый шаг
12:40 Перевод строки в число
18:55 Работа с файлами
26:30 Просто открыть и закрыть
30:50 Права доступа
35:22 Форматный ввод и вывод
41:55 Поиск в файлах
45:15 Время решать задачи
46:50 Печать в строчку
50:30 Вариабельные аргументы
58:24 Написать printf и похожие функции
01:09:30 Разбор задач и завершение

Errata:
* Пока пусто
Рекомендации по теме
Комментарии
Автор

Огонь, эти лекции зайдут "встройщикам".

DARTWADER
Автор

Константин, спасибо за лекцию.

42:35 - опечатка "лл"

И, кстати, в одной из лекций был вопрос - почему полно народу в дискорде, но на стриме никто не сидит. Ссылки таки нужно выкладывать, стримы я, например, могу только позднее смотреть. Все ссылки я себе сохраняю :) Смотрю, как появляется возможн7ость - позже на месяц, на три :D

alex_s_ciframi
Автор

Эх, не хватает времени на всё(, вот вроде и видос есть полезный, интересный, а уже минут через 15 спать надо((

xaoc
Автор

Благодарю за лекции, Константин! Весьма увлекательно и познавательно. 5:55 разве размер массива argv не argc+1?

antonpetrenko
Автор

Спасибо за лекцию, очень нравится, что даже довольно скучные вещи у вас получается объяснять интересно и на реальных примерах, жалко правда, что в этой лекции всего 1 задача на подумать, но это понятно, т.к. базового материала довольно много.

Касательно размера буфера в PrintFError, задача действительно не тривиальная, и вполне понятно, что вычисление точного размера будет эквивалентно по сложности написанию своей реализации функции принтф, однако достаточно ведь только примерно оценить этот размер, для чего необходимо будет только обработать флаги, подставить максимально возможный символьный размер для каждого спецификатора, кроме строк и добавить вычисленные размеры строк, ну и добавить длину строки формата.
Хотя также выглядит весьма здравым решением отдать вычисление порядка буфера юзеру и просто принимать дополнительный аргумент.

Также есть вопрос, насколько вообще эффективно использовать функции с префиксом v, когда в языке присутствует вариадик макрос? лично мне кажется, что неэффективно, т.к. передача va_list в аргумент уберает любую возможность оптимизации функций с переменным числом аргументов, в виде передачи некоторое количество этих аргументов через регистры, что реализуют многие компиляторы.
Ну т.е. не лучше ли функции с простой логикой, как например PrintFError без вычисления размера буфера, выносить в макросы с переменным числом аргументов?

ДенисСомин
Автор

подушню немножко.
4:03 в стандарте "argc должен быть неотрицательным". нулем тоже может быть (а вдруг вашу программу кто-то через execv вызвал с нуликами?). и argv[0] тогда тоже должен быть нулевым указателем (:

Stedmiel
Автор

Про printf аналоги. Выход однозначно лучше - vsnprintf и обработка возвращаемого значения.
Или принимать буфер аргументом. Из "принято решать" есть ещё vasprintf, что конечно не советую никому.
Также, в подобных функциях по очевидным причинам буфер обычно static и нередко общий для семейства функций, например в известном DearImGui.

Важный нюанс - компилятор не будет проверять fmt-строку таких функций в отличие от стандартных, что крайне чревато, ошибки легки и повсеместны.
В GCC и MinGW решение: __attribute__((format(printf, 1, 2))) в начале объявления функции, в документации описано подробно.

Вообще использовать функции без N, не имея инвариантов и надеясь на лучшее - а потом условные "эксперты" опеннета именуют С "дыряшкой".

OttogiMazik
Автор

Интересно, а почему Константин Игоревич не объявляет счетчик цикла прямо в круглых скобках в объявлении цикла. См. стр. 19 на 27:25
По-моему, объяснение чтобы видеть все переменные функции здесь не работает, т.к. переменная i используется только внутри цикла

MVZ
Автор

Очень круто, Большое спасибо!
У меня возник вопрос по вариадическим аргументам.
Вот есть функция sum(len, a, b, c, ...). Зачем там указывать len ? Видимо чтобы в va_list указать откуда отталкиваться и начать считывать. Почему нельзя было написать sum(...) нельзя ли начать считывать с самого начала аргументов, а не отталкиваться от последнего в сигнатуре ?

kemalbidzhiev
Автор

Для любителей конспирологии.
Закладывался ли смысл в синий задний фон...

dmitriy
Автор

Разъясните, как f(x, ...) раскладывает на стек параметры - как оно там под капотом устроено?

dmitryivanov
Автор

А лекции по Си есть записи или планируются ?

Якстатинепонимаюкак