
- •6000, Interdata 8/32. Язык "c", однако, не связан с каки-
- •1 Является учебным введением в центральную часть языка "c".
- •1.1. Hачинаем
- •Раздел 7.4. Функция scanf во многом сходна с printf , но она
- •1.5.3. Подсчет символов
- •If (выражение)
- •1.7. Функции
- •1.8. Аргументы - вызов по значению
- •1.10. Область действия: внешние переменные
- •1.11. Резюме
- •2.1. Имена переменных
- •2.9. Побитовые логические операции
- •3.5. Циклы - while и for
- •3.6. Цикл do - while
- •3.7. Оператор break
- •3.8. Оператор continue
- •If (disaster)
- •4.2. Функции, возвращающие нецелые значения
- •2 И 3; она обрабатывает необязательно знак и десятичную точ-
- •4.4. Внешние переменные
- •1, Это соображение следует использовать с определенной осто-
- •If ( число )
- •4.6. Статические переменные
- •4.7. Регистровые переменные
- •4.10. Рекурсия
- •4.11.2. Макроподстановка
- •5.1. Указатели и адреса
- •5.5. Указатели символов и функции
- •5.11. Командная строка аргументов
- •Int argc;
- •5.12. Указатели на функции
- •6.2. Структуры и функции
- •6.5. Структуры, ссылающиеся на себя
- •Int count; /* number of occurrences */
- •8 Мы продемонстрируем, как правильно выполнить эту задачу.
- •Int hashval;
- •6.7. Поля
- •Int ival;
- •6.9. Определение типа
- •Int count; /* number of occurrences */
- •7.1. Обращение к стандартной библиотеке
- •7.2. Стандартный ввод и вывод - функции getchar и putchar
- •7.3. Форматный вывод - функция printf
- •7.4. Форматный ввод - функция scanf
- •7.5. Форматное преобразование в памяти
- •7.6. Доступ к файлам
- •7.7. Обработка ошибок - stderr и exit
- •7.8. Ввод и вывод строк
- •8.1. Дескрипторы файлов
- •8.2. Низкоуровневый ввод/вывод - операторы read и write
- •8.4. Произвольный доступ - seek и lseek
- •8.6. Пример - распечатка справочников
- •Ino_t&_ino; /*inode number*/
- •Ino_t st_ino; /* inode number */
- •13. Объекты и l-значения
- •15.1. Первичные выражения
- •15.2. Унарные операции
- •15.3. Мультипликативные операции
- •15.4. Аддитивные операции
- •15.5. Операции сдвига
- •15.6. Операции отношения
- •15.14. Операция присваивания
- •15.15. Операция запятая
- •16. Описания
- •16.1. Спецификаторы класса памяти
- •16.4. Смысл описателей
- •Int count;
- •16.6. Инициализация
- •0;Неинициализированные автоматические и регистровые перемен-
- •17.7. Оператор switch
- •18.1. Внешнее определение функции
- •19.1. Лексическая область действия
- •19.2. Область действия внешних идентификаторов
- •24. Соображения о переносимости
- •28. Тип перечисления
- •29. Таблица изображений непечатных символов языка "c".
Int count; /* number of occurrences */
STRUCT TNODE *LEFT; /* LEFT CHILD */
STRUCT TNODE *RIGHT; /* RIGHT CHILD */
\) TREENODE, *TREEPTR;
В результате получаем два новых ключевых слова: TREENODE
(структура) и TREEPTR (указатель на структуру). Тогда функ-
цию TALLOC можно записать в виде
TREEPTR TALLOC()
\(
CHAR *ALLOC();
RETURN((TREEPTR) ALLOC(SIZEOF(TREENODE)));
\)
Необходимо подчеркнуть, что описание TYPEDEF не приводит
к созданию нового в каком-либо смысле типа; оно только до-
бавляет новое имя для некоторого существующего типа. при
этом не возникает и никакой новой семантики: описанные таким
способом переменные обладают точно теми же свойствами, что и
переменные, описанные явным образом. По существу конструкция
TYPEDEF сходна с #DEFINE за исключением того, что она интер-
претируется компилятором и потому может осуществлять подста-
новки текста, которые выходят за пределы возможностей мак-
ропроцессора языка "C". Например,
TYPEDEF INT (*PFI) ();
создает тип PFI для "указателя функции, возвращающей значе-
ние типа INT", который затем можно было бы использовать в
программе сортировки из главы 5 в контексте вида
PFI STRCMP, NUMCMP, SWAP;
Имеются две основные причины применения описаний
TYPEDEF. Первая причина связана с параметризацией программы,
чтобы облегчить решение проблемы переносимости. Если для ти-
пов данных, которые могут быть машинно-зависимыми, использо-
вать описание TYPEDEF, то при переносе программы на другую
машину придется изменить только эти описания. Одна из типич-
ных ситуаций состоит в использовании определяемых с помощью
TYPEDEF имен для различных целых величин и в последующем
подходящем выборе типов SHORT, INT и LONG для каждой имею-
щейся машины.
Второе назначение TYPEDEF состоит в обеспечении лучшей доку-
ментации для программы - тип с именем TREEPTR может оказать-
ся более удобным для восприятия, чем тип, который описан
только как указатель сложной структуры.
И наконец, всегда существует вероятность, что в будущем ком-
пилятор или некоторая другая программа, такая как LINT, смо-
жет использовать содержащуюся в описаниях TYPEDEF информацию
для проведения некоторой дополнительной проверки программы.
* 7. Ввод и вывод *
Средства ввода/вывода не являются составной частью языка
"с", так что мы не выделяли их в нашем предыдущем изложении.
Однако реальные программы взаимодействуют со своей окружаю-
щей средой гораздо более сложным образом, чем мы видели до
сих пор. В этой главе будет описана "стандартная библиотека
ввода/вывода", то есть набор функций, разработанных для
обеспечения стандартной системы ввода/вывода для "с"- прог-
рамм. Эти функции предназначены для удобства программного
интерфейса, и все же отражают только те операции, которые
могут быть обеспечены на большинстве современных операцион-
ных систем. Процедуры достаточно эффективны для того, чтобы
пользователи редко чувствовали необходимость обойти их "ради
эффективности", как бы ни была важна конкретная задача. И,
наконец, эти процедуры задуманы быть "переносимыми" в том
смысле, что они должны существовать в совместимом виде на
любой системе, где имеется язык "с", и что программы, кото-
рые ограничивают свои взаимодействия с системой возможностя-
ми, предоставляемыми стандартной библиотекой, можно будет
переносить с одной системы на другую по существу без измене-
ний.
Мы здесь не будем пытаться описать всю библиотеку вво-
да/вывода; мы более заинтересованы в том, чтобы продемонст-
рировать сущность написания "с"-программ, которые взаимодей-
ствуют со своей операционной средой.