Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
Общая характеристика языка Си
Язык программирования Си был разработан в лабораториях Bell Labs в период с 1969 по 1973 годы. Согласно Ритчи, самый активный период творчества пришёлся на 1972 год. Язык назвали «Си» (C — третья буква латинского алфавита), потому что многие его особенности берут начало от старого языка «Би» (B — вторая буква латинского алфавита). Язык программирования Си отличается минимализмом. Авторы языка хотели, чтобы программы на нём легко компилировались с помощью однопроходного компилятора, чтобы каждой элементарной составляющей программы после компиляции соответствовало весьма небольшое число машинных команд, а использование базовых элементов языка не задействовало библиотеку времени выполнения. Однопроходный компилятор компилирует программу, не возвращаясь назад, к уже обработанному тексту. Поэтому использованию функций и переменных должно предшествовать их объявление. Код на Си можно легко писать на низком уровне абстракции, почти как на ассемблере. Иногда Си называют «универсальным ассемблером» или «ассемблером высокого уровня», что отражает различие языков ассемблера для разных платформ и единство стандарта Си, код которого может быть скомпилирован без изменений практически на любой модели компьютера. Си часто называют языком среднего уровня или даже низкого уровня, учитывая то, как близко он работает к реальным устройствам. Однако, в строгой классификации, он является языком высокого уровня. Си создавался с одной важной целью: сделать более простым написание больших программ с минимумом ошибок по правилам процедурного программирования, не добавляя на итоговый код программ лишних накладных расходов для компилятора, как это всегда делают языки очень высокого уровня, такие, как Бейсик. С этой стороны Си предлагает следующие важные особенности: - простую языковую базу, из которой вынесены в библиотеки многие существенные возможности, вроде математических функций или функций управления файлами; - ориентацию на процедурное программирование, обеспечивающую удобство применения структурного стиля программирования; - систему типов, предохраняющую от бессмысленных операций; - использование препроцессора для, например, определения макросов и включения файлов с исходным кодом; - непосредственный доступ к памяти компьютера через использование указателей; - минимальное число ключевых слов; - передачу параметров в функцию по значению, а не по ссылке (при этом передача по ссылке эмулируется с помощью указателей); - указатели на функции и статические переменные; - области действия имён; - структуры и объединения — определяемые пользователем собирательные типы данных, которыми можно манипулировать как одним целым. В то же время в Си отсутствуют - вложенные функции; - сопрограммы; - а также средства: - автоматического управления памятью; - объектно-ориентированного программирования; - функционального программирования. После появления язык Си был хорошо принят, потому что он позволял быстро создавать компиляторы для новых платформ, а также позволял программистам довольно точно представлять, как выполняются их программы. Благодаря этому программы, написанные на Си, эффективнее написанных на многих других языках. Как правило, лишь оптимизированный вручную код на ассемблере может работать ещё быстрее, потому что он даёт полный контроль над машиной, однако развитие современных компиляторов вместе с усложнением современных процессоров сократило этот разрыв. Лекция 16 Языки программирования высокого уровня Turbo Pascal и С 16.1 Язык программирования Паскаль. 16.1.1. Основы языка. 16.1.2. Структура программы на языке Паскаль. 16.1.3. Классификация типов данных языка Паскаль. 16.2 Язык программирования Си. 16.2.1 Основы языка. 16.2.2 Структура программы на языке Си. 16.2.3 Классификация типов данных языка Си. Язык программирования Паскаль Основы языка Алфавит языка Алфавит естественного (например, русского) языка состоит из фиксированного набора литер – различимых графических изображений, каждое из которых всегда рассматривается как нечто единое целое, даже в том случае, когда это изображение не является непрерывным, например, русская буква " Ы". Считается, что алфавит алгоритмического языка состоит из фиксированного набора основных символов, причем часть этих символов является литерами (" + " ), а часть – определенными комбинациями литер Набор основных символов, образующих алфавит, состоит из трех групп: - буквы (буквы латинского алфавита); - цифры (0..9); - спецсимволы: Знак арифметической операции (+, -, *, / ); Знак операции сравнения (=, < > - не равно, > , > = - больше или равно, < , < = ); Разделитель (., ; : ( ) [ ] { } ' " ); Служебное слово (and, array, begin, case, const, div, do, downto, else, end, for, function, goto, if, in, label, mod, nil, not, of, or, procedure, program, record, repeat, set, then, to, type, until, var, while, with). Составные элементы Паскаль–программы К основным элементам, из которых состоит программа на языке Турбо Паскаль, относятся: - операторы - идентификаторы и имена - описания - переменные - процедуры и функции Операторы Одним из ведущих понятий языка является понятие оператор. Это наиболее крупное и содержательное понятие: каждый оператор представляет собой законченную фразу языка и определяет некоторый вполне законченный этап обработки данных. Все операторы можно разбить на две группы: - простые (основные) операторы; - структурированные операторы. К простым операторам относятся те, которые в своем составе (т.е. в последовательности символов, образующей запись оператора) не содержат других операторов. Операторы этой группы назовем основными операторами. К ним относятся: оператор присваивания, оператор процедуры, оператор перехода, пустой оператор. Другую группу образуют операторы, в состав которых входят другие операторы. Операторы этой группы будем называть производными операторами, К этой группе относятся следующие типы операторов: составной оператор, выбирающий оператор, оператор цикла, оператор присоединения. В записи алгоритма могут использоваться последовательности из этих операторов, без ограничений на их количество. Все операторы в такой последовательности отделяются друг от друга разделителем " ; " (точка с запятой) – тем самым производится четкое разбиение всей записи на отдельные операторы. Таким образом, если обозначить через S любой допустимый оператор, то в общем случае такая последовательность будет иметь вид S; S; …; S Операторы этой последовательности обычно выполняются в порядке их следования в тексте программы, при его просмотре слева направо по строке и сверху вниз по строкам. Таким образом, преемником каждого оператора обычно является следующий по порядку в тексте программы оператор, Этот естественный порядок выполнения операторов может быть нарушен с помощью операторов перехода, которые сами определяют своих преемников. Что касается производных операторов, то размещение входящих в их состав других операторов (которые могут быть как основными, так и производными) и порядок их выполнения определяются другими правилами, которые будут излагаться при рассмотрении соответствующих операторов. Идентификаторы и имена Весьма важным и употребительным понятием языка является идентификатор — этот термин происходит от слова " идентифицировать", т.е. " отождествлять". Поскольку алгоритм, определяющий процесс обработки данных, оперирует с различными программными объектами — переменными величинами, функциями и т.д., то при записи алгоритма приходится как-то ссылаться на используемые объекты. Для этой цели программным объектам даются индивидуальные имена и описание тех или иных действий над объектами дается в терминах их имен, которые и представляют соответствующие объекты. Именами обозначаются и некоторые атрибуты используемых объектов, например тип значений, которые могут принимать программные объекты. Роль таких имен и выполняют идентификаторы. Идентификатором является любая конечная последовательность букв и цифр, начинающаяся обязательно буквой. Примеры идентификаторов: х SUMMА pi step Petrov a28cd5 (поскольку пробелы внутри идентификаторов не допускаются, то наличие пробела означает конец идентификатора). Следующие записи не являются идентификаторами, поскольку каждая из них не подходит под синтаксическое определение идентификатора: 5f sum(2) step.7 Алма-Ата Заметим, что запись begin вообще говоря подходит под синтаксическое определение идентификатора –это последовательность из пяти букв, начинающаяся буквой. Однако вспомним, что begin является служебным словом. А поскольку служебные слова в паскале запрещается использовать для иных целей, то указанная запись не может быть использована в качестве идентификатора. Идентификаторы не имеют какого-либо постоянно присущего им смысла, а используются только в качестве имен программных объектов или их атрибутов, так что в дальнейшем вместо слова " идентификатор" мы часто будем использовать более короткий термин " имя": Имена (идентификаторы) выбираются программистом по своему усмотрению. Чтобы сделать программу решения той или иной задачи более наглядной и понятной, следует избегать кратких; но мало выразительных имен типа х, t, s и т.д., а выбирать их так, чтобы имя отражало суть обозначаемого объекта (конечно, в рамках алфавита конкретной реализации языка), например summa time INTEGRAL Road Ivanov и т.п. При этом следует иметь в виду, что разные объекты, вообще говоря, нельзя обозначать одним и тем же идентификатором (т.е. каждый идентификатор в одной программе может быть использован только в одном смысле) — о некоторых исключениях из этого общего правила будет сказано позднее. Синтаксическое определение не накладывает ограничений на длину идентификаторов, хотя в конкретных реализациях языка такие ограничения имеют место. Чтобы иметь более наглядные имена, целесообразно использовать строчные и прописные буквы: СтеныДлина СтержняДлина Некоторым идентификаторам в Турбо Паскале заранее предписан вполне определенный смысл. Например, идентификатор sin считается именем известной всем функции, значение которой равно синусу ее аргумента (в радианах). Такие идентификаторы называются стандартными. Однако в отличие от служебных слов типа begin, смысл и назначение любого стандартного идентификатора может быть переопределен программистом по своему усмотрению с помощью соответствующего описания, хотя делать это без особой на то необходимости не рекомендуется для избежания ошибок в программе. Описания Важным понятием языка является описание (впрочем, суть этого понятия точнее отражал бы термин объявление). Необходимость этого понятия связана со следующими обстоятельствами. Операторы, о которых говорилось выше, задают правила обработки данных, т.е. определяют действия над программными объектами. Но прежде, чем задавать такие действия, программист должен как-то ввести в употребление нужные ему программные объекты и точно определить необходимые атрибуты (свойства) каждого из них. Если, например, таким объектом является массив, то надо указать его размерность, размеры по каждому измерению, а также указать, что представляют собой элементы этого массива. Кроме того, правила обработки данных формулируются в терминах имен соответствующих объектов. Чтобы однозначно понять и реализовать эти правила, необходимо знать, какой объект назван тем или иным именем. Для введения в употребление нужных программных объектов, описания их атрибутов, присваивания имен объектам, а также для некоторых других целей и служат описания. В Турбо Паскале имеется пять типов описаний, каждый из которых предназначен для определенных целей: - описание меток; - описание констант; - описание типов; - описание переменных; - описание процедур и функций. В общих чертах назначение каждого типа описания ясно из его названия, а впоследствии все типы описаний будут рассмотрены более подробно. Переменные При синтаксических определениях ряда понятий языка, в том числе операторов и описаний, часто используется понятие переменная. Переменная — это программный объект, способный принимать значение. Это значение переменная получает уже в процессе выполнения программы, обычно в результате выполнения оператора присваивания. Присвоенное ей значение переменная сохраняет до тех пор, пока этой переменной не будет присвоено новое текущее значение — при этом предыдущее ее значение (если оно было определено) безвозвратно теряется, С каждой переменной связывается определенный тип значений, которые она может принимать. Попытка присвоить переменной значение иного типа квалифицируется как ошибка в программе. С точки зрения синтаксиса, переменная (в простейшем случае) — это идентификатор, который сопоставлен переменной в качестве ее имени. Это имя используется для ссылки на значение переменной. Другими словами, имя в тексте программы представляет значение этой переменной. С алгоритмической точки зрения весьма важным является такое действие, как присваивание переменной некоторого значения. Удобно считать, что выполнение этого действия означает помещение присваиваемого переменной значения в выделенный для нее ящик. При этом каждый запоминающий ящик обладает следующими свойствами. 1) В каждый момент времени в ящике может храниться не более одного значения. 2) Каждый ящик способен хранить только значения одного и того же типа. Попытка поместить в ящик значение любого другого типа приводит к тому, что ящик отказывается принимать на хранение передаваемое ему значение — это расценивается как ошибка в программе. 3) Значение, помещенное в ящик, будет храниться в нем до тех пор, пока в этот ящик не будет помещено новое значение (в момент присваивания соответствующей переменной этого нового значения) – при этом предыдущее содержимое ящика безвозвратно теряется (уничтожается). 4) Находящееся в ящике значение считается текущим значением соответствующей переменной. Это текущее значение может быть выдано из ящик а для использования сколько угодно раз, но при этом содержимое ящика не меняется; из него каждый раз выдается копия хранящегося значения с сохранением оригинала в ящике без какого-либо изменения. 5) К началу выполнения программы содержимое всех запоминающих ящиков считается неопределенным; в частности, их нельзя считать и пустыми, поскольку эти ящики могли использоваться при выполнении предыдущих программ, после чего в ящиках могло что-то остаться. В свете сказанного следует вернуться к символу " : = " из числа разделителей. При описании процессов обработки данных особенно часто приходится задавать такое действие, как присваивание переменной величине ее нового текущего значения, для чего приходится использовать выражения типа " присвоить значение", " положить равным" и т.д., которые являются синонимами. Поскольку это действие встречается особенно часто, то для его обозначения вместо служебного слова используется символ ": =", который легко запоминается и вместе с тем обеспечивает компактность и наглядность записи. Например, запись z: =x + у означает, что переменной z должно быть присвоено новое текущее значение, равное значению суммы х + у. В математике для этой цели обычно используется знак равенства " = ", например z = х. Однако этот знак в математике используется и для обозначения операции сравнения. Для устранения возможности неоднозначного понимания, в паскале символ " = " используется только для обозначения операции сравнения, а для обозначения операции присваивания выбран символ " : = ", изображаемый парой литер. Функции и процедуры Понятие функции хорошо известно из школьного курса математики. С помощью функций задаются самые различные зависимости одних значений (значений функции) от других значений (значений аргументов). Заметим лишь, что в алгоритмических языках допускаются только такие функции, для которых заданы алгоритмы вычисления их значений. В математике такое требование не является обязательным — можно, например, использовать функцию f(x, y), значение которой равно количеству простых чисел в интервале (х, у) — даже в том случае, если мы не знаем, как именно следует вычислять значение этой функции при любых конкретных значениях аргументов х и у. Таким образом, в алгоритмическом языке любая функция задается некоторой вычислительной процедурой, выполнение которой и дает значение функции. Программист может, ввести в употребление любые нужные ему в данной программе функции. Наряду с функциями, предназначенными для вычисления отдельного значения, можно вводить в употребление и процедуры более общего характера, представляющие собой некоторые вполне законченные этапы решения задачи — упорядочение компонент вектора по их убыванию, сложение матриц и т.п. Вводимые в употребление функции и процедуры должны быть определены (описаны) в разделе функций и процедур паскаль-программы. При 'Таком описании каждой функции (процедуре) дается свое имя. Сама процедура формулируется, в основном в терминах формальных параметров — идентификаторов, которые в описании процедуры представляют те заранее не фиксируемые значения или программные объекты, к которым должна применяться эта процедура. Все эти формальные параметры в явном виде перечисляются в описании процедуры или функции. Для использования в программе какой-либо функции или процедуры достаточно указать ее имя и задать ее фактические параметры, т.е. те конкретные значения и (или) объекты, к которым должна быть применена указанная процедура или функция. Для обращения к функциям и процедурам в Турбо Паскале имеются соответствующие понятия — вызов функции и оператор процедуры. Некоторые функции и процедуры, например элементарные функции математического анализа (sin (x), ln(х) и т.д.) или процедуры ввода/вывода используются во многих программах. Для удобства их использования, в Турбо Паскале зафиксирован некоторый набор так называемых стандартных функций и процедур, которые можно использовать в любой программе без их явного описания. Можно считать, что к началу трансляции любой паскаль-программы в соответствующий ее раздел автоматически вставляются описания всех стандартных функций и процедур, используемых в этой программе. За каждой из них в языке закреплено некоторое стандартное имя. Однако эти имена не являются зарезервированными словами, так что программист может по своему усмотрению переопределить любое из этих стандартных имен. Синтаксис языка. Для облегчения понимания текста паскаль-программы и упрощения транслятора, язык Турбо Паскаль требует выполнения определенных правил записи текста программы, которые не находят своего отражения в синтаксисе языка. При формулировании этих правил мы будем использовать понятие " разделитель текста", понимая под этим термином пробел, конец строки и комментарий. Пробел — это литера, не имеющая графического изображения: пробелу соответствует пустая позиция в строчке текста (на листе бумаги, бланке, экране дисплея и т.д.). Однако пробел имеет определенное представление (свой цифровой код) в машине и вводится в машину вместе с остальными литерами текста программы, Конец строки – это управляющая литера, также не имеющая графического изображения. Дело в том, что при записи текста паскаль-программы он естественным образом разбивается на отдельные строчки — хотя бы в силу ограниченности листа бумаги, бланка или экрана дисплея, на которых фиксируется этот текст. Число возможных позиций в строчке обычно фиксировано, однако число литер в части текста, образующей очередную строчку, может быть меньше числа возможных позиций. Разбиение всего текста на отдельные строчки производится программистом по своему усмотрению. Чтобы указать, что очередная часть текста должна образовывать новую строчку, и служит управляющая литера " конец строки", которая заносится в исходный текст при его нанесении на внешние носители данных или при его непосредственном вводе в машину с помощью клавиатуры терминала. Как и в случае пробела, эта литера тоже имеет свой код, который фиксируется на внешнем носителе данных или непосредственно вводится в машину при наборе текста на клавиатуре. Упомянутые выше правила записи текста паскаль-программы состоят в следующем: - между двумя последовательными конструкциями языка, любая из которых является идентификатором, числом или служебным словом, обязательно должен находиться хотя бы один разделитель текста; - разделители текста не должны встречаться внутри идентификаторов, чисел и служебных слов; - кроме случаев, указанных в предыдущем пункте, между двумя последовательными основными символами языка может встречаться любое число разделителей текста и они не влияют на смысл программы (при трансляции паскаль-программы в машинную программу разделители текста в указанных здесь случаях игнорируются). Управляющая литера " конец строки" в тексте не задается в явном виде: переход на следующую строчку текста автоматически подразумевает наличие этой управляющей литеры. В тех случаях, когда в тексте надо явно указать наличие пробела (это бывает существенно при записи текста вручную на обычном листе бумаги, а не на бланке), мы будем изображать его литерой " _ ", например begin_if_ x< 25_then_x: =x + 1 _else_x: =0 Сформулированные выше правила записи текста программы отвечают и на вопрос о том, где могут быть помещены комментарии. И хотя в этом отношении возможности весьма велики, обычно комментарии помещают между достаточно крупными синтаксическими единицами – описаниями, операторами и т.д. |
Последнее изменение этой страницы: 2017-04-12; Просмотров: 2560; Нарушение авторского права страницы