Здравствуйте, Сергей. Хочу вас поблагодарить за ваши видео уроки. Я закончила школу программирования и сейчас активно готовлюсь к собеседованиям. На данный момент смотрю курс по Джанго. Очень помогает при подготовке, и я понимаю что то знала, чем то пользовалась без знаний как это работает. Вы преподаватель от Бога.
3:35 Если заранее известно, что строка заведомо поместится в destination, т.е. нет необходимости контролировать max_len_copy, то всё копирование можно сделать заголовком цикла с пустым телом: while(*dst++=*src++); При этом завершающий \0 тоже будет скопирован этим же циклом, поэтому оператор *dst = '\0'; тоже излишен.
Объясните пожалуйста, по какой причине завершается этот цикл? Запускал отладчик, и он завершается после присваивания dst '/0', но я не понимаю как это влияет на выход из цикла.
Кажется понял: операция присваивания в языке C возвращает результат, равный значению, полученному в результате присваивания, и как раз когда операция возвращает '\0', что по сути равняется 0, тогда и завершается цикл.
@@Вайс-я8з Совершенно верно, присваивание в Си - не только команда, но и выражение, равное значению, которое было присвоено. Последним выполнится присваивание символа \0, этот символ является условием продолжения цикла, а поскольку он равен нулю (условие ложно), то цикл завершается.
Это вы про это: str[sizeof(str) - 1] = '\0'; там в имитации функции strcat() если добавляем больше, чем длина исходной строки, то не будет символа конца строки, поэтому в конец на всякий случай пропишем, чтобы точно был
@@selfedu_rus Почему мы заносим в 14 ячейку, а не в 15. При вычитании str[sizeof(str) - 1] мы добавляем не в последнюю ячейку, а пред последнюю. это на минуте 14:34
@@selfedu_rus понял, я просто думал, что когда объявляем char str[15]; мы получаем от 0…15 . По сути 16 ячеек. А оказывается 0…14. Если работать с индексами. Верно?
Чтобы показать, как работает копирование строки в меньший буфер без терминатора, можно показать копирование в один и тот же буфер двух строк, где вторая будет короче первой. Я бы вообще не рекомендовал использовать небезопасные функции копирования в буфер даже при разработке на микроконтроллерах. Это какой-то анахронизм.
Хмм, мне кажется в while(*buf++) ошибка, произойдет выход указателя *buff за пределы конца строки массива str. Мне кажется правильнее будет так: size_t str_length(const char *str) { const char *p_str = str; while (*p_str) p_str++; return p_str - str; }
Да, ради бога, пусть выходит, это же указатель и его значение может быть любым. Главное, что цикл остановится, когда встретится 0 - маркер конца строки.
Здравствуйте, Сергей. Хочу вас поблагодарить за ваши видео уроки. Я закончила школу программирования и сейчас активно готовлюсь к собеседованиям. На данный момент смотрю курс по Джанго. Очень помогает при подготовке, и я понимаю что то знала, чем то пользовалась без знаний как это работает. Вы преподаватель от Бога.
Спасибо. Объяснение, что под капотом, понравилось.
Спасибо за очередную порцию знаний (повторение для меня) Грамотная подача материала, ЖИРНЫЙ ЛАЙК в поддержку канала!!!
Спасибо
3:35 Если заранее известно, что строка заведомо поместится в destination, т.е. нет необходимости контролировать max_len_copy, то всё копирование можно сделать заголовком цикла с пустым телом:
while(*dst++=*src++);
При этом завершающий \0 тоже будет скопирован этим же циклом, поэтому оператор *dst = '\0'; тоже излишен.
Объясните пожалуйста, по какой причине завершается этот цикл? Запускал отладчик, и он завершается после присваивания dst '/0', но я не понимаю как это влияет на выход из цикла.
Кажется понял: операция присваивания в языке C возвращает результат, равный значению, полученному в результате присваивания, и как раз когда операция возвращает '\0', что по сути равняется 0, тогда и завершается цикл.
@@Вайс-я8з Совершенно верно, присваивание в Си - не только команда, но и выражение, равное значению, которое было присвоено. Последним выполнится присваивание символа \0, этот символ является условием продолжения цикла, а поскольку он равен нулю (условие ложно), то цикл завершается.
спасибо!👏💪👍
как использовать безопасностные функции, если они работают не так, как обычные, например, strcpy и strcpy_s?
Правильно ли я понимаю, что в конструкции while(*buf++), while( ) воспринимает 0 как false, а любые другие значения как true?
да, и не только while, в языке Си (и многих других) 0 - это False, а 1 - True
@@selfedu_rus спасибо
Добрый день! Спасибо за ваши труды! Почему мы при добавление символа конца строки size_of[str]-1. Это же 14 символ получается?
Это вы про это:
str[sizeof(str) - 1] = '\0';
там в имитации функции strcat() если добавляем больше, чем длина исходной строки, то не будет символа конца строки, поэтому в конец на всякий случай пропишем, чтобы точно был
@@selfedu_rus Почему мы заносим в 14 ячейку, а не в 15. При вычитании str[sizeof(str) - 1] мы добавляем не в последнюю ячейку, а пред последнюю. это на минуте 14:34
@@donfedor007 В 15-ю (счет идет с единицы), а индекс ячейки 14 (он отсчитывается с нуля).
@@selfedu_rus понял, я просто думал, что когда объявляем char str[15]; мы получаем от 0…15 . По сути 16 ячеек. А оказывается 0…14. Если работать с индексами. Верно?
@@donfedor007 да
Чтобы показать, как работает копирование строки в меньший буфер без терминатора, можно показать копирование в один и тот же буфер двух строк, где вторая будет короче первой. Я бы вообще не рекомендовал использовать небезопасные функции копирования в буфер даже при разработке на микроконтроллерах. Это какой-то анахронизм.
Хмм, мне кажется в while(*buf++) ошибка, произойдет выход указателя *buff за пределы конца строки массива str. Мне кажется правильнее будет так:
size_t str_length(const char *str)
{
const char *p_str = str;
while (*p_str)
p_str++;
return p_str - str;
}
Да, ради бога, пусть выходит, это же указатель и его значение может быть любым. Главное, что цикл остановится, когда встретится 0 - маркер конца строки.
На Паскале всё гораздо проще.
Там весь этот процесс скрыт внутри. Проще да, но из-за этого не так гибко и временами не так эффективно, как можно сделать на Си.