Продолжая использовать наш сайт, вы даете согласие на обработку файлов cookie, которые обеспечивают правильную работу сайта. Благодаря им мы улучшаем сайт!
Принять и закрыть

Читать, слущать книги онлайн бесплатно!

Электронная Литература.

Бесплатная онлайн библиотека.

Читать: Язык программирования Си для персонального компьютера - C. О. Бочков на бесплатной онлайн библиотеке Э-Лит


Помоги проекту - поделись книгой:

С.О. Бочков

Д.М. Субботин

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

Под общей редакцией канд. техн. наук, доцента П.И.Садчикова

ВВЕДЕНИЕ

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

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

Язык Си имеет ряд существенных особенностей, которые выделяют его среди других языков программирования. В значительной степени на формирование идеологии языка повлияла цель, которую ставили перед собой его создатели, — обеспечение системного программиста удобным инструментальным языком, который мог бы заменить язык ассемблера. В результате появился язык программирования высокого уровня, обеспечивающий необычайно легкий доступ к аппаратным средствам компьютера. Иногда Си называют языком программирования "среднего" уровня. С одной стороны, как и другие современные языки высокого уровня, язык Си поддерживает полный набор конструкций структурного программирования, модульность, блочную структуру программ, раздельную компиляцию. С другой стороны, язык Си имеет ряд низкоуровневых черт.

Перечислим некоторые особенности языка Си:

В языке Си реализованы некоторые операции низкого уровня (в частности, операции над битами). Некоторые из таких операций напрямую соответствуют машинным командам.

Базовые типы данных языка Си отражают те же объекты, с которыми приходится иметь дело в программе на языке ассемблера, — байты, машинные слова, символы, строки. Несмотря на наличие в языке Си развитых средств построения составных объектов (массивов и структур), в нем практически отсутствуют средства для работы с ними как с единым целым (нельзя, например, сложить две структуры).

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

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

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

Язык Си был разработан в США сотрудниками фирмы Bell Laboratories на рубеже 70-х годов. Примерно в то же время он был использован для разработки операционной системы UNIX. Вопросы повышения переносимости играли большую роль с самого начала разработки как языка Си, так и операционной системы UNIX, поэтому их распространение на новые компьютеры протекало очень быстро.

Первое описание языка Си было дано его авторами, Б. Керниганом и Д. Ритчи (имеется русский перевод — [1]). К сожалению, оно не было строгим и полным и содержало ряд моментов, допускающих неоднозначное толкование. Это привело к тому, что в последующем различные разработчики систем программирования трактовали язык Си по-разному. В течение долгого времени фактическим стандартом языка Си служила его реализация в седьмой версии операционной системы UNIX, однако заявления о совместимости некоторой системы программирования с реализацией языка Си в операционной системе UNIX, как правило, не означали точного соответствия. В настоящее время число только наиболее распространенных реализаций языка Си исчисляется десятками, и все они поддерживают, по существу, разные диалекты языка. Ситуация усугубляется тем, что обычно в документации особенности реализации языка освещаются неполно и нестрого.

Для исправления этой ситуации в 1983 г. при Американском Национальном Институте Стандартов (ANSI) был образован комитет по стандартизации языка Си. В октябре 1986 г. разработанный этим комитетом проект был опубликован для общественного обсуждения. В 1989 г. окончательный вариант проекта был утвержден в качестве стандарта ANSI. Подавляющее большинство используемых в настоящее время реализаций языка Си не поддерживает стандарт ANSI в полном объеме. Тем не менее, отчетливо просматривается тенденция к созданию новых реализаций языка Си, соответствующих стандарту ANSI.

В последние годы язык Си получил в СССР широкое распространение. Вышло немало книг, посвященных ему. Некоторые из них носят учебный характер [6, 8, 10, 11], в других рассматриваются конкретные реализации [4, 8, 13], третьи дают краткую, справочную информацию по языку [2, 3, 5, 9, 14] либо дают его сравнительную характеристику [7, 12].

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

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

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

В СССР наибольшее распространение на персональных компьютерах типа IBM PC/XT/AT и совместимых с ними получили система программирования фирмы Microsoft версий 4.0 и 5.0 (далее по тексту называемая СП MSC) и система программирования Турбо Си фирмы Borland International версий 1.5 и 2.0 (далее по тексту называемая СП ТО. Версия 4.0 СП MSC является наименее мощной реализацией языка Си из вышеперечисленных, поэтому описание базируется на ней. В тех случаях, когда имеются отличия для версии 5.0 СП MSC либо для СП ТС, в тексте делаются соответствующие отступления.

Описание библиотечных функций языка Си затрудняется тем, что расхождений в составе библиотек в различных системах программирования (даже в пределах разных версии одной и той же системы программирования) значительно больше, чем отличий в реализации языка. В данной книге описаны стандартные библиотечные функции версии 4.0 СП MSC и версии 1.5 и 2.0 СП ТС.

Материал книги организован следующим образом:

В разделе 1 "Элементы языка Си" описываются алфавит, лексические конструкции и правила языка Си.

В разделе 2 "Структура программы" обсуждаются структура и компоненты Си-программы, организация исходных файлов и правила доступа к программным объектам.

В разделе 3 "Объявления" описывается, каким образом объявлять переменные, функции, а также типы, определяемые пользователем. Помимо простых переменных, язык Си позволяет объявлять указатели и составные объекты—массивы, структуры, объединения.

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

В разделе 5 "Операторы" описываются управляющие конструкции.

В разделе 6 "Функции" обсуждаются правила построения и вызова модулей, которые в языке Си называются функциями. В частности, в этом разделе объясняется, как определять, объявлять и вызывать функции, как описывать параметры функции и возвращаемые значения.

В разделе 7 "Директивы препроцессора и указания компилятору" описываются директивы, распознаваемые препроцессором языка Си. Препроцессор представляет собой макропроцессор, автоматически вызываемый в качестве нулевого прохода компилятора языка Си.

В разделе 8 описаны модели памяти для процессора с сегментной архитектурой памяти (типа Intel 8086/8088) и правила работы с ними в программах, написанных на языке Си.

Соглашения о нотации

В книге приняты следующие соглашения о нотации:

Обозначение Смысл
Угловые скобки Угловые скобки выделяют нетерминальные символы в синтаксических конструкциях.
  Например, в записи
  goto <имя>
  <имя> представлено в угловых скобках, чтобы обратить внимание на то, что определяется общая форма оператора перехода goto. В своей программе пользователь подставит конкретный идентификатор вместо нетерминального символа <имя>
Квадратные скобки Квадратные скобки, ограничивающие синтаксическую конструкцию, означают ее необязательность. Например, в операторе возврата return выражение необязательно: return [<выражение>];
Многоточие Многоточие может быть вертикальным или горизонтальным. В следующем примере вертикальные многоточия означают, что нуль или более объявлений может следовать перед одним или более операторами внутри фигурных скобок.
  {
  [<объявление>]
  .
  .
  .
  <оператор>
  [<оператор>]
  .
  .
  .
  }
  Вертикальные многоточия также используются в примерах программ для обозначения части программы, которая пропущена.
  Горизонтальное многоточие, следующее после некоторой синтаксической конструкции, обозначает последовательность конструкций той же самой формы, что и предшествующая многоточию конструкция. Например, запись
  ={<выражение>[,<выражение>]…} означает, что одно или более выражений, разделенных запятыми, может появиться между фигурными скобками. В целях экономии места в некоторых случаях вместо вертикальных многоточий используются горизонтальные.

ЧАСТЬ 1 ОПИСАНИЕ ЯЗЫКА СИ

ЭЛЕМЕНТЫ ЯЗЫКА СИ

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

– алфавит;

– константы;

– идентификаторы;

– ключевые слова;

– комментарии.

Компилятор языка Си воспринимает исходный файл, содержащий программу на языке Си, как последовательность текстовых строк. Каждая строка завершена символом новой строки. Этот символ вставляется текстовым редактором при нажатии клавиши ENTER (ВВОД).

Компилятор языка Си последовательно считывает строки программы и разбивает каждую из считанных строк на группы символов, называемые лексемами. Лексема—это единица текста программы, которая имеет самостоятельный смысл для компилятора языка Си и которая не содержит в себе других лексем. Никакие лексемы, кроме символьных строк, не могут продолжаться на последующих строках текста программы. Знаки операций, константы, идентификаторы и ключевые слова, описанные в этом разделе, являются примерами лексем. Разделители, например квадратные скобки [], фигурные скобки {}, круглые скобки (), угловые скобки < > и запятые, также являются лексемами. Внутри идентификаторов, ключевых слов, а также знаков операций, состоящих из нескольких символов, пробельные символы недопустимы.

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

i+++j

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

Алфавит

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

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

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

В последующих разделах описываются символы из множества символов языка Си и объясняются правила их использования.

Буквы и цифры

Множество символов языка Си включает прописные и строчные буквы латинского алфавита и арабские цифры:

прописные латинские буквы: ABCDEFGHIJKLMNOPQRSTUVWXYZ;

строчные латинские буквы: abcdefghijkimnopqrstuvwxyz;

десятичные цифры: 0123456789.

Буквы и цифры используются при формировании констант, идентификаторов и ключевых слов (эти конструкции описаны ниже).

Компилятор языка Си рассматривает одну и ту же прописную и строчную буквы как различные символы.

Пробельные символы

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

Символ CONTROL-Z (шестнадцатеричный код 1А) рассматривается как индикатор конца файла. Он автоматически вставляется текстовым редактором при создании файла в его конец. Компилятор языка Си завершает обработку файла с исходным текстом программы при обнаружении символа CONTROL-Z.

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

Комментарии компилятор языка Си также рассматривает как пробельные символы.

Разделители

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

Таблица 1.1.

Символ Наименование Символ Наименование
, Запятая ! Восклицательный знак
. Точка | Вертикальная черта
; Точка с запятой / Наклонная черта вправо (слэш)
: Двоеточие \ Наклонная черта влево(обратный слэш)
? Знак вопроса ~ Тильда
Одиночная кавычка (апостроф) _ Подчеркивание
( Левая круглая скобка # Знак номера
) Правая круглая скобка % Процент
{ Левая фигурная скобка & Амперсанд
} Правая фигурная скобка ^ Стрелка вверх
< Знак "меньше" - Знак минус
> Знак "больше" = Знак равенства
[ Левая квадратная скобка + Знак плюс
] Правая квадратная скобка * Знак умножения (звездочка)

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

Специальные символы

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

В СП ТС шестнадцатеричное значение байта может задаваться не только как \х, но и как \Х.

В СП ТС, помимо перечисленных специальных символов, имеется еще один: \?—знак вопроса (код Ox3F). Он введен в состав языка Си для совместимости со стандартом ANSI на язык Си. Стандарт ANSI предусматривает использование пары знаков вопроса (??) в качестве признака последовательности, представляющей какой-либо символ, который может не иметь представления на клавиатуре терминала. Если же необходимо просто записать подряд два знака вопроса (например, в символьной строке), следует записать их так: ?\?. В СП ТС, однако, не реализованы последовательности, начинающиеся знаками ??, поэтому использование специального символа \? необязательно.

Таблица 1.2.

Специальный символ Шестнадцатеричное значение в коде ASCII Наименование
\n ОА Новая строка
\t 09 Горизонтальная табуляция
\v Вертикальная табуляция
\b 08 Забой
OD Возврат каретки
\f ОС Новая страница
07 Звуковой сигнал
\’ Апостроф
\" 22 Двойная кавычка
\\ 5C Обратный слэш
\ddd   Байтовое значение в восьмеричном представлении
\xdd   Байтовое значение в шестнадцатеричном представлении

Примечание. При работе с текстовым редактором ввод каждой строки завершается нажатием клавиши ENTER (ВВОД). Фактически при этом в текст вставляются два символа: возврат каретки и новая строка (с шестнадцатеричными значениями 0D и 0А в коде ASCII). Однако стандартные библиотечные функции ввода и вывода текстовой информации рассматривают эту пару символов как один символ — символ новой строки с шестнадцатеричным значением 0А. Этот символ представляется в символьных константах и символьных строках как \n. При чтении текстовой строки стандартные библиотечные функции заменяют упомянутую пару символов единственным символом новой строки, а при записи символа новой строки добавляют перед ним символ возврат каретки.

Если обратный слэш предшествует символу, не входящему в приведенный список, то обратный слэш игнорируется, а символ представляется обычным образом. Например, сочетание \h в строковой или символьной константе представляет символ h.

Конструкция \ddd позволяет задать произвольное байтовое значение как последовательность от одной до трёх восьмеричных цифр. Конструкция \xdd позволяет задать произвольное байтовое значение как последовательность от одной до двух шестнадцатеричных цифр, а для версии 5.0 СП MSC – до трех шестнадцатеричных цифр. Например, символ забой в коде ASCII может быть задан как \010 или \х08. Нулевой код может быть задан как \0 или \х0. В восьмеричном представлении байта могут быть заданы только восьмеричные цифры, причем по крайней мере одна цифра должна быть задана. Например, символ забой может быть задан как \10. Аналогично, в шестнадцатеричном представлении байта должна быть задана по крайней мере одна шестнадцатеричная цифра. Так, шестнадцатеричное представление символа забой может быть задано и как \х08, и как \х8.

Примечание. Если восьмеричное или шестнадцатеричное представление байта используется в составе строки, то рекомендуется полностью задавать все цифры представления. В противном случае, если символ, непосредственно следующий за представлением, случайно окажется восьмеричной или шестнадцатеричной цифрой, он будет интерпретироваться как часть этого представления. Например, в версии 4.0 СП MSC строка \х7Веll при выводе на печать будет выглядеть как {ell, поскольку \х7В проинтерпретируется как код левой фигурной скобки. Строка \х07Ве11 будет правильным представлением кода звукового сигнала с последующим словом Bell.

В СП ТС разбор конструкций, представляющих байтовое значение, реализован не вполне корректно; так, запись "\1234" считается ошибочной, хотя она представляет восьмеричное значение 123 и символ '4'.

Специальные символы позволяют посылать неграфические управляющие последовательности на внешние устройства. Например, код \033 (символ ESC в коде ASCII) часто используется как первый символ команд управления терминалом и принтером.

Помимо специальных символов, обратный слэш (\) используется также в качестве признака продолжения символьных строк и препроцессорных макроопределений. Если символ новой строки непосредственно следует за обратным слэшем, то комбинация "обратный слэш—символ новой строки" игнорируется и следующая строка рассматривается как продолжение предыдущей строки.

Операции

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

В таблице 1.3. представлен список операций. Операции должны использоваться точно так, как они представлены в таблице,' без пробельных символов между символами в тех операциях, которые представлены несколькими символами.

Операция sizeof не включена в эту таблицу, поскольку задается ключевым словом, а не символом.

Таблица 1.3.

Операция Наименование Операция Наименование
! Логическое НЕ ^ Поразрядное исключающее ИЛИ
~ Обратный код && Логическое И
+ Сложение; унарный плюс || Логическое ИЛИ
- Вычитание; унарный минус ?: Условная операция
* Умножение; косвенная адресация ++ Инкремент
/ Деление -- Декремент
% Остаток от деления = Простое присваивание
<< Сдвиг влево += Присваивание со сложением
>> Сдвиг вправо -= Присваивание с вычитанием
< Меньше *= Присваивание с умножением
<= Меньше или равно /= Присваивание с делением
> Больше %= Присваивание с остатком от деления
>= Больше или равно >>= Присваивание со сдвигом вправо
== Равно <<= Присваивание со сдвигом влево
!= Не равно &= Присваивание с поразрядным И
& Поразрядное И; адресация |= Присваивание с поразрядным включающим ИЛИ
| Поразрядное включающее ИЛИ ^= Присваивание с поразрядным исключающим ИЛИ
, Последовательное выполнение (запятая)    

Примечание. Условная операция ?: является не двухсимвольной, а тернарной (трехоперандной) операцией. Она имеет следующий формат: <операнд1> ? <операнд2> : <операнд3>

Константы

Константа — это число, символ или строка символов. Константы используются в программе для задания постоянных величин. В языке Си различают четыре типа констант: целые, с плавающей точкой, символьные константы и символьные строки.

Целые константы

Целая константа — это десятичное, восьмеричное или шестнадцатеричное число, которое представляет целое значение. Десятичная константа имеет следующий формат представления:

<цифры>

<цифры> — последовательность из одной или более десятичных цифр от 0 до 9.

Восьмеричная константа имеет следующий формат представления:



Поделиться книгой:

На главную
Назад