
- •Происхождение языка с
- •Язык среднего уровня
- •Структурированный язык
- •Язык программирования
- •Компиляторы против интерпретаторов
- •Вид программ на с
- •Библиотеки и компоновка
- •Раздельная компиляция
- •Карта памяти с-программы
- •Переменные, константы, операторы и выражения
- •Идентификаторы
- •Типы данных
- •Модификаторы типов
- •Модификаторы доступа
- •Объявление переменных
- •Локальные переменные
- •Формальные параметры
- •Глобальные переменные
- •Спецификаторы хранения
- •Статические переменные
- •Статические локальные переменные
- •Статические глобальные переменные
- •Регистровые переменные
- •Оператор присваивания
- •Многочисленное присваивание
- •Преобразование типов при присваивании
- •Инициализация переменных
- •Константы
- •Символьные константы с обратным слэшем
- •Операторы
- •Арифметические операторы
- •Увеличение и уменьшение
- •Операторы отношения и логические операторы
- •Битовые операторы
- •Оператор ?
- •Операторы указания & и *
- •Оператор sizeof
- •Оператор «запятая»
- •Операторы [ ] u ()
- •Приоритеты в с
- •Выражения
- •Преобразование типов в выражениях
- •Принудительные преобразования
- •Пробелы и круглые скобки
- •Сокращенные операторы в с
- •Операторы управления программой
- •Истина и ложь в с
- •Операторы выбора
- •Вложенные if
- •Лесенка if-else-if
- •Оператор ?
- •Вложенные операторы switch
- •Вариации цикла for
- •Бесконечный цикл
- •Циклы for без тела
- •Метки и goto
- •Функции
- •Оператор return
- •Выход из функции
- •Возвращаемые значения
- •Значения, возвращаемые функцией main()
- •Правила видимости для функций
- •Аргументы функции
- •Передача по значению и передача по ссылке
- •Создание передачи по ссылке
- •Передача массивов в функции
- •Аргументы функции main()
- •Функции, возвращающие нецелые значения
- •Использование прототипов функции
- •Прототипы стандартных библиотечных функций
- •Создание прототипов функций, не имеющих параметров
- •Возврат указателей
- •Рекурсия
- •Сопоставление классического и современного объявления параметров
- •Указатели на функции
- •Особенности реализации
- •Параметризированные функции и функции общего назначения
- •Эффективность
- •Массивы
- •Одномерный массив
- •Создание указателя на массив
- •Передача одномерных массивов в функции
- •Двумерные массивы
- •Массивы строк
- •Многомерные массивы
- •Индексация с помощью указателей
- •Размещение массивов
- •Инициализация массива
- •Инициализация безразмерных массивов
- •Пример программы игры в крестики-нолики
- •Указатели
- •Указатели - это адреса
- •Переменные-указатели
- •Операторы для работы с указателями
- •Выражения с указателями
- •Присваивание указателей
- •Арифметические действия с указателями
- •Сравнение указателей
- •Динамическое выделение и указатели
- •Указатели на константы
- •Указатели на константы
- •Указатели на константы
- •Указатели и массивы
- •Указатели на символьные массивы
- •Массивы указателей
- •Указатели на указатели - многочисленное перенаправление
- •Инициализация указателей
- •Указатели на функции
- •Проблемы, связанные с указателями
- •Структуры, объединения и определяемые пользователем типы
- •Структуры
- •Доступ к членам структуры
- •Присваивание структур
- •Массивы структур
- •Программа инвентаризации
- •Передача структур в функции
- •Передача членов структур в функции
- •Передача всей структуры в функцию
- •Указатели на структуры
- •Объявление указателя на структуру
- •Использование указателей на структуру
- •Массивы и структуры в структурах
- •Битовые поля
- •Объединения
- •Перечисления
- •Использование sizeof для обеспечения переносимости
- •Ввод, вывод, потоки и файлы
- •Потоки и файлы
- •Текстовые потоки
- •Двоичные потоки
- •Консольный ввод/вывод
- •Чтение и запись символов
- •Чтение и запись строк: gets() и puts()
- •Форматированный консольный ввод/вывод
- •Печать символов
- •Вывод чисел
- •Вывод адресов
- •Спецификатор %n
- •Модификаторы формата
- •Спецификатор минимума ширины поля
- •Спецификатор точности
- •Выровненный вывод
- •Работа с другими типами данных
- •Модификаторы * u #
- •Спецификаторы формата
- •Ввод чисел
- •Ввод беззнаковых целых
- •Чтение отдельных символов с помощью scanf()
- •Чтение строк
- •Ввод адреса
- •Спецификатор %n
- •Использование множества сканирования
- •Пропуск нежелательных специальных символов
- •Обычные символы в управляющей строке
- •В scanf() следует передавать адреса
- •Модификаторы формата
- •Подавление ввода
- •Файловая система ansi с
- •Указатель на файл
- •Открытие файла
- •Запись символа
- •Чтение символа
- •Использование fopen(), getc(), putc() и fclose()
- •Использование feof()
- •Две расширенные функции: getw() и putw()
- •Работа со строками: fgets() и fputs()
- •Fseek() и произвольный доступ
- •Удаление файлов
- •Работа с консолью
- •Препроцессор и комментарии
- •Директивы условной компиляции
- •Использование defined
- •Операторы препроцессора # и ##
- •Предопределенные макросы
- •Комментарии
Ввод адреса
Для ввода адреса следует использовать спецификатор формата %р. Данный спецификатор позволяет функции scanf() читать адрес в формате, определяемом архитектурой процессора. Например, следующая программа вводит адрес и отображает содержимое по этому адресу: #include <stdio.h> int main(void) { char *p; printf ("Enter an address: "); scanf{"%р", &p); printf("Value at. location %p is %c\n", p, *p); return 0; }
Спецификатор %n
Спецификатор %n говорит функции scanf() о необходимости присвоения переменной, на которую указывает соответствующий аргумент, числа прочитанных символов из потока ввода на момент обнаружения %n.
Использование множества сканирования
Функция scanf() поддерживает спецификатор формата общего назначения, называемый множеством сканирования. Множество сканирования определяет набор символов. Когда scanf() обрабатывает множество сканирования, она вводит символы до тех пор, пока символы являются частью множества сканирования. Читаемые символы сохраняются в символьном массиве, на который указывает соответствующий аргумент. Для определения множества сканирования необходимо поместить сканируемые символы в квадратные скобки. Открывающей квадратной скобке должен предшествовать знак процента. Например, следующее множество сканирования сообщает функции scanf() о необходимости чтения только символов X, Y и Z:
%[XYZ]
При использовании множества сканирования функция scanf() продолжает читать символы и помещает их в соответствующий массив символов, пока не встретится символ, не принадлежащий множеству сканирования. После возврата из scanf() массив будет содержать оканчивающуюся нулевым символом строку, состоящую из введенных символов. Чтобы понять, как это работает, рассмотрим программу: #include <stdio.h> int main(void) { int i; char str[80], str2[80]; scanf ("%d%[abcdefg]%s", &i, str, str2); printf ("%d %s %s", i, str, str2); return 0; } Введем 123abcdtye, после чего нажмем ввод. Программа отобразит 123 abed tye. Поскольку "t" не является частью множества сканирования, scanf() останавливает чтение символов в str при обнаружении "t". Оставшиеся символы помещаются в str2.
Можно указать диапазоны множества сканирования, используя дефис. Например, следующая команда говорит функции scanf() о необходимости чтения символов от «А» до «Z»:
% [A-Z]
Использование дефиса для описания диапазонов не определено стандартом ANSI С. Тем не менее это общепринято.
Можно определить более одного диапазона, используя множество сканирования. Например, данная программа читает цифры, а затем буквы: /* пример использования множества сканирования с заданием диапазонов */ #linclude <stdio.h> int main (void) { char s1[80], s2[80]; printf("Enter numbers, then some letters"); scanf("%[0-9]%[a-zA-Z]", s1, s2); printf("%s %s", s1, s2); return 0; }
Можно указать инвертированный набор в случае, если первый символ - это ^. Если присутствует ^, то scanf() принимает все символы, не определенные во множестве сканирования. Следующая программа использует ^ для инверсии типа символов, читаемых множеством сканирования: /* пример использования множества сканирования с заданием инвертированных диапазонов */ #include <stdio.h> int main(void) { char s1[80], s2[80]; printf("Enter non-numbers, then some non-letters"); scanf ("%[^0-9]%[^a-zA-Z]", s1, s2) ; printf ("%s %s", s1, s2); return 0; }
Следует помнить, что множество сканирования чувствительно к регистру. Следовательно, если необходимо просканировать как прописные, так и строчные буквы, следует указать их отдельно.