Константи не змінюються. Вони незмінні. Життя влаштоване інакше, і ваші тестові програми теж не повинні стати статичними. Якщо ви вивчаєте C, жорстко задані числа на кшталт 5 та 7 швидко набридають. Вам потрібна взаємодія. Ви хочете, щоб комп’ютер чекав, поки ви щось введете.
На сцену виходить scanf.
Це друга частина історії, що починається з printf. Якщо printf виводить дані на екран, то scanf зчитує дані з клавіатури. Це не найнадійніший інструмент у стандартній бібліотеці C, але для простого консольного введення він справляється зі своїм завданням без необхідності підключати сторонні залежності.
Ось як перетворити статичний скрипт на динамічну програму.
Код
Скопіюйте його. Запустіть. Введіть цифри, коли програма попросить.
`
Розбір scanf
Магія відбувається у цих двох рядках:
`scanf(“%d”, &a);
scanf: Ім’я функції. Абревіатура від «сканувати форматоване введення» (scan formatted input)."%d": Специфікатор формату. Він вказуєscanfочікувати ціле число. Якби ви зчитували число з плаваючою точкою (float), ви б використовували%f.&a: Це критично важлива частина. Ви передаєте не * значення * змінноїa. Ви передаєте адресу змінноїa.
Уявіть це так: printf повинен знати, що знаходиться всередині змінної. scanf повинен знати, куди помістити дані. Оператор & надає цю адресу в пам’яті. Пропустіть амперсанд і програма аварійно завершиться. Або, що ще гірше, ви отримаєте попередження, яке виглядає як нісенітниця, і змінну, яка не зміниться.
Як це працює на практиці
Коли ви запускаєте програму:
- У терміналі виводиться повідомлення: Enter the first value:
- Курсор блимає. Програма чекає. Ви залишаєтеся в цьому стані, доки не введете щось і не натиснете Enter.
- Ви вводите
5. Натискаєте клавішу Enter. scanfзахоплює це значення5, перетворює рядок символів “5” на ціле значення 5 і зберігає його за адресою пам’яті&a.- Той самий цикл відбувається для другого значення.
Потім виконується математична операція. c = a + b;. Просте додавання.
Зрештою, printf виводить результат. Зверніть увагу на рядок формату: printf("%d+%d=%d\n", a, b, c);. Ви підставляєте змінні назад у рядок. Саме так створюється зрозумілий висновок.
Чому це важливо
Більшість сучасних програм не використовують консольне введення. Ви не вводите команди в чорне вікно для веб-браузера або фоторедактора. Але розуміння цього потоку є фундаментальним.
Введення -> Обробка -> Висновок.
Це базовий цикл будь-якого програмного забезпечення.
Як scanf обробляє адреси пам’яті
Коли ви запускаєте цей код, різниця між успішним виконанням та аварійним завершенням роботи (crash) визначається одним символом. А саме – амперсандом (& ) перед змінними a та b.
Це оператор адреси. Він вказує scanf, куди саме у пам’яті слід записати отримані вхідні дані. Без нього scanf не знає розташування змінної. Він отримує лише значення, яке марне для збереження даних назад у програму. Якщо ви опустите цей оператор, програма або не скомпілюється або негайно аварійно завершиться під час виконання. Цей оператор необхідний для типів char, int, float та структур.
Спробуйте видалити його. Подивіться, що станеться. Це болісний, але необхідний урок про те, як C керує пам’яттю.
Освоєння виведення через printf
printf – це ваше вікно для взаємодії з користувачем. Він надсилає дані до стандартного висновку. Найпростіша версія гранично зрозуміла.
`
Це виводить слово Hello. Нічого більше. Без переведення рядка. Курсор залишається одразу після літери ‘o’.
Додати символ нового рядка.
`
Тепер висновок переходить до наступного рядка. \n – це символ повернення каретки. Він необхідний для зручного для виведення в консолі.
Змінні змінюють правила гри. Ви не можете просто вивести ім’я змінної, як це робиться в Python або JavaScript. Ви маєте використовувати заповнювач (плейсхолдер).
`
%d це заповнювач. Він замінюється цілим значенням змінної b під час виконання. Так C обробляє динамічний висновок.
Ви можете змішувати текст та змінні. Один з незграбних способів – ланцюжок кількох викликів друку.
`
Це працює. Але це також громіздко. Чистіший підхід полягає у вбудовуванні всього в один рядок.
`
Працюють кілька значень. Просто переконайтеся, що наповнювачі відповідають аргументам по порядку.
`
Порядок має значення. Перший ‘%d’ відповідає ‘a’. Другий – b. Третій – c. Якщо ви зміните їх місцями, математика буде неправильною. Якщо ви пропустите один, поведінка програми буде невизначеною. Кількість та типи специфікаторів у рядку формату повинні точно відповідати параметрам.
Специфічні для типів заповнювачі
C суворо слідкує за типами даних. Ви не можете використовувати той самий заповнювач для всього. Ви маєте зіставити тип даних зі специфікатором формату.
- Використовуйте %d для int (цілочисленні значення).
- Використовуйте %f для float (числа з плаваючою комою).
- Використовуйте %c для char (одинакові символи).
- Використовуйте %s для рядків символів (масиви символів).
Якщо ви використовуєте %d для float, ви отримаєте безглуздий висновок. Якщо ви використовуєте %s для int, програма, швидше за все, завершиться аварійно. Точність тут не опціональна.
Для отримання більш детальної інформації про ці специфікатори зверніться до довідкових матеріалів UNIX. Введіть команду man 3 printf. Інші компілятори надають аналогічну документацію. Це варто прочитати.
Поширені помилки, яких слід уникати
Компілятори C корисні, але не вміють читати думки. Ви будете робити помилки. Ось як уникнути найпоширеніших із них.
- Чутливість до регістру : C чутливий до регістру.
PrintfабоPRINTFпризведуть до помилки. Правильно писатиprintf. Те саме стосується імен змінних і викликів функцій. - Відсутність оператора адреси : Забути поставити
&уscanf– часта помилка. Це спричиняє негайний збій під час виконання. Завжди вказуйте для примітивних типів. - Невідповідність параметрів : Занадто багато або занадто мало аргументів у
printfабоscanfпризводить до помилок. Рядок формату визначає структуру. Дотримуйтесь її. - Неоголошені змінні : Ви повинні оголосити змінну перед її використанням. C не виводить типи автоматично. Ви визначаєте
int a;перед тим, як зможете вивестиa.
Ці помилки повторюються. Але їх легко виправити, коли ви розпізнаєте закономірність.




























































