Синтаксис и семантика языка программирования. Описание синтаксиса языков программирования Что такое синтаксис в программировании

Любой язык программирования состоит из трех частей:

● Алфавит.

● Синтаксис.

● Семантика

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

  1. Алфавит языка Си

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

1. Латинские строчные и прописные буквы: a, b, …, z и A, B, …, Z

2. Цифры: 0, 1, …, 9

3. Символ подчеркивания: _

4. Пробел (код 32)

5. Специальные символы: +, -, * и др.

6. Составные символы, воспринимаемые как один символ: <=, >= и др.

7. В комментариях и строковых константах допустимо использование кириллицы.

  1. Понятие о типе

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

● Тип определяет множество значений, которые может принимать данное.

● Тип определяет перечень операций, которые можно применять к данным.

● Каждое значение может относиться только к одному типу.

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

  1. Система типов языка Си Система типов языка Си

В соответствии с одной из систем классификации все типы языка Си делят на следующие четыре категории:

void ,

● скалярные,

● агрегатные.

Остановимся вначале кратко на каждой из четырех категорий типов.

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

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

● В качестве типа значения, возвращаемого функцией. Если из заголовка функции следует, что типом значения, которое она возвращает, является void , то это означает, что функция не возвращает значения. В этом случае она может использоваться подобно процедуре такого языка, как Паскаль.

● Зарезервированное слово void в языке используется для указания на то обстоятельство, что функция не имеет параметров.

В качестве примера применения типа void может служить объявление библиотечной функции clrscr(), которая не имеет возвращаемого значения и не принимает параметров:

void clrscr(void );

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

В стандарте языка С99 к скалярным типам относятся следующие виды типов:

● арифметические,

● логический,

● указатели,

● перечисления.

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

Арифметические типы составляют большую группу типов. В ней можно выделить три части:

● вещественные,

● комплексные.

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

Каждая из оставшихся разновидностей арифметических типов включает в себя достаточно большое количество отдельных типов. К числу основных (базовых) арифметических типов относят следующие типы. Для целочисленных типов базовыми типами считаются типы char иint , а для вещественных типов –float иdouble . Обращает на себя внимание тот факт, что символьный тип (типchar ) в языке Си рассматривается как разновидность целочисленного типа. Это обстоятельство можно рассматривать как проявление ослабленной типизации, которое присуще языку Си.

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

signed (знаковый),

unsigned (беззнаковый),

long (длинный),

short (короткий).

С учетом модификаторов можно написать 17 разновидностей арифметических типов.

Основным целочисленным типом в языке Си является тип int . Это аппаратно-зависимый тип. Размер, который занимает данное, относящееся к этому типу, зависит от размера машинного слова конкретной среды программирования.

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

Перечислимый тип является взаимосвязанным набором целочисленных констант. Перечислимые типы будут рассматриваться во второй части пособия.

● массивы,

● структуры,

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

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

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

Языки программирования относятся к группе формальных языков, для которых в отличие от естественных языков однозначно определены синтаксис и семантика. Описание синтаксиса языка включает определение алфавита и правил построения различных конструкций языка из символов алфавита и более простых конструкций. Для этого обычно используют форму Бэкуса-Наура (БНФ) или синтаксические диаграммы . Описание конструкции в БНФ состоит из символов алфавита языка, названий более простых конструкций и двух специальных знаков:

· «::=» - читается как «может быть заменено на»,

· «|» - читается как «или».

При этом символы алфавита языка, которые часто называют терминальными символами или терминалами, записывают в неизменном виде. Названия конструкций языка (нетерминальные символы или нетерминалы), определяемых через некоторые другие символы, при записи заключают в угловые скобки («< », « >»).

Пример БНФ

Правила построения конструкции <Целое>, записанные в

БНФ, могут выглядеть следующим образом:

<Целое> ::= <3нак> <Целое без знака> | <Целое без знака>

<Целое без знака> ::= <Целое без знака> <Цифра> | <Цифра>

<Цифра> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

<3нак> ::= + | -

Для отображения того, что конструкция <Целое без знака> может включать неограниченное количество цифр, использовано правило с левосторонней рекурсией. Многократное применение этого правила позволяет построить целое число с любым количеством цифр.

Синтаксические диаграммы отображают правила построения конструкций в более наглядной форме. На такой диаграмме символы алфавита изображают блоками в овальных рамках, названия конструкций – в прямоугольных, а правила построения конструкций - в виде линий со стрелками на концах. При этом, если линия входит в блок, то в описываемую конструкцию должен входить соответствующий символ. Разветвление линии означает, что при построении конструкции возможны варианты. На рис. 2.1 представлена синтаксическая диаграмма, иллюстрирующая первые два правила описания конструкции <Целое>. Из диаграммы видно, что целое число может быть записано со знаком или без и включать произвольное количество цифр.



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

Алфавит языка программирования Borland Pascal 7.0 включает:

1. строчные, прописные буквы латинского алфавита (a..z, A..Z) и знак подчеркивания (_), который также во многих случаях считается буквой (строчные и прописные буквы не различаются);

2. цифры (0...9);

3. специальные знаки, состоящие из одного и двух символов:

. ,+ - * / = : < > { } () ^ @ $ #<> <= >= := (* *)

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

Из символов алфавита в соответствии с правилами синтаксиса строят различные конструкции. Простейшей из них является конструкция <Идентификатор>.

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

В Borland Pascal идентификатор представляет собой последовательность букв латинского алфавита (включая символ подчеркивания) и цифр, которая обязательно начинается с буквы.

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

Структура программы

Программа на Borland Pascal состоит из трех частей: заголовка, раздела описаний и раздела операторов.

  • Заголовок программы не является обязательным, он состоит из служебного слова program и идентификатора - имени программы.
  • Раздел описаний содержит описания всех используемых программой ресурсов (полей данных, подпрограмм и т.д.).
  • Раздел операторов заключается в, так называемые, операторные скобки begin ...end и заканчивается точкой. Между операторными скобками записывают управляющие операторы программы, которые разделяют специальным знаком – точкой с запятой «;». Если точка с запятой стоит перед end , то считается, что после точки с запятой стоит «пустой» оператор.
  • В тексте программы возможны комментарии, которые помещают в фигурные скобки.

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

Program example; {заголовок программы}

{раздел описаний}

Uses crt;

Var a,b:integer; {объявление переменных}

{раздел операторов}

Write ("Введите два натуральных числа:"); {запрашиваем ввод данных}

Readln(a,b); {вводим значения}

while a<>b do {цикл-пока а<>b}

if a>b then a:=a-b {если a>b, тогда a:=a-b}

else b:=b-a; {иначе b:=b-a}

Writeln(‘Hauбoльшuй общий делитель равен ’,a); {выводим результат}

End. {конец программы}

Программа названа «example». Раздел описаний в данном случае включает только описание переменных (см. параграф 2.3). Раздел операторов содержит операторы ввода исходных данных, вычислений и вывода результатов. Начнем рассмотрение особенностей программирования на языке Borland Pascal с проблемы описания данных.

Форма Бэкуса-Наура (БНФ)

Форма Бэкуса-Наура (БНФ) была впервые применена при описании Алгола-60. БНФ совпадает по сути с нотацией КС-грамматик, отличаясь лишь обозначениями. Предусмотрены следующие метасимволы:

<> - служат для выделения нетерминалов - понятий языка. | - «или». Разделяет альтернативные правые части правил. - «есть по определению». Заменяет стрелку, используемую при записи продукций КС-грамматик.

Терминальные символы записываются как есть, никаких специальных способов их выделения не предусмотрено. Вот пример определений на БНФ, взятый из спецификации Алгола-60 - «Модифицированного сообщения»:

<простое арифметическое выражение> ::= <терм> 1 Окак операции типа сложения> <терм> | <простое арифметическое выражение> <знак операции типа сложения> <терм> <знак операции типа сложения> ::= + | -

Как видим, для выражения повторений используется рекурсия, причем повсеместно - левая. БНФ использована Н. Виртом при описании языка Паскаль. Хотя в нотацию были добавлены метаскобки {и}, обозначающие повторение, применены они лишь в отдельных случаях, в то время как, например, грамматика выражений леворекурсивна.

Синтаксические диаграммы

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

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

Таким образом, синтаксические диаграммы могут служить не только для порождения, но и для распознавания автоматных языков. Диаграммы стали популярны после выхода книги К. Йенсен и Н. Вирта «Паскаль». Они использованы в первой ее части - «Руководстве» - компактном учебнике языка. На рис. 3.1 показана одна из имеющихся там диаграмм.

Расширенная форма Бэкуса-Наура

Как уже говорилось, отсутствие в нотации формальных грамматик (и БНФ) средств явного задания повторений создает ряд трудностей. Во-первых, определения оказываются сложными для понимания, недостаточно наглядными из-за обилия рекурсий. Во-вторых, возникают проблемы с тем, что грамматики, дающие подходя- щие семантические деревья, оказываются леворекурсивными. При описании Модулы-2 и Оберона Н. Вирт использовал расширенную Бэкуса-Наура форму (РБНФ). Главные модификации касаются введения скобок { и} для повторений, а [ и ] - для обозначения необязательного вхождения цепочек терминалов и нетерминалов в правые части правил. Соглашения относительно обозначений терминалов и нетерминалов также изменены, что не столь принципиально. В дальнейшем мы будем пользоваться именно РБНФ. Вот как она определяется в спецификации Оберона-2: Варианты разделяются знаком |. Квадратные скобки [ и ] означают необязательность записанного внутри них выражения, а фигурные скобки { и } означают его повторение (возможно, 0 раз). Нетерминальные символы начинаются с заглавной буквы (например, Оператор). Терминальные символы или начинаются малой буквой (например, идент), или записываются целиком заглавными буквами (например, begin), или заключаются в кавычки (например, ":="). К этому следует добавить, что в роли знака «есть по определению» в РБНФ используется «=», а каждое правило заканчивается точкой. Вот так может быть определен синтаксис идентификатора (имени) с помощью РБНФ:

Имя = Буква { Буква | Цифра }.

Являясь метаязыком, РБНФ должна быть пригодна для описания языков, имеющих практический интерес. В том числе с помощью РБНФ может быть определен и синтаксис самой РБНФ:

Синтаксис = { Правило }. Правило = Имя "=" Выражение Выражение = Вариант { "I" Вариант }. Вариант - Элемент { Элемент }. Элемент = Имя | Цепочка | "{" Выражение "}" | "[" Выражение "]" | "{" Выражение "}". Цепочка = """ { символ) """ | """{ символ } """.

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

Описания синтаксиса языков семейства Си

Си (англ. C) - стандартизированный процедурный язык программирования, разработанный в начале 1970-х годов сотрудниками Bell Labs Кеном Томпсоном и Денисом Ритчи как развитие языка Би. Си был создан для использования в операционной системе UNIX. С тех пор он был портирован на многие другие операционные системы и стал одним из самых используемых языков программирования. Си ценят за его эффективность; он является самым популярным языком для создания системного программного обеспечения. Его также часто используют для создания прикладных программ. Несмотря на то, что Си не разрабатывался для новичков, он активно используется для обучения программированию. В дальнейшем синтаксис языка Си стал основой для многих других языков. Для языка Си характерны лаконичность, современный набор конструкций управления потоком выполнения, структур данных и обширный набор операций.

В знаменитой книге Б. Кернигана и Д. Ритчи описание синтаксиса языка Си дано в нотации, которая эквивалентна БНФ, но использует другие соглашения об обозначениях терминалов и нетерминалов, альтернативных правых частей правил, необязательных конструкций. Нетерминалы записываются курсивом, терминалы - прямым шрифтом. Альтернативные части правил выписываются в столбик по одному в строке или помечаются словами «one of» (один из). Необязательные части сопровождаются подстрочным индексом «opt (от optional) - необязательный; «необ» - в некоторых русских пере- водах). Левая часть правила записывается отдельной строкой с отступом влево. Вот пример определений конструкций языка Си:

Составной оператор {список описанийopt список операторовopt } список операторов оператор оператор список операторов

Как видим, из-за отсутствия явного способа выражения повторений, определе- ния изобилуют рекурсией. Аналогичная нотация с минимальными изменениями использована для описа- ния синтаксиса языков-потомков Си: Си++, Ява, Си#. Вот выдержка из стандарта ЕСМА-334 на язык Си#:

Block: {Statement-listopt} statement-list: statement statement-list statement

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

Особенности языка Си

  1. Имеет простую языковую базу, из которой вынесены в библиотеки многие существенные возможности, вроде математических функций или функций управления файлами;
  2. Имеет ориентацию на процедурное программирование, обеспечивающую удобство применения структурного стиля программирования;
  3. Имеет систему типов, предохраняющую от бессмысленных операций;
  4. Использование препроцессора для, например, определения макросов и включения файлов с исходным кодом;
  5. Имеет непосредственный доступ к памяти компьютера через использование указателей;
  6. Имеет минимальное число ключевых слов;
  7. Передача параметров в функцию по значению, а не по ссылке (при этом передача по ссылке выполняется с помощью указателей);
  8. Указатели на функции и статические переменные;
  9. Имеет области действия имён;
  10. Записи - определяемые пользователем собирательные типы данных (структуры), которыми можно манипулировать как одним целым;

Пример программы "Hello world " на Си

main() { printf("Hello, World!\n"); } #include int main() { printf("Hello, World!\n"); return 0; }

Описания синтаксиса языка Ада

Ада(Ada) - язык программирования, созданный в 1979-1980 годах в результате проекта, предпринятого Министерством обороны США с целью разработать единый язык программирования для встраиваемых систем (то есть систем управления автоматизированными комплексами, работающими в реальном времени). Имелись в виду, прежде всего, бортовые системы управления военными объектами (кораблями, самолётами, танками, ракетами, снарядами и т. п.). Перед разработчиками не стояло задачи создать универсальный язык, поэтому решения, принятые авторами Ады, нужно воспринимать в контексте особенностей выбранной предметной области. Язык назван в честь Ады Лавлэйс.Исследования, выполненные в начале и середине 1970-х годов, показали, что если Пентагон будет использовать единый язык программирования для решения всех своих задач вместо примерно 450 языков и их диалектов, то появится возможность получить огромную экономию средств (около 24 млрд долл. за период с 1983-го по 1999 год).Язык Ада основан на идеях структурного программирования и обеспечивает поддержку разработки сложных многомодульных программ, высокую степень машино-независимости и переносимости.При проектировании языка в первую очередь внимание акцентировалось на надежности и эффективности - язык создавался специально для разработки больших программных комплексов реального времени для встроенных систем, к которым предъявляются высокие требования надежности.

Особенности

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

Осбенности синтаксиса

  1. Программы модульные, механизм контроля импорта-экспорта описаний между модулями включает две разные директивы: одну для подключения другого модуля (with), другую - для импорта его описаний (use). Также существует возможность переименовать модуль при импорте (rename) - этот вариант позволяет использовать для обозначения пакета более удобные программисту идентификаторы.
  2. Пакеты (один из типов модулей) могут содержать заголовок и личную часть - то, что содержится в ней, не экспортируется и другим модулям недоступно.
  3. Поддерживается механизм обобщённых (настраиваемых) модулей: пакетов, процедур и функций, позволяющих описывать обобщённые алгоритмы обработки данных без указания конкретного типа.
  4. Развитая система типов, как встроенных, так и порождаемых программистом. Есть множество способов создания новых типов, язык поддерживает два разных понятия: «подтип» и «производный тип». Переменные типа и подтипа совместимы, переменные типа и его производного типа - нет.
  5. Развитые средства обращения к процедурам и функциям: поддерживаются входные и выходные параметры, передача фактических параметров в произвольном порядке с указанием имён формальных, параметры со значениями по умолчанию.
  6. Поддерживается переопределение процедур, функций и операторов - создание нескольких вариантов процедуры, функции или оператора с одним и тем же именем, но различными сигнатурами (типами и количеством параметров).
  7. Встроенные в язык конструкции поддержки параллельного программирования: поддерживаются понятия «задача» (параллельно выполняемый фрагмент программы), «вход задачи» (средство синхронизации и коммуникации параллельно выполняющихся задач), поддерживается механизм «рандеву» (протокол взаимодействия параллельно выполняемых задач через вход одной из них), имеется оператор выбора SELECT для организации условного межпотокового взаимодействия (выбора параллельной задачи, с которой следует взаимодействовать, в зависимости от готовности к рандеву и некоторых других условий).

Контекстно-свободные грамматики языков Aда-83 и Ада-95 определены с помощью варианта БНФ, в который добавлены обозначения повторений и необязательных частей. Названия нетерминалов записываются обычным шрифтом с использованием знака подчеркивания, если название составное, а зарезервированные слова - жирным шрифтом. Поскольку ни квадратные, ни фигурные скобки в Аде не используются, как не используется и знак «|» (все это метасимволы), никакого специального обозначения для терминалов не предусмотрено. Определение синтаксиса оператора if, взятое из стандарта Ада-95, выглядит так:

If_statement::= if condition then sequence_of_statements {elsif condition then sequence_of_statements} end if;

Интересная и полезная особенность: синтаксические правила структурных конструкций представлены в виде, соответствующем их рекомендованному форматированию в программах (разделение на строки, отступы).

Для удовлетворения требованиям надёжности язык построен таким образом, чтобы как можно большее количество ошибок обнаруживалось на этапе компиляции. Кроме того, одним из требований при разработке языка была максимально лёгкая читаемость текстов программ, даже в ущерб лёгкости написания. Результатом такого подхода стал несколько «тяжеловесный» синтаксис и множество ограничений, отсутствующих в наиболее распространённых промышленных языках (С и C++) и часто воспринимаемых профессиональными программистами как избыточные, например, та же строгая типизация. Это привело к формированию представления об Аде как о сложном, малопонятном и неудобном в использовании языке.

Пример программы "Hellow world" на Аде

with Ada.Text_IO; procedure Hello is use Ada.Text_IO; begin Put_Line("Hello, world!"); end Hello;

Определение синтаксиса Кобола и ПЛ/1

Кобол (COBOL, COmmon Business Oriented Language ), язык программирования третьего поколения (первая версия в 1959), предназначенный, в первую очередь, для разработки бизнес-приложений.Разработчиком первого единого стандарта Кобола являлась Грейс Хоппер (бабушка Кобола). К 1997 году активно использовалось около 240 миллиардов строк кода на Коболе. Около 90 % финансовых транзакций в мире обрабатывается кодом на Коболе, и 75 % коммерческой обработки данных написано на Коболе. Общая стоимость используемого в настоящее время коболовского кода оценивается в 2 триллиона долларов США. До сих пор ежегодно пишутся миллиарды новых строк кода на Коболе.

Своеобразная система обозначений, являющаяся примером ранних нотаций, была применена при описании языков Кобол и ПЛ/1. Вот пример - определение формата глагола MOVE в Коболе:


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

Особенности языка Кобол

  1. Грамоздкость, многословность
  2. Хооршие, современные средства для работы со структурами данных и файлами, что обеспечило ему долгую жизнь в бизнес-приложениях(по крайней мере, в США).
  3. Обеспечивает наглядную и достаточно компактную запись алгоритмов в форме, независимой от конкретных машин, предназначенных для решения задач.
  4. Содержит большое колличество команд,которые представляют собой сложные комплексы типовых подпрограмм, обеспечивающих решение планово-экономических задач.

Пример программы "Hello world " на Коболе

IDENTIFICATION DIVISION. PROGRAM-ID. HELLO-WORLD. * ENVIRONMENT DIVISION. * DATA DIVISION. * PROCEDURE DIVISION. PARA-1. DISPLAY "Hello, world.". * EXIT PROGRAM.

ПЛ/1 -(PL/I, Programming Language I - «Язык программирования номер один») - разработанный в 1964 году язык программирования, созданный для научных, инженерных и бизнес-ориентированных вычислений. Он содержит такой широкий набор синтаксических конструкций и встроенных функций, что, вероятно, не существует ни одного компилятора, поддерживающего все возможности языка ПЛ/1. ПЛ/1 поддерживает рекурсию и структурное программирование, и его основная область применения - обработка данных

Основные свойства ПЛ/1

  1. Свободный синтаксис
  2. Ключевые слова и идентификаторы нечувствительны к регистру
  3. По умолчанию (в классических мэйнфреймовских версиях - всегда) передача параметров по ссылке
  4. Поддержка сложных структур с объединениями (в терминологии языка Паскаль - записи с вариантами)
  5. Чрезвычайно развитая система встроенных типов данных, при этом возможность неявных преобразований между большинством из них
  6. Несколько видов динамического выделения памяти
  7. Очень обобщенные операторы со многими вариантами синтаксиса
  8. Строго определённая семантика управляющих конструкций
  9. Операции с массивами
  10. Развитый механизм исключительных состояний
  11. Поддержка на уровне языка мультизадачности и асинхронного ввода-вывода
  12. Поддержка на уровне языка сложных методов доступа для ввода-вывода
  13. Очень развитый препроцессор, фактически сам являющийся подмножеством ПЛ/1

Пример программы "Hello world" на ПЛ/1

Test: procedure options(main); declare My_String char(20) varying initialize("Hello, world!"); put skip list(My_String); end Test;

Алфавит языка

Первоначальный алфавит ПЛ/1 включал 60 символов:

$ @ # A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 = + - * / () , . " % ; : ¬ & | > < _ ? пробел

Была предусмотрена возможность работы и с более ограниченным 48-символьным алфавитом, в который не входили:

@ # ; : ¬ & | > < _ ? -

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

Литература

  1. Свердлов С.З. Языки программирования и методы трансляции: Учебное пособие. - СПб.: Питер, 2007. - 638 с.: ил.

Во всяком языке программирования определены способы организации данных и способы организации действий над данными. Кроме того, существует понятие «элементы языка», включающее в себя множество символов (алфавит), лексемы и другие изобразительные средства языка программирования. Несмотря на разнообразие указанных языков, их изучение происходит приблизительно по одной схеме. Это связано с общностью структуры различных языков программирования высокого уровня, которая схематически отражена на рис. 1.12.

Рис. 1.12. Структуры языка программирования высокого уровня

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

Язык программирования имеет три основные составляющие: алфавит, синтаксис и семантику.

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

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

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

Для описания синтаксиса языка программирования тоже нужен какой-то язык. В этом случае речь идет о метаязыке («надъязыке»). Метаязык – язык, используемый для описания других языков. Наиболее распространенными метаязыками являются металингвистические формулы Бекуса-Наура (язык БНФ) и синтаксические диаграммы. В дальнейшем мы чаще всего будем использовать язык синтаксических диаграмм. Он более нагляден, легче воспринимается. В некоторых случаях для удобства мы будем обращаться к отдельным элементам языка БНФ.

В БНФ всякое синтаксическое понятие описывается в виде формулы, состоящей из правой и левой части, соединенных знаком::=, смысл которого эквивалентен словам «по определению есть». Слева от знака::= записывается имя определяемого понятия (метапеременная), которое заключается в угловые скобки < >, а в правой части записывается формула или диаграмма, определяющая все множество значений, которые может принимать метапеременная.

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

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

В записях метаформул приняты определенные соглашения. Например, формула БНФ, определяющая понятие «двоичная цифра», выглядит следующим образом:

<двоичная цифра>::=0|1.

Значок | эквивалентен слову «или». Это определение можно представить на языке синтаксических диаграмм (рис. 1.13).

Рис. 1.13. Понятие «двоичная цифра» на языке синтаксических диаграмм

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

Понятие «двоичный код» как непустую последовательность двоичных цифр БНФ описывает так:

<двоичный код> ::= <двоичная цифра> | <двоичный код> <двоичная цифра>.

Определение, в котором некоторое понятие определяется само через себя, называется рекурсивным. Рекурсивные определения характерны для БНФ.

Синтаксическая диаграмма двоичного кода представлена на рис. 1.14.

Рис. 1.14. Синтаксическая диаграмма двоичного кода

Возвратная стрелка обозначает возможность многократного повторения. Очевидно, что диаграмма более наглядна, чем БНФ.

Синтаксические определения языка программирования состоят из имени, определяемого в настоящий момент и не определенного где-либо выше термина, за которым следует двоеточие (:). Альтернативы обычно следуют за этим в отдельных строках, но могут также помещаться и в одной строке, в таком случае им предшествует фраза «одно из».

Грамматические правила лексики языка рассматриваются с точки зрения существования раз-личных категорий словоориентированных языковых единиц (лексем), распознаваемых компилятором. Грамматические правила структуры фраз подробно определяют допустимые способы группирования лексем в выражения, операторы и прочие смысловые единицы языка.

Например, лексемы языка C++ образуются из последовательности операций, выполняемых с программой компилятором и препроцессором языка.

Программа на языке C++ – последовательность ACSII-символов, представляющих собой ее исходный код, создаваемый при работе в текстовом редакторе.

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

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

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

Комментарии – текстовые части, предназначенные для аннотирования программы. Комментарии перед лексическим анализом исключаются из исходного текста программы.

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

Компилятор языка C++ распознает лексемы шести классов: ключевые слова, идентификаторы, константы, строковые литералы, операции и знаки пунктуации (также называемые разделителями). Формальное описание лексемы имеет следующий вид:

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

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

– константа;

– строковый литерал;

– операция;

– знак пунктуации.

Во время лексического анализа исходного кода выбирается лексема максимальной длины. Например, слово external будет рассматриваться как отдельный идентификатор, а не как ключевое слово extern, за которым следует идентификатор al.

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

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

– не-цифра;

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

– идентификатор цифра.

Не-цифра: одно из

abcdefghijklmnopqrstuvwxyz_ ;

ABCDEFGHIJKLMNOPQRSTUVWXYZ;

цифра: одно из

Идентификатор – произвольное имя любой длины, присваиваемое классам, объектам, функциям, переменным, определяемым пользователем типам данных и т.д. Идентификаторы могут содержать буквы от А до Z и от а до z, символ подчеркивания (_) и цифры от 0 до 9. Существуют только два ограничения:

– первый символ должен являться буквой или символом подчеркивания;

– уникальность и контекст идентификаторов.

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

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

– константа-с-плавающей-точкой;

– целочисленная-константа;

– перечислимая-константа;

– символьная-константа.

Операциями называются лексемы, вызывающие некоторые вычисления с переменными и объектами, указанными в выражении. Набор операций C++ включает в себя помимо обычных арифметических и логических операций средства манипуляции с данными на битовом уровне, доступа к компонентам структур и объединений, а также операции с указателями (установка и обращение по ссылке).

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

Объект – идентифицируемая область памяти, которая может содержать фиксированное значение переменной (или набор таких значений). Каждая величина имеет связанное с ней имя и тип (который также называют типом данных). Имя используется для доступа к объекту. Имя может являться простым идентификатором либо сложным выражением, уникальным образом «указывающим» на данный объект.

Тип используется:

– для определения требуемого количества памяти при ее исходном распределении;

– для интерпретации битовых кодов, находимых в объектах при последующих к ним обращениях;

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

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

Для связи идентификаторов с объектами требуется, чтобы каждый идентификатор имел как минимум два атрибута: класс памяти и тип (иногда его называют типом данных).

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

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

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

– функция;

– прототип функции;

Контекст зависит от того, как и где объявлены идентификаторы.

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

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

Идентификаторы, объявленные в списке объявлений параметров в прототипе функции (не являющиеся частью определения функции), имеют контекст прототипа функции. Конец этого контекста совпадает с концом прототипа функции.

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

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

Пространство имен – это контекст, в пределах которого идентификатор должен быть уникальным.

Видимость идентификатора – область исходного кода программы, из которого допустим нормальный доступ к связанному с идентификатором объекту.

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

Видимость не может выходить за пределы контекста, но контекст может превышать видимость.

Загрузочный модуль (выполняемая программа) создается из полученных в результате раздельной компиляции объектных модулей с автоматическим поиском и присоединением библиотечных подпрограмм и процедур. Компоновка – это процесс, который позволяет правильно связать каждое вхождение идентификатора с одним конкретным объектом или функцией. Все идентификаторы имеют один из трех атрибутов компоновки, тесно связанных с их контекстом: внешняя компоновка, внутренняя компоновка или отсутствие компоновки. Эти атрибуты определяются местоположением и форматом объявлений, а также явным (или неявным по умолчанию) использованием спецификатора класса памяти.

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

Идентификаторы с типом компоновки отсутствие представляют уникальные элементы программы.

Правила внешней и внутренней компоновки:

– любой идентификатор объекта или файла, имеющий файловый контекст, будет иметь внутренний тип компоновки, если его объявление содержит спецификатор класса памяти static ;

– если объявление идентификатора объекта или функции содержит спецификатор класса памяти extern , то идентификатор имеет тот же тип компоновки, что и видимое объявление идентификатора с файловым контекстом. Если такого видимого объявления не имеется, то идентификатор будет иметь внешний тип компоновки;

– если функция объявлена без спецификатора класса памяти, то ее тип компоновки определяется, как если бы был использован спецификатор класса памяти extern ;

– если идентификатор объекта с файловым контекстом объявлен без спецификатора класса памяти, то идентификатор имеет внешний тип компоновки.

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

Различают объявления определения (их обычно просто называют объявлениями) и объявления ссылки (иногда называемыми неопределяющими объявлениями). Объявление определения, как и следует из названия, выполняет две функции: объявления и определения. Неопределяющие объявления требуют наличия где-либо далее в программе определений. Объявление ссылки просто вводит в программу одно или более имен идентификаторов. Определение фактически распределяет объекту память и связывает идентификатор с этим объектом.

В число объектов, которые могут быть объявлены, входят:

– переменные;

– функции;

– классы и компоненты классов;

– компоненты структур;

– компоненты объединений;

– массивы прочих типов;

– перечислимые константы;

– метки операторов.

Спецификатор типа с одним или более модификатором используется для задания типа объявляемого идентификатора.

Типы делятся на фундаментальные и производные. К фундаментальным типам относятся: void, char, int, float, double, short, long, signed, а также некоторые варианты unsigned. Производные типы включают в себя указатели и ссылки на другие типы, массивы других типов, типы функций, типы классов, структуры и объединения. Объект класса может, например, содержать некоторое число объектов различных типов вместе с функцией манипуляции этими объектами, плюс механизм контроля доступа и наследования от других классов.

Фундаментальные спецификаторы типа создаются из следующих ключевых слов:

char, int, signed, double, long, unsigned, float, short.

На базе этих ключевых слов можно построить интегральные типы и типы с плавающей точкой, которые в совокупности называются арифметическими типами. Типы char, short, int и long называются интегральными типами.

Простые объявления идентификаторов переменных имеют следующий шаблон:

тип данных перем1 <=иниц1>, перем2 <=иниц2>,...;

где перем1, перем2, ... – это произвольная последовательность отдельных идентификаторов. Каждая из переменных объявляется с указанным типом данных.

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

«Указатель на объект типа type» содержит (то есть указывает) адрес объекта с типом type. Поскольку указатель сам по себе является объектом, то можно установить указатель на указатель. В число прочих объектов, на которые обычно устанавливается указатель, входят массивы, структуры и классы. Размер указателей объектов зависит обычно от модели памяти, размера и расположения сегментов данных.

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

Указатель функции имеет тип «указатель функции, возвращающей тип type», где type есть тип возвращаемых функцией данных.

Объявление указателя всегда должно устанавливать его на некоторый конкретный тип, даже если этот тип void (что фактически означает указатель на любой тип). Однако уже после объявления указатель обычно может быть переназначен на объект другого типа. Указатель со значением null – это адрес, гарантированно отличный от любого допустимого указателя, используемого в программе. Присвоение указателю целой константы 0 определяет его значение null.


2. ПОНЯТИЕ ЯЗЫКА ПРОГРАММИРОВАНИЯ. ПОНЯТИЕ ЛЕКСИКИ, СИНТАКСИСА И СЕМАНТИКИ.

3.СПОСОБЫ ФОРМАЛЬНОГО ОПРЕДЕЛЕНИЯ СИНТАКСИСА ЯЗЫКА ПРОГРАММИРОВАНИЯ: МЕТАЯЗЫК, СИНТАКСИЧЕСКИЕ ДИАГРАММЫ.

Анализировать условие достижения конца потока (конца файла) и ошибки ввода-вывода;

Получать и устанавливать указатель текущей позиции в потоке;

Управлять буферизацией потока и размером буфера.

Все операции ввода-вывода реализованы с помощью функций, находящихся в

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

Поток можно открыть в текстовом или двоичном режиме. В соответствии с этим различают файлы текстовые и двоичные.

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

читается числовая информация, то происходит преобразование прочитанной последовательности символов в двоичное целое или число с плавающей точкой в соответствии со спецификацией формата; при форматном выводе числовой информации происходит преобразование из внутреннего представления числа в последовательность символов, изображающих число. Последовательность символов, хранящаяся в текстовом файле, может быть разбита на строки. При записи в текстовый поток символа новой строки ‘\n’ он заменяется последовательностью символов CR (“возврат каретки”) и LR (“перевод строки”). При

чтении из текстового файла последовательность символов CR и LR преобразуется в один символ новой строки ‘\n’.

Если в файле хранится не текстовая информация, а двоичная, то никакие преобразования не должны выполняться. Например, в файл записывается (а затем читается) числовая информация в своем внутреннем представлении. Такой файл надо открыть как двоичный.

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

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

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

символов, указанных в спецификации преобразования. Прочитанная последовательность символов интерпретируется в соответствии с форматной строкой (форматная строка просматривается последовательно от первого символа к последнему) как символьное представление целого числа или вещественного числа или один символ или строка символов. Затем преобразуется во внутреннее представление и записывается в область памяти очередной переменной из списка аргументов (указатель текущей позиции файла при этом перемещается

на новую текущую позицию в соответствии с числом прочитанных байтов).

Этот процесс продолжается пока не исчерпана форматная строка или не достигнут конец файла или не произошла ошибка. В первом случае функция возвращает количество объектов, получивших значение при вводе, при достижении конца файла – возвращает константу EOF, в случае ошибки – значение –1.

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

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

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

13. ПОНЯТИЕ ПРОГРАММЫ. СТРУКТУРА ПРОГРАММЫ.

Простая программа – это программа с управляющей структурой, обладающей следующими особенностями:

1) имеется только один вход и один выход,

2) через каждый узел программы проходит путь от входа к выходу структуры.

Логически программы можно разбить на 2 блока:

1. величины с которыми работаем

2. действия производимые над величинами (в соответствии с алгоритмом решения задачи).

Программа в си состоит из подпрограмм. Из них путем механического объединения формируется текст программы, но всегда существует основная подпрограмма. Синтаксис подпрограммы: 1. Заголовок void main ()

2. тело – {блок} – составной оператор, позволяющий задавать величины и действовать над ними – крупная единица действия. В блоке величина сначала должна быть определена и только потом использована.

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

директивы препроцессору, указания компилятору, объявления и определения.

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

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

путем их объявления. Каждый исходный файл компилируется отдельно, а затем связывается с другими компоновщиком программ. Отдельные исходные файлы можно объединить в один исходный файл, компилируемый как единое целое, используя директиву препроцессора – include.

14. ЯЗЫКОВЫЕ СРЕДСТВА ВЫЧИСЛЕНИЙ НАД ДАННЫМИ: ВЫРАЖЕНИЕ, ОПЕРАТОР ПРИСВАИВАНИЯ. СИНТАКСИС И СИМАНТИКА ВЫРАЖЕНИЯ И ОПРЕТОРА ПРИСВАИВАНИЯ.

ВЫРАЖЕНИЕ – множество взаимосвязанных операций над переменными и константами и скобок «()», в котором результат одной операции является операндом другой.

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

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

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

Оператор присваивания

В простейшем случае общий вид оператора: V = E;

Здесь V – имя переменной, а E – выражение. В операторе присваивания используется операция присваивания = .

Тип вычисленного значения выражения перед присваиванием преобразуется к типу переменной по правилам преобразования типов.

12. СОВМЕСТИМОСТЬ ТИПОВ. ПРЕОБРАЗОВАНИЕ ТИПОВ.

В выражениях в качестве операндов могут присутствовать переменные и константы разных типов (здесь и далее мы ограничимся пока только известными нам базовыми типами данных). Результат каждой операции также имеет свой определенный тип, который зависит от типов операндов. Если в бинарных операциях типы данных обоих операндов совпадают, то результат будет иметь тот же самый тип. Если нет, то транслятор должен включить в код программы неявные операции, которые преобразуют тип операндов, то есть выполнить ПРИВЕДЕНИЕ ТИПОВ. Преобразование типов может включать в себя следующие действия:

Увеличение или уменьшение разрядности машинного слова , то есть “усечение” или “растягивание” целой переменной;

Преобразование целой переменной в переменную с плавающей точкой и наоборот;

Преобразование знаковой формы представления целого в беззнаковую и наоборот.

В тех случаях, когда программиста не устраивает принятый порядок неявного преобразования типов, он может сам преобразовать результат к такому типу, какой ему необходим. Это можно сделать, в частности, путем присваивания результата дополнительной переменной, во время которого требуемое преобразование будет произведено. Но он может сделать то же самое внутри выражения "на лету" с помощью специальной операции. Она представляет собой имя типа, к которому осуществляется приведение, заключенное в круглые скобки и стоящее перед операндом. В качестве примера рассмотрим получение дробной части числа:

double x,d; // double x,d; int n;

d = x - (int)x; // n = x; d = x - d;

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

1) все операнды типа float преобразуются к типу double;

2) если один операнд имеет тип long double, то второй операнд преобразуется к типу long double;

3) если один операнд имеет тип double, то второй операнд преобразуется к типу double;

4) если один операнд имеет тип unsigned long, то второй операнд преобразуется к типу unsigned long;

5) если один операнд имеет тип long, то второй операнд преобразуется к типу long;

6) если один операнд имеет тип unsigned int, то второй операнд преобразуется к типу unsigned int;

7) все операнды типа char преобразуются к типу int;

8) все операнды типа unsigned char преобразуются к типу unsigned int;

9) иначе оба операнда имеют тип int.

Тип значения выражения имеет тип результата последней выполняемой операции в этом выражении

15. ЯЗЫКОВЫЕ СРЕДСТВА УПРАВЛЕНИЯ ВЫЧИСЛЕНИЯМИ: ВЕТВЛЕНИЯ, ЦИКЛЫ (ПОНЯТИЕ, НАЗНАЧЕНИЕ, СТРУКТУРНАЯ СХЕМА, ВИДЫ).

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

Таким образом, в самом общем виде структурная схема цикла содержит три части:

Действия по подготовке цикла к первому исполнению;

Действия, являющиеся основным содержанием данного вычислительного процесса – тело цикла;

Действия, отслеживающие повторение тела цикла – проверка условия продолжения или условия окончания повторений.

Блок-схема алгоритма вычисления значения полинома n–й степени для заданного значения x:
Для итерационных методов характерны стереотипные вычисления, связанные с переходом от одного приближения к следующему. Это позволяет записывать соответствующие этим методам алгоритмы в виде циклических, причем число повторений этих стереотипных вычислений (итераций) заранее, как правило, неизвестно и зависит от начального приближения и допустимой погрешности. Характерным условием окончания цикла является некоторое отношение, связывающее разность последовательных приближений и допустимую погрешность.

 

Возможно, будет полезно почитать: