#9. Функция scanf() для форматированного ввода | Язык C для начинающих

Sdílet
Vložit
  • čas přidán 11. 09. 2024
  • Практический курс по C/C++: stepik.org/cou...
    Телеграм-канал: t.me/java_and_c
    Инфо-сайт: proproprogs.ru...
    Порядок работы функции scanf() форматированного ввода данных из входного потока stdin. Спецификаторы преобразований и модификаторы.

Komentáře • 40

  • @Aaron_Esh
    @Aaron_Esh Před rokem +12

    Самый лучший преподаватель, которого я когда-либо слышал. Ваши курс на Stepik по ООП - это excellence! Спасибо Вам огромное!

  • @user-cm9nh5hv7w
    @user-cm9nh5hv7w Před 11 měsíci +6

    Спасибо за уроки, очень толковые, всё по делу и без воды. Время 18:00, для модификатора "l" я полагаю приведена ошибочная строка "%hx, %ho, %hu - для unsigned long;", нужно "%lx, %lo, %lu ...

  • @siarheiulas6969
    @siarheiulas6969 Před 3 měsíci +2

    Отличное изложение, спасибо за материал!

  • @name_surname-eo6dz
    @name_surname-eo6dz Před rokem +1

    Отличный плейлист.По Си не так много видосов.Автору респект👍.

  • @ГубкаБоб-р8ъ
    @ГубкаБоб-р8ъ Před rokem +1

    Новый урок, спасибо большое. Всегда жду с нетерпением нового выпуска

  • @АлександрКаптуров-с8и

    Сергей, как же хорошо, что Вы вернулись!) Давно от Вас не было видео

  • @andredru4278
    @andredru4278 Před 8 měsíci +1

    Спасибо. Самое ценное на последних секундах.

  • @TSM_149
    @TSM_149 Před rokem +1

    Большое спасибо за курс! Отличное и понятное изложение.

  • @vimbor5034
    @vimbor5034 Před rokem +1

    Ура, новая лекция!!! Сергей, вы заставили нас волноваться))) Мы уже привыкли к регулярным выходам новых видео, а тут...(( получился большой перерыв после предыдущего видео по Си... Шучу, конечно же...Огромнейшая вам благодарность за то, что находите время делать такие крутые лекции!!!
    P.S. Отдельное спасибо за сертификат с отличием по курсу Добрые, добрые структуры данных! Это приятная неожиданность. Уверен, что курс будет востребован (свой комментарий на Stepik я написал ;))

  • @Jheronimus_Bosch
    @Jheronimus_Bosch Před rokem

    Спасибо за видео! Форматированный ввод - очень удобная вещь.

  • @vadoos2501
    @vadoos2501 Před rokem +1

    Спасибо большое за прекрасно изложенный материал. Все просто супер.
    Сергей, если вдруг планируете вернуться к изложению материала на Python - Flask and Django - представлены на 10 баллов из 10. Хотелось бы еще увидеть такой материал на вашом канале - фреймворк FastAPI - сейчас он набирает полулярность космическими темпами. На ютубе есть пару материалов, но это не то, кроме вас никто не сможет отобразить все основные моменты данного фреймворка)))

  • @MakiHaruko231
    @MakiHaruko231 Před rokem

    Как раз начал изучать Си. Спасибо большое!!!

  • @ztarlitz
    @ztarlitz Před 16 dny +1

    Чем спецификатор формата отличается от модификатора формата? Надо бы про это рассказать. Или дать ссылку на стандарт, а то путаница возникает.

  • @donfedor007
    @donfedor007 Před rokem +1

    Спасибо Вам! очень интересно!

  • @novingo2
    @novingo2 Před 10 měsíci

    Спасибо огромное. Отличный урок

  • @user-xm5zl9up4r
    @user-xm5zl9up4r Před 7 měsíci +1

    Спасибо

  • @jamjam3337
    @jamjam3337 Před rokem +1

    👏👍

  • @maksyann5268
    @maksyann5268 Před 7 měsíci +1

    Почему scanf() не работает в режиме отладки?

  • @user-xr1sr4pz4z
    @user-xr1sr4pz4z Před rokem +1

    Топчик

  • @DGT67
    @DGT67 Před 6 měsíci +1

    Сергей, приветствую! скажите, а канал Network Education случайно не ваш ?) голос очень похож)

    • @selfedu_rus
      @selfedu_rus  Před 6 měsíci +1

      нет )

    • @DGT67
      @DGT67 Před 6 měsíci

      @@selfedu_rus следующий вопрос) кокую книгу по с++ посоветуете из лафоре и прата ?? )

  • @user-zw3dt4qx3i
    @user-zw3dt4qx3i Před rokem +2

    #include
    int main()
    {
    int s;
    int r1, r2, r3, res;
    scanf("%d", &s);
    r1 = s / 100;
    r2 = (s / 10)%10;
    r3 = s % 10;
    res = r1 + r2 + r3;
    printf("%d", res);
    return 0
    }
    Запустил в режиме отладки, останавливается на вызове функции scanf(); вот только в терминале уже не могу ввести данные.
    Без отладки все работает исправно. Как при отладке работать с scanf(); ?

  • @TSM_149
    @TSM_149 Před rokem

    Выполняю уроки в разных ОС - Win и Linux(Ubuntu) в одной и той же среде VSCode (настройки одинаковые std=c99).
    Немного отличается результат при компиляции. В строке 8, в Linux выдается warning:
    ...use of assignment suppresion and length modifier together in gnu_scanf format...
    ,но ввожу данные и всё отрабатывает, как положено. На Win такого нет! Поискал в Google, есть сообщения о таком, но что это и как исправить пока не понимаю, дальше будем разбираться, очень интересно!

  • @user-kb8nl1vz1i
    @user-kb8nl1vz1i Před 7 měsíci +1

    И все же не совсем понимаю, поясните пожалуйста в чем логическая ошибка:
    char x; // объявление переменной - операционная система где то выделяет память. На данном этапе появляется информация об адресе ячейки и длине зарезервированной памяти в одну ячейку.
    x = 5; число 5 записывается в переменную х. И вот после просмотра лекции я уже не понимаю что делает этот оператор. Гораздо логичнее будет так:
    &x = 5; (или 00000101); при этом мы обращается к адресу ячейки и заносим туда значение.
    Так почему мы заносим значение по имени а не сразу по адресу как сканф?

    • @selfedu_rus
      @selfedu_rus  Před 7 měsíci

      Имя переменной - это абстракция языка Си (равно, как и всех других ЯП высокого уровня). Когда компилятор видит имя x он понимает, что в выделенную по эту переменную область памяти, нужно занести (записать) число 5 и формирует соответствующие машинные коды.

  • @lindx2533
    @lindx2533 Před rokem +1

    ахренетья даже и не знал что * делает пропуск данных

  • @whinerino
    @whinerino Před 10 měsíci +1

    Здравствуйте! Подскажите, пожалуйста, как пофиксить проблему "Code is already running"?

    • @selfedu_rus
      @selfedu_rus  Před 10 měsíci

      в трее запущен exe-файл и не завершается, удалите его вручную

  • @user-fj7wb6ji7w
    @user-fj7wb6ji7w Před rokem +1

    16:14 "...возвращаемся в программу, запускаем её..." и только у меня одного ничего не запускается, потому что компилятор выдаёт ошибку "format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘long long int *’ [-Wformat=]" ??

    • @selfedu_rus
      @selfedu_rus  Před rokem

      Вполне возможно, что у вас компилятор проверяет строгое соответствие спецификатора и типа переменной. В scanf() вместо %d пропишите %lld (компилятор должен отрабатывать по стандарту C99).

  • @pewpewpew8613
    @pewpewpew8613 Před 10 měsíci +1

    я конечно дико извиняюсь, но кто решил что будет классной идеей сделать приведение %f в float для scanf(), но в double для printf()?

    • @selfedu_rus
      @selfedu_rus  Před 10 měsíci

      в printf() и float и double выводятся как тип double; в scanf() такое сделать нельзя, т.к. размеры типов разные и нужны уже два спецификатора

  • @grayich
    @grayich Před rokem

    Непойму, почему в scanf используются адреса переменных, а не сами переменные?

    • @selfedu_rus
      @selfedu_rus  Před rokem +1

      если прописать саму переменную, то данные из нее просто будут скопированы в соответствующий параметр функции scanf и все

    • @grayich
      @grayich Před rokem

      @@selfedu_rus а, вот оно что, получается разработчики попытались вложить смысл в каждую возможную вариацию синтаксиса.. сложнааа)

    • @MakiHaruko231
      @MakiHaruko231 Před rokem +1

      Потому что объявления какого-нибудь параметра в функции попадает в стек. А при выходя из области видимости переменная которая была там объявлена удаляется в стеке. То есть, параметр к примеру foo в функции just_function, при достижения компилятором конечной фигурной скобки этой функции, удаляет все объявленные переменные, параметры, из стека. Потому вводимые переменные при вызове функции ничего не меняют, функция лишь копирует значения переменной которую ввели в вызове и присваивает параметру, потом же эти переменные удаляются из стека. Чтобы это не произошло, есть 2 варианта:
      1) Выделить память в куче
      2) Сделать переменную статистической (у статистической переменной продолжительность хранения является окончания программы, то есть она будет жить в оперативной памяти пока программа не завершится).
      Но, это все слишком уж муторно, к примеру тебе надо просто изменить значения переменной в функции, тебе что обязательно выделять память в куче или объявлять статистическую переменную? Нет. Можно сделать все проще. Можно использовать указатель (указатель это переменная которая хранит адрес другой переменной).
      В функции scanf, первый параметр как раз таки и является указатель. Зачем в этой функции указатель если значения его адрес другой переменной? Ну потому что указатель можно разыменовать, что такое разыменование? Это возвращение значения переменной, у которой адрес ты как раз таки хранишь. Разыменования в указателях обозначается символом *. Я приведу пример:
      int i = 2;
      int *ptr = &i; // &i - это адрес переменной i, указатель ptr хранит адрес переменной i
      printf("%d", *ptr); // выведет: *ptr == 2.
      Так вот. В функциях если параметр является указателям, ты можешь там же изменять значения переменной у которой адрес ты хранишь в указателе, с помощью разыменования. И даже не надо будет беспокоиться об стеке, потому что после окончания функции твой параметр указатель просто исчезнет из стека, но это не меняет то что ты изменил значения переменной у которой адрес ты хранишь.
      void scn(int *ptr) {
      *ptr = 4;
      }
      int main() {
      int i = 2;
      printf("Var I: %d", i); // Var I: 2
      scn(&i); // я вызываю функцию scn и передаю адрес переменной
      printf("Var I: %d", i); // Var I: 4
      }

    • @michaelplatonov
      @michaelplatonov Před rokem

      У процессоров есть регистры, в них могут храниться значения, либо адреса памяти по которым эти значения находятся. Также у процессоров есть инструкции, которые могут принимать и возвращать значения в регистрах, адреса в регистрах, значения адресов находятся в памяти. И то и другое просто последовательность нулей и/или единиц, даже сами инструкции.
      Допустим у нас есть функция на Си для перемещения значений двух переменных между собой, через третью:
      long exchange(long *xp, long y)
      {
      long x = *xp;
      *xp = y;
      return x;
      }
      На языке ассемблера получится следующее:
      (адрес xp хранится в регистре %rdi, значение y в %rsi)
      1 movq (%rdi), %rax перемещает значение по адресу находящемуся в регистре %rdi в регистр %rax
      2 movq %rsi, (%rdi) перемещает значение из регистра %rsi по адресу хранящемуся в регистре %rdi
      ret
      Первая инструкция считывает значение x из памяти и сохраняет его в регистре %rax, что является прямой реализацией операции x = *xp, позже регистр %rax будет использован для возврата значения из функции, и поэтому возвращающим значением будет x. Вторая инструкция записывает значение y в ячейку памяти с адресом xp, что является реализацией *xp = y. Этот пример иллюстрирует как инструкцию mov можно использовать для чтения из памяти в регистр и для записи из регистра в память. Во-первых мы видим то что называется указателями в Си - это просто адреса. Во-вторых, локальные переменные, такие как x, часто хранятся в регистрах, а не в ячейках памяти. Доступ к регистру происходит намного быстрее, чем доступ к памяти.

    • @olegkomlev
      @olegkomlev Před 11 měsíci

      В языке С аргументы функции передаются по значению. Поэтому указание самой переменной передает в функцию то, что содержится в переменной (например ,если в переменной записано число 3, то функция получит просто 3 ). Но чтобы изменить значение переменной, функция должна записать что-то в ту область памяти, которая отведена для этой переменной, поэтому ей нужно передать значение адреса, начиная с которого располагается данная переменная (а длина этой области определяется буквой спецификатора после %).
      И довольно частая ошибка начинающих - забыть & для таких переменных. В С++ добавлено более удобное средство: там можно в заголовке функции указать у таких переменных &, тогда при вызове можно будет просто указывать саму переменную, без &. Но scanf - это древняя функция из первоначального С, где такой возможности не было, поэтому для совместимости оставлено именно так.

  • @wolfgerfff7153
    @wolfgerfff7153 Před 11 měsíci

    Здравствуйте, подскажите пожалуйста как собирать и компилировать многофайловые проекты VS Code...буду очень благодарен!!!