Жорстко задані числа (hardcoding) підходять першої спроби, але реальне програмне забезпечення має реагувати те що, що вводять користувачі. Вихідний фрагмент коду використовував константи. Він був статичним. Передбачуваним. Нудним.

Щоб програма стала корисною, необхідно отримувати дані від користувача під час виконання програми. Для цього використовується функція scanf. Вона є протилежністю printf. Якщо printf виводить дані на екран, то scanf зчитує їх із клавіатури.

Нижче показано, як обробляти базове введення цілих чисел C.

Захоплення введення користувача

Не можна просто оголосити змінну і очікувати, що вона магічно прийме дані користувача. Потрібно запитати ці дані. Також необхідно вказати комп’ютеру, куди слід зберегти ці дані. Саме тому scanf вимагає вказівника (знак & ). Якщо ви забудете поставити амперсанд, програма може завершитися аварійно або записати сміття в пам’ять. Завжди використовуйте його для примітивних типів, таких як int.

Розгляньте оновлену логіку:

  1. Оголосіть змінні для зберігання введених даних та результату.
  2. Виведіть підказку (prompt) для користувача, щоб він знав, що вводити.
  3. Використовуйте scanf з правильним специфікатором формату (%d для цілих чисел).
  4. Виконайте обчислення, використовуючи збережені значення.
  5. Виведіть результат, увімкнувши змінні введення до рядка виведення.

`

Чому це важливо

Перехід від констант до змінних змінює все. Програма більше не повторюється як заїжджена платівка. Вона адаптується. Ви можете запустити її один раз із числами 5 та 7. Ви можете запустити її знову з числами 100 та 200. Логіка залишається незмінною; змінюються дані.

Це основа інтерактивних програм командного рядка (CLI). Перш ніж створювати складні інструменти, необхідно зрозуміти, як безпечно отримувати дані змінні.

Ключові висновки

  • scanf вимагає покажчика: Завжди використовуйте оператор взяття адреси (& ) перед ім’ям змінної в scanf.
  • Специфікатори формату повинні збігатися: Якщо ви читаєте int, ви обов’язані використовувати %d. Використання %f для цілого числа призведе до невизначеної поведінки.
  • Підказки (prompts) критично важливі: Без чіткої підказки, такої як “Enter the first value:”, користувач залишиться дивитися на миготливий курсор, запитуючи, зависла програма чи ні. Чи не зависла. Вона просто чекає на введення.

Код працює. Він простий. Але він функціональний. Ви перейшли від статичного скрипта до динамічного інструменту. Наступним кроком зазвичай стає обробка помилок. Що станеться, якщо користувач введе “hello” замість числа? scanf завершиться невдачею мовчки, залишивши ваші змінні неініціалізованими. Це проблема другого дня.

А поки що у вас є програма, яка дійсно прислухається.

Введення, виведення та правила взаємодії

Ви змінили. Тепер скомпілюйте код. Запустіть його. Якщо програма аварійно завершує роботу, не панікуйте. Скоріш за все, ви пропустили якусь дрібну деталь синтаксису.

Візьміть функцію scanf. Вона використовує рядки формату аналогічно printf. Введіть man scanf, якщо вам потрібна докладна документація. Але зверніть увагу на амперсанд (& ) перед змінними, такими як a та b.

Це оператор адреси.

Він повертає адресу пам’яті змінної. Зараз це може здатися заплутаним. Покажчики прояснять це питання пізніше. Але поки що слідуйте правилу: якщо ви використовуєте scanf для char, int або float, вам необхідний &. Він також потрібний для структур.

Пропустіть &? Ви отримаєте помилку виконання. Умисно поруште це правило. Подивіться, що станеться. Це єдиний спосіб запам’ятати, чому це важливо.

Точне форматування виводу

Давайте розберемо printf. Почнемо із простого.

`printf(“Hello”);

Ця команда відправляє слово “Hello” у стандартний висновок. Нічого більше. Без переведення рядка. Курсор залишається одразу після літери “o”.

Тепер додамо переклад рядка.

`printf(“Hello\n”);

\n викликає повернення каретки. Висновок закінчується на власному рядку. Це стандартне очікування для чистого консольного виводу.

Для змінних потрібні заповнювачі. Щоб вивести значення b :

`printf(“%d”, b);

%d це заповнювач. Коли код виконується, printf замінює його фактичним цілим числом b.

Ви можете вбудовувати значення у пропозиції. Ви можете використовувати кілька дзвінків поспіль:

printf("The temperature is"); printf("%d", b); printf("degrees\n");

Але це втомлює. Чистіший підхід полягає в об’єднанні їх в один рядок формату:

printf("The temperature is %d degrees\n", b);

Також можна виводити кілька значень.

`printf(“%d + %d = %d\n”, a, b, c);

Тут криється пастка. Кількість заповнювачів у рядку формату повинна точно відповідати кількості змінних, що йдуть за нею. Точно.

Якщо у вас є три теги %d, вам потрібно три параметри. Типи мають збігатися. Порядок має збігатися. Порушите ці правила? Висновок буде сміттям. Або що гірше, програма аварійно завершить роботу.

Відповідність типів заповнювачам

printf обробляє більшість стандартних типів C. Вам потрібно використовувати правильний код.

  • int використовує %d
  • float використовує %f
  • char використовує %c
  • рядки символів використовують %s

Для більш глибокого розуміння перевірте man 3 printf у системі UNIX. Ваш конкретний компілятор, швидше за все, має керівництво або довідковий файл, що охоплює крайні випадки.

Поширені помилки

Новачки постійно спотикаються про ці моменти.

Регістр символів має суворе значення. printf пишеться малими літерами. Printf або PRINTF призведуть до помилки.

scanf вимагає оператора адреси (& ). Забудьте про нього, і програма не збереже ваше введення правильно.

Кількість параметрів має значення. Занадто багато чи надто мало аргументів у printf або scanf призводить до невизначеної поведінки.

Оголошення має передувати використанню. Ви не можете використовувати ім’я змінної C, не оголосивши його заздалегідь. Компілятор повинен знати структуру пам’яті та тип заздалегідь.

Компілятор не здогадується. Він вимагає суворого дотримання правил.