45940 (665245), страница 2
Текст из файла (страница 2)
Компилятор с “C” может быть простым и компактным. Кроме то-
го, компиляторы легко пишутся; при использовании современной
технологии можно ожидать написания компилятора для новой ЭВМ
за пару месяцев и при этом окажется, что 80 процентов прог-
раммы нового компилятора будет общей с программой для уже
существующих компиляторов. Это обеспечивает высокую степень
мобильности языка. Поскольку типы данных и стуктуры управле-
ния, имеющиеся в “C”, непосредственно поддерживаются боль-
шинством существующих ЭВМ, библиотека, необходимая во время
прогона изолированных программ, оказывается очень маленькой.
На PDP -11, например, она содержит только программы для
32-битового умножения и деления и для выполнения программ
ввода и вывода последовательностей. Конечно, каждая реализа-
ция обеспечивает исчерпывающую, совместимую библиотеку функ-
ций для выполнения операций ввода-вывода, обработки строк и
распределения памяти, но так как обращение к ним осуществля-
ется только явно, можно , если необходимо, избежать их вызо-
ва; эти функции могут быть компактно написаны на самом “C”.
-
8 -
Опять же из-за того , что язык “C” отражает возможности
современных компьютеров, программы на “C” оказываются доста-
точно эффективными, так что не возникает побуждения писать
вместо этого программы на языке ассемблера. Наиболее убеди-
тельным примером этого является сама операционная система
“UNIX”, которая почти полностью написана на “C”. Из 13000
строк программы системы только около 800 строк самого низко-
го уровня написаны на ассемблере. Кроме того, по существу
все прикладное программное обеспечение системы “UNIX” напи-
сано на “C”; подавляющее большинство пользователей системы
“UNIX”(включая одного из авторов этой книги) даже не знает
языка ассемблера PDP-11.
Хотя “C” соответствует возможностям многих ЭВМ, он не
зависит от какой-либо конкретной архитектуры машины и в силу
этого без особых усилий позволяет писать “переносимые” прог-
раммы, т.е. программы, которые можно пропускать без измене-
ний на различных аппаратных средствах. В наших кругах стал
уже традицией перенос программного обеспечения, разработан-
ного на системе “UNIX”, на системы ЭВМ: HONEYWELL, IBM и
INTERDATA. Фактически компиляторы с “C” и программное обес-
печение во время прогона программ на этих четырех системах,
по-видимому, гораздо более совместимы, чем стандартные вер-
сии фортрана американского национального института стандар-
тов (ANSI). Сама операционная система “UNIX” теперь работает
как на PDP-11, так и на INTERDATA 8/32. За исключением прог-
рамм, которые неизбежно оказываются в некоторой степени ма-
шинно-зависимыми, таких как компилятор, ассемблер и отлад-
чик. Написанное на языке “C” программное обеспечение иден-
тично на обеих машинах. Внутри самой операционной системы
7000 строк программы, исключая математическое обеспечение
языка ассемблера ЭВМ и управления операциями ввода-вывода,
совпадают на 95 процентов.
Программистам, знакомым с другими языками, для сравне-
ния и противопоставления может оказаться полезным упоминание
нескольких исторических, технических и философских аспектов
“C”.
Многие из наиболее важных идей “C” происходят от гораз-
до более старого, но все еще вполне жизненного языка BCPL ,
разработанного Мартином Ричардсом. Косвенно язык BCPL оказал
влияние на “C” через язык “B”, написанный Кеном Томпсоном в
1970 году для первой операционной системы “UNIX” на ЭВМ
PDP-7.
Хотя язык “C” имеет несколько общих с BCPL характерных
особенностей, он никоим образом не является диалектом пос-
леднего. И BCPL и “B” - “безтипные” языки; единственным ви-
дом данных для них являются машинное слово, а доступ к дру-
гим объектам реализуется специальными операторами или обра-
щением к функциям. В языке “C” объектами основных типов дан-
ных являются символы, целые числа нескольких размеров и чис-
ла с плавающей точкой. Кроме того, имеется иерархия произ-
водных типов данных, создаваемых указателями, массивами,
структурами, объединениями и функциями.
-
9 -
Язык “C” включает основные конструкции потока управле-
ния, требуемые для хорошо структуированных программ: группи-
рование операторов, принятие решений (IF), циклы с проверкой
завершения в начале (WHILE, FOR) или в конце (DO) и выбор
одного из множества возможных вариантов (SWITCH). (Все эти
возможности обеспечивались и в BCPL, хотя и при несколько
отличном синтаксисе; этот язык предчувствовал наступившую
через несколько лет моду на структурное программирование).
В языке “C” имеются указатели и возможность адресной
арифметики. Аргументы передаются функциям посредством копи-
рования значения аргумента , и вызванная функция не может
изменить фактический аргумент в вызывающей программе. Если
желательно добиться “вызова по ссылке”, можно неявно пере-
дать указатель, и функция сможет изменить объект, на который
этот указатель указывает. Имена массивов передаются указани-
ем начала массивов, так что аргументы типа массивов эффек-
тивно вызываются по ссылке.
К любой функции можно обращаться рекурсивно, и ее ло-
кальные переменные обычно “автоматические”, т.е. Создаются
заново при каждом обращении. Описание одной функции не может
содержаться внутри другой, но переменные могут описываться в
соответствии с обычной блочной структурой. Функции в “C” -
программе могут транслироваться отдельно. переменные по от-
ношению к функции могут быть внутренними, внешними, но из-
вестными только в пределах одного исходного файла, или пол-
ностью глобальными. Внутренние переменные могут быть автома-
тическими или статическими. Автоматические переменные для
большей эффективности можно помещать в регистры, но объявле-
ние регистра является только указанием для компилятора и ни-
как не связано с конкретными машинными регистрами.
Язык “C” не является языком со строгими типами в смысле
паскаля или алгола 68. Он сравнительно снисходителен к пре-
образованию данных, хотя и не будет автоматически преобразо-
вывать типы данных с буйной непринужденностью языка PL/1.
Существующие компиляторы не предусматривают никакой проверки
во время выполнения программы индексов массивов, типов аргу-
ментов и т.д.
В тех ситуациях, когда желательна строгая проверка ти-
пов, используется специальная версия компилятора. Эта прог-
рамма называется LINT очевидно потому, она выбирает кусочки
пуха из вашей программы. Программа LINT не генерирует машин-
ного кода, а делает очень строгую проверку всех тех сторон
программы, которые можно проконтролировать во время компиля-
ции и загрузки. Она определяет несоответствие типов, несов-
местимость аргументов, неиспользованные или очевидным обра-
зом неинициализированные переменные, потенциальные трудности
переносимости и т.д. Для программ,которые благополучно про-
ходят через LINT, гарантируется отсутствие ошибок типа при-
мерно с той же полнотой, как и для программ, написанных,
например, на АЛГОЛЕ-68. Другие возможности программы LINT
будут отмечены, когда представится соответствующий случай.
-
10 -
Наконец, язык “C”, подобно любому другому языку, имеет
свои недостатки. Некоторые операции имеют неудачное старшин-
ство; некоторые разделы синтаксиса могли бы быть лучше; су-
шествует несколько версий языка, отличающихся небольшими де-
талями. Тем не менее язык “C” зарекомендовал себя как исклю-
чительно эффективный и выразительный язык для широкого раз-
нообразия применений программирования.
Содержание книги организовано следующим образом. Глава
1 является учебным введением в центральную часть языка “C”.
Цель - позволить читателю стартовать так быстро,как только
возможно, так как мы твердо убеждены, что единственный спо-
соб изучить новый язык - писать на нем программы. При этом ,
однако, предполагается рабочее владение основными элементами
программирования; здесь не объясняется, что такое ЭВМ или
компилятор, не поясняется смысл выражений типа N=N+1. Хотя
мы и пытались, где это возможно, продемонстрировать полезную
технику программирования. Эта книга не предназначается быть
справочным руководством по структурам данных и алгоритмам;
там, где мы вынуждены были сделать выбор, мы концентрирова-
лись на языке.
В главах со 2-й по 6-ю различные аспекты “C” излагаются
более детально и несколько более формально, чем в главе 1,
хотя ударение по-прежнему делается на разборе примеров за-
конченных, полезных программ, а не на отдельных фрагментах.
В главе 2 обсуждаются основные типы данных, операторы и
выражения. В главе 3 рассматриваются управляющие операторы:
IF-ELSE ,WHILE ,FOR и т.д. Глава 4 охватывает функции и
структуру программы - внешние переменные, правила определен-
ных областей действия описания и т.д. В главе 5 обсуждаются
указатели и адресная арифметика. Глава 6 содержит подробное
описание структур и объединений.
В главе 7 описывается стандартная библиотека ввода-вы-
вода языка “C”, которая обеспечивает стандартный интерфейс с
операционной системой. Эта библиотека ввода-вывода поддержи-
вается на всех машинах, на которых реализован “C”, так что
программы, использующие ее для ввода, вывода и других сис-
темных функций, могут переноситься с одной системы на другую
по существу без изменений.
В главе 8 описывается интерфейс между “C” - программами
и операционной системой “UNIX”. Упор делается на ввод-вывод,
систему файлов и переносимость. Хотя некоторые части этой
главы специфичны для операционной системы “UNIX”, програм-
мисты, не использующие “UNIX”, все же должны найти здесь по-
лезный материал, в том числе некоторое представление о том,
как реализована одна версия стандартной библиотеки и предло-
жения для достижения переносимости программы.
Приложение A содержит справочное руководство по языку
“C”. Оно является “официальным” изложением синтаксиса и се-
мантики “C” и (исключая чей-либо собственный компилятор)
окончательным арбитром для всех двусмысленностей и упущений
в предыдущих главах.
-
11 -
Так как “C” является развивающимся языком, реализован-
ным на множестве систем, часть материла настоящей книги мо-
жет не соответствовать текущему состоянию разработки на ка-
кой-то конкретной системе. Мы старались избегать таких проб-
лем и предостерегать о возможных трудностях. В сомнительных
случаях, однако, мы обычно предпочитали описывать ситуацию
для системы “UNIX” PDP-11 , так как она является средой для
большинства программирующих на языке “C”. В приложении а
также описаны расхождения в реализациях языка “C” на основ-
ных системах.
1. Учебное введение.
Давайте начнем с быстрого введения в язык “C”. Наша
цель - продемонстрировать существенные элементы языка на ре-
альных программах, не увязая при этом в деталях, формальных
правилах и исключениях. В этой главе мы не пытаемся изложить
язык полностью или хотя бы строго (разумеется, приводимые
примеры будут корректными). Мы хотим как можно скорее довес-
ти вас до такого уровня, на котором вы были бы в состоянии
писать полезные программы, и чтобы добиться этого, мы сосре-
дотачиваемся на основном: переменных и константах, арифмети-
ке, операторах передачи управления, функциях и элементарных
сведениях о вводе и выводе. Мы совершенно намеренно оставля-
ем за пределами этой главы многие элементы языка “C”, кото-
рые имеют первостепенное значение при написании больших
программ, в том числе указатели, сртуктуры, большую часть из
богатого набора операторов языка “C”, несколько операторов
передачи управления и несметное количество деталей.
Такой подход имеет, конечно, свои недостатки. Самым су-