Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Knig13524_Prog / M._UEIT_Yazyik_Si_-_rukovodstvo_dlya_nachinayuschih.451484

.pdf
Скачиваний:
220
Добавлен:
30.05.2015
Размер:
665.1 Кб
Скачать

M. УЭИТ С. ПРАТА Д. МАРТИН Язык Си - руководство для начинающих

"Мир"; Москва; 1988 ISBN 5-03-001309-1 /русск./

Аннотация

M. УЭИТ С. ПРАТА Д. МАРТИН

Язык Си — руководство для начинающих

Предисловие редактора перевода

Созданием языков программирования занимаются в большинстве случаев очень квалифицированные люди, часто группы программистов, а иногда даже международные коллективы. Однако подавляющее большинство языков программирования умирало, едва родившись. Лишь к немногим из них был проявлен интерес, и буквально единицы получили действительно широкое распространение. К таким "счастливым" языкам принадлежит язык Си, разработанный Д. Ритчи. Он появился не на пустом месте. Ему предшествовали и оказали на него серьезное влияние язык BCPL, разработанный М. Ричардсоном, и язык Би (В), созданный К. Томпсоном.

Си — это достаточно выразительный язык программирования, предназначенный для описания широкого круга задач и содержащий современные механизмы управления вычислительным процессом и работы с данными. В то же время язык Си очень прост: в него введены некоторые средства, характерные скорее для ассембле-ров, чем для языков высокого уровня. Простота языка не требует создания слишком сложных компиляторов и позволяет получать достаточно эффективный объектный код. Эти свойства языка особенно важны при написании операционных систем, но они могут оказаться очень полезными и при разработке прикладных программ.

Наибольшую популярность язык приобрел у системных программистов. Видимо, этому способствовали как сам факт успешного написания на языке Си переносимой операционной системы UNIX, получившей широкое распространение, так и элегантность и лаконичность языка. Чрезвычайно привлекательными для системных программистов оказались возможность использовать память раз-яичных типов в том числе регистровую, введение указателей, являющихся аналогами косвенных адресов, а также возможность работы со сложными структурами данных, применение препроцессора и Удобство работы с символьными строками.

Прикладные программы пишутся обычно на традиционных языках высокого уровня,

например на Фортране. Однако в тех случаях, когда некоторые части таких программ оказываются особенно критичными в отношении времени, их можно писать не на ассемблере, как обычно, а на языке Си. Такой подход сократит время разработки прикладных программ, обеспечит их достаточную эффективность, а во многих случаях и переносимость, т. е. использование одной программы на ЭВМ различных типов.

Предлагаемая читателю книга — учебник по языку Си. Книга написана известными американскими специалистами М. Уэйтом, С. Пратой и Д. Мартином с большим педагогическим и методическим мастерством: излагаемый материал проиллюстрирован многочисленными примерами и задачами. Это обеспечивает легкость понимания и усвоения предмета. Поскольку трансляторы с языка Си появились сейчас на отечественных машинах, книга может представлять интерес не только для широкого круга читателей, впервые знакомящихся с языком Си, но и для системных программистов, инженеров и научных работников.

Перевод выполнили В. С. Явнилович (предисловие, гл. 1–9) и Л. Н. Горинович (гл. 10– 15 и приложения).

Э. А. Трахтенгерц

Предисловие

Си — простой, изящный язык программирования, на котором останавливает свой выбор все большее число программистов. Эта книга (если вы не посмотрели на титульный лист) называется "Язык Си. Руководство для начинающих"; она представляет собой простой и хороший учебник по языку Си.

Слова "Руководство для начинающих", стоящие в подзаголовке книги, говорят о том, что нашей целью было дать обзор основ языка Си. В программировании опыт — великий учитель; с этой целью в книге приведено много задач учебного и познавательного характера. Мы пытались использовать рисунки всюду, где, как мы надеялись, они помогут внести ясность. Чтобы вы имели возможность проверить себя, в конце каждой главы приводятся вопросы для самоконтроля (и ответы на них). Мы не предполагаем у вас большого опыта работы на каком-нибудь языке программирования, однако иногда будем сравнивать язык Си с другими языками, ориентируясь на тех читателей, которые знают их.

Мы несколько расширили границы обычного учебника: обсудили ряд более сложных тем, таких, как использование структур, приведение типов, работу с файлами; в приложении мы рассмотрели возможности побитовой обработки на языке Си, а также некоторые расширения языка. Мы описали программную среду компилятора с языка Си, функционирующего как с операционной системой UNIX, так и с программным обеспечением микрокомпьютеров: например, обсудили вопрос переключения ввода-вывода и продемонстрировали использование портов в микропроцессорах INTEL 8086/8088. И наконец, мы включили шутливые рисунки как одно из довольно приятных дополнений.

Мы попытались сделать эту книгу поучительной, понятной и полезной. Чтобы получить максимальную пользу от книги, вы должны работать с ней самым активным образом. Не занимайтесь просто чтением примеров. Вводите их в вашу вычислительную систему и пытайтесь выполнить. Хотя Си и переносимый (или мобильный) язык, вполне возможно, вы найдете различия между тем, как программа работает в вашей системе и у нас. Не бойтесь экспериментировать — измените часть программы, чтобы увидеть, к чему это приведет. Модифицируйте ваши программы, чтобы они слегка отличались от исходных. Попробуйте не обращать внимания на наши иногда встречающиеся предупреждения и посмотрите, что при этом произойдет. Попытайтесь ответить на вопросы и выполнить упражнения. Чем больше вы сделаете самостоятельно, тем большему научитесь.

Мы желаем вам удачи при изучении языка Си. Мы попытались сделать книгу отвечающей вашим потребностям и надеемся, что она поможет вам достичь поставленных целей.

Мы благодарим Роберта Лафора из издательства Waite Group за редакторские советы и Боба Петерсена за техническую помощь. Мы приносим благодарность также компании Lifeboat Associates (в особенности Джошуа Аллену и Тодду Кацу) за возможность использовать компилятор Lattice С. Мы благодарим специалистов компаний C-Systems, Software Toolworks, Telecon Systems и Supersoft за предоставленную нам информацию о своих компиляторах с языка Си. Один из авторов, С. Прата, посвящает свой труд родителям

— Вики и Биллу — с любовью.

М. Уэйт, С. Прата, Д. Мартин

1. Вступление

ИСТОРИЯ СИ ДОСТОИНСТВА СИ ЯЗЫКИ КОМПИЛЯЦИИ

Добро пожаловать в мир языка Си. В данной главе мы попробуем подготовить вас к изучению этого мощного языка, завоевывающего все большую популярность. Что вам для этого нужно? Во-первых, интерес к Си, который, по-видимому, у вас уже есть. Но, чтобы усилить его, мы кратко обрисуем некоторые привлекательные стороны данного языка. Вовторых, вы нуждаетесь в учебнике по языку Си — и учебником послужит вам эта книга. Кроме того, вам нужен доступ к какой-нибудь вычислительной системе, в которой имеется компилятор с языка Си. Это вы должны обеспечить себе сами. Наконец, вам необходимо научиться выполнять Си-программу на вашей вычислительной системе, и мы в конце главы дадим вам несколько советов по этому поводу.

ПРОИСХОЖДЕНИЕ ЯЗЫКА СИ

Сотрудник фирмы Bell Labs Деннис Ритчи создал язык Си в 1972 г. во время совместной работы с Кеном Томпсоном над операционной системой UNIX. Ритчи не выдумал Си просто из головы — прообразом послужил язык Би, разработанный Томпсоном, который в свою очередь…, но это уже другая история. Важным моментом для нас является то, что язык Си был разработан как инструмент для программистов-практиков. В соответствии с этим главной целью его автора было создание удобного и полезного языка.

Мы думаем, что критерий полезности принимался во внимание ПРИ разработке большинства языков программирования, но, кроме того, часто учитывались и другие потребности. Одной из главных Целей при создании языка Паскаль, например, было построение ПРОЧНЫХ основ обучения принципам программирования. Язык Бейсик создавался так, чтобы его синтаксис был близок к синтаксису английского языка; поэтому им легко могли пользоваться студенты, не знакомые с ЭВМ. Все эти цели тоже важны, но они не всегда совместимы с прагматическими, каждодневными требованиями. Предпосылки, послужившие основой создания языка Си как средства программирования, позволили разработать, кроме того, язык, облегчающий труд программиста.

ДОСТОИНСТВА ЯЗЫКА СИ

Язык Си быстро становится одним из наиболее важных и популярных языков программирования. Его использование все более расширяется, поскольку часто программисты предпочитают язык Си всем другим языкам после первого знакомства с ним. Когда вы изучите язык Си достаточно хорошо, вы сможете оценить многие из его достоинств. Сейчас мы упомянем лишь некоторые из них.

Си — современный язык . Он включает в себя те управляющие конструкции, которые рекомендуются теоретическим и практическим программированием. Его структура побуждает программиста использовать в своей работе нисходящее проектирование, структурное программирование и пошаговую разработку модулей. Результатом такого подхода является надежная и читаемая программа.

Си — эффективный язык . Его структура позволяет наилучшим образом использовать возможности современных ЭВМ. На языке Си программы обычно отличаются компактностью и быстротой исполнения.

Си — переносимый, или мобильный, язык . Это означает, что программа, написанная на Си для одной вычислительной системы, может быть перенесена с небольшими изменениями (или вообще без них) на другую. Если модификации все-таки необходимы, то часто они могут быть сделаны путем простого изменения нескольких элементов в "головном" файле, который сопутствует главной программе. Конечно, структура большинства языков программирования подразумевает переносимость, но тот, кто переносил программу, написанную на Бейсике, с персональной ЭВМ IBM PC на машину Apple (они во многом, похожи) или пытался выполнить программу, написанную на Фортране для машины типа IBM, в системе UNIX, знает о многих возникающих при этом мучительных

РИС. 1.1. Достоинства языка Си.

проблемах. Язык Си предоставляет исключительные возможности для переноса программ. Компиляторы с данного языка реализованы почти на 40 типах вычислительных систем, начиная от- 8-разрядных микропроцессоров и кончая CRAY-1 одним из самых мощных в настоящее время суперкомпьютеров.

Си — мощный и гибкий язык (два излюбленных слова в литературе по вычислительной технике). Например, большая часть мощной и гибкой (!) операционной системы (ОС) UNIX написана на языке Си. Речь идет о компиляторах и интерпретаторах других языков, таких, как Фортран, АПЛ, Паскаль, Лисп, Лого и Бейсик. Поэтому, когда вы используете компилятор с Фортрана в системе UNIX, результирующая объектная программа в конечном счете получается с помощью некоторой программы, написанной на языке Си. Кроме того, программы, написанные на Си, используются для решения физических и технических проблем и даже для производства мультипликационных фильмов.

Си обладает рядом замечательных конструкций управления , обычно ассоциируемых с ассемблером. Если вы остановите свой выбор на Си, то сможете реализовывать свои программы с максимальной эффективностью.

Си — удобный язык . Он достаточно структурирован, чтобы поддерживать хороший стиль программирования, и вместе с тем не связывать вас смирительной рубашкой ограничений.

Кроме уже упомянутых достоинств язык Си имеет и некоторые другие. У него, безусловно, есть и ряд недостатков, но вместо того чтобы далее углубляться в это, давайте обсудим еще один вопрос.

БУДУЩЕЕ ЯЗЫКА СИ

Язык Си уже занимает доминирующее положение в мире мини-компьютеров, работающих под управлением ОС UNIX. Сейчас он распространяется на область

персональных ЭВМ. Многие фирмы, производящие программное обеспечение, все чаще обращаются к Си, как к удобному языку для реализации своих проектов: программ обработки текстов, составления крупноформатных таблиц, компиляторов и т. д., поскольку известно, что Си позволяет получить компактные и эффективные программы. Что еще важнее, эти программы могут быть легко модифицированы и адаптированы к новым моделям ЭВМ.

Другой причиной, способствующей проникновению Си в программное обеспечение персональных ЭВМ, является желание пользователей, работающих в системе UNIX, отлаживать свои программы дома. Поскольку уже созданы варианты компилятора с языка Си для некоторых моделей персональных ЭВМ, пользователи имеют возможность это делать.

По нашему мнению, то, что подходит для фирм и программистов с большим опытом работы на Си, хорошо и для остальных пользователей. Все больше и больше программистов останавливают свой выбор на языке Си, чтобы воспользоваться его преимуществами. Поэтому вам совсем не обязательно быть. профессиональным программистом, чтобы следовать их примеру.

Короче говоря, Си суждено стать одним из наиболее важных языков программирования

в80-90-е годы. Он уже применяется на мини-компьютерах и персональных ЭВМ. Он используется фирмами, производящими программное обеспечение, студентами, обучающимися программированию, и различными энтузиастами. И если вы хотите работать

всфере программотехники, то один из первых вопросов, на который вы должны будете отвечать "да", — "Умеете ли вы программировать на Си?".

ИСПОЛЬЗОВАНИЕ ЯЗЫКА СИ

Си — язык "компилируемого" типа. Не огорчайтесь, если это звучит для вас пока как непонятный набор слов; вы поймете, что это значит, когда мы опишем этапы процесса создания работающей Си-программы.

Если вы привыкли использовать какой-нибудь язык программирования компилируемого типа, например Паскаль или Фортран, вам будут понятны основные этапы "сборки" программ, написанных на Си. Но если ваш опыт основан на работе с такими языками

РИС. 1.2. Области применения языка Си.

интерпретируемого типа, как Бейсик и Лого, или у вас совсем нет соответствующей подготовки, то процесс сборки может показаться вам поначалу необычным. К счастью, мы можем объяснить вам все детали этого процесса, и вы увидите, что на самом деле он достаточно понятен и прост.

Чтобы дать вам первое представление о процессе создания программы, ниже приводится упрощенная схема того, что необходимо сделать — начиная от написания программы и кончая ее выполнением.

1.Используйте "редактор текстов" для создания программы на языке Си.

2.Попытайтесь осуществить трансляцию вашей программы с помощью удобного для вас компилятора. Он проведет проверку правильности вашей программы и, если обнаружит ошибки, выдаст сообщение об этом. В противном случае компилятор выполнит перевод программы в некоторый внутренний язык ЭВМ и поместит результат в новый файл.

3.Набрав имя этого нового файла на клавиатуре дисплея, вы можете запустить вашу программу.

В некоторых вычислительных системах второй этап может быть разбитым на два или три шага, но его суть от этого не изменится. Давайте рассмотрим теперь каждый этап более подробно.

Использование текстового редактора для подготовки программы

В отличие от языка Бейсик у Си нет собственного текстового редактора. В качестве него вы можете использовать любой из редакторов общего типа, имеющихся в вашей вычислительной системе. В операционной системе UNIX, например, это чаще всего редакторы ed, ex, edit, emacs или vi. На персональном компьютере это может быть ed, edlin, Wordstar, Volkswriter или любой другой из широкого набора редакторов. При работе с некоторыми из них вам необходимо будет определить конкретную версию редактора (путем задания соответствующих параметров). Например, при использовании редактора Wordstar необходимо ввести параметр N, указывающий на отсутствие документирования.

При работе с редактором от вас потребуется, во-первых, не ошибаться, набирая текст программы на пульте дисплея, и, во-вторых, выбирать имя для файла, в который будет помещена данная программа. Правила выбора имени выглядят довольно просто: оно должно быть допустимым именем в вашей вычислительной системе и должно оканчиваться символом с. Ниже приведены два правильно построенных имени: sort.c add.c

Первая часть имени файла должна напоминать вам, что программа делает. Вторая часть (символ .c ) указывает на то, что данный файл содержит текст программы, написанной на языке Си. В программировании принято называть часть имени, следующую за точкой, "расширением". Расширения используются для того, чтобы информировать вас и вычислительную систему о типе файла.

РИС. 1.3. Схема работы интерпретатора и компилятора.

Рассмотрим простой пример. Предположим, что при помощи редактора мы подготовили программу, которая приведена ниже, и поместили ее в файл с именем inform.с.

#include main() printf (" Символ .с используется как окончание имени файла с СИпрограммой. ");

Выше приведенный текст, который мы набрали на клавиатуре дисплея, обычно называется исходным кодом (текстом); он содержится в исходном файле. Важным моментом, который необходимо сразу отметить, является то, что наш исходный файл — это начальный пункт процесса программирования, а не его конец.

Исходные файлы и выполняемые файлы

Наша замечательная программа, несмотря на свою лаконичность и простоту, для компьютера является совершенно бессмысленным набором символов, так как он "не понимает" директив типа #include или printf . Он понимает только специальный язык, называемый машинным кодом, — набор последовательностей двоичных цифр, например, 10010101 и 01101001. Если мы хотим, чтобы компьютер выполнил программу, мы должны осуществить перевод (трансляцию) нашего кода (исходного) в ее код (машинный). В результате этих действий будет получен выполняемый файл, т. е. файл, содержащий весь необходимый машинный код, требующийся компьютеру для выполнения задания.

Если вышеприведенные рассуждения выглядят скучными и непонятными, не огорчайтесь. Дело в том, что процесс перевода удалось переложить на сам компьютер! "Умные" программы, называемые компиляторами, выполняют весь объем работы, связанный с этим переводом. Детали процесса зависят от особенностей конкретной системы. Ниже кратко описано несколько способов перевода.

Компиляция Си-программы в ОС UNIX

Компилятор с языка Си в ОС UNIX называется cc . Чтобы осуществить компиляцию нашей программы, на клавиатуре дисплея необходимо набрать только строку:

cc inform.c

Через несколько секунд интерпретатор команд ОС UNIX выдаст на экран дисплея символ "приглашение", информируя нас, что задание выполнено. (Вообще говоря, мы можем получить предупреждения и сообщения об ошибках в том случае, если программа была написана с ошибками, но давайте предположим, что все было сделано правильно.) Если мы используем директиву Is, осуществляющую вывод на экран списка имен файлов, мы обнаружим новый файл с именем a.out — файл с выполняемой программой, содержащий результат трансляции (или "компиляции") нашей исходной программы. Чтобы выполнить ее, мы должны только набрать на клавиатуре символы a.out и на экране дисплея появится фраза:

Символ .c используется как окончание имени файла с Си-программой.

РИС. 1.4. Создание Си-программы в среде ОС UNIX.

Программа-компилятор, называемая сс , объединяет несколько последовательных шагов задания в один. Это станет более очевидным, когда мы рассмотрим выполнение аналогичного процесса компиляции на персональном компьютере.

Компиляция Си-программы на IBM PC (компиляторы Microsoft С и Lattice С)

Описанное ниже разбиение процесса компиляции программы на последовательные шаги зависит как от операционной системы, так и от самого компилятора. Конкретный пример, который мы здесь рассматриваем, — это функционирование компилятора Microsoft С под управлением операционной системы PC DOS I.I (Компилятор Lattice С, лежащий в основе версии, реализованной фирмой Microsoft, запускается по аналогичным правилам, только вместо команд mс1 и mc2 необходимо использовать команды lс1 lс2.

Так же как и прежде, мы считаем, что исходная программа содержится в файле inform.с. Наша первая команда выглядит следующим образом:

mcl inform

(Компилятор интерпретирует строку символов inform как inform.с.) Если ошибок нет, то в результате будет получен промежуточный файл с именем inform.q. Затем мы набираем на клавиатуре следующую команду:

mc2 inform

в результате выполнения которой будет создан файл с именем inform.obj, содержащий так называемый "объектный код" (код на языке машины), соответствующий нашей исходной программе. (Объяснения приведены ниже.) После этого вводится команда

link с inform

по завершении которой создается файл inform.ехе. Наша цель достигнута — получен файл, содержащий выполняемую программу. Если мы затем введем команду

inform. ехе

или просто

inform

то наша программа начнет выполняться.

РИС. 1.5. Создание Си-программы при помощи компиляторов Microsoft С и Lattice С. На самом деле вы можете не знать, что происходит, когда вы пользуетесь

вышеописанной процедурой, но, если вам интересно, мы кратко опишем выполняемые при этом действия.

Что здесь нового? Во-первых, новым является то, что вводится файле именем inform.obj. Поскольку в нем содержится машинный код, непонятно, почему мы не остановились в этом месте? Ответом может служить то, что полная программа включает в себя части, которые мы не писали. Например, мы использовали команду printf, являющуюся программой, помещенной в Си-библиотеку. Вообще говоря, может возникать необходимость использовать в программе стандартные процедуры, помещенные в различные библиотеки. Эта потребность приводит к использованию второго нового понятия — команды link.