Константы не меняются. Они неизменны. Жизнь устроена иначе, и ваши тестовые программы тоже не должны быть статичными. Если вы изучаете 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.
Эти ошибки повторяются. Но их легко исправить, как только вы распознаете закономерность.




























