Курс лекции по Информатике

2





Федеральное агентство по образованию

Государственное образовательное учреждение
высшего профессионального образования

Тульский государственный университет



Кафедра прикладной математики и информатики

















ИНФОРМАТИКА



Конспект лекций для студентов 



Направления: 010500 - Прикладная математика и информатика

специальности: 010501 - Прикладная математика 





очной формы обучения





























Тула 2005


Разработал  М.Б.Кривоногов, канд. техн. наук, доцент.

	 




Лекция 1

Введение

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

Понятие информации определяется как “знания получаемые в процессе чтения, наблюдения, изучения…”. В кибернетике понятие информация определяется как “новые знания об объекте управления, позволяющие вырабатывать управленческие решения, как мера устранения неопределенности в управленческой системе, как упорядоченное отражение действительности”. Применительно к вычислительным наукам понятие информация определяется как “сведения, представленные в символьной форме”.

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

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

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

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

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

Такими помощниками и являются современные ЭВМ. Наука, исследующая законы и методы обработки, накопления и передачи информации с помощью ЭВМ называется информатикой.

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

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

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

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

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


Лекция 2

 Понятие алгоритма

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

Примером алгоритма может служить правило нахождения наибольшего общего делителя двух чисел (алгоритм Евклида). Даны два целых положительных числа m и n. Требуется найти их наибольший общий делитель, то есть наибольшее положительное целое число, которое нацело делит как m, так и n.

1 шаг (нахождение остатка). Разделим m на n. Пусть остаток равен r. Имеем 0  r < n.

2 шаг (это нуль?). Если r = 0, то алгоритм заканчивается; n – искомое число.

3 шаг (замена). Положите m  n, n  r и возвращайтесь к шагу 1.

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

 Теория алгоритмов

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

Точные математические понятия, которые в том или ином смысле формализовали интуитивное понятие алгоритма, предложены только в середине 30-х годов нашего столетия. Исторически первые из предложенных понятий можно разделить на два вида.

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

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

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

 Алгоритмический процесс

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

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

 Алгоритмический язык

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

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

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

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

Лекция 3

 Языки программирования

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

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

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

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

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

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

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

Возникновение и развитие языков программирования неразрывно связано с развитием ЭВМ и с расширением сферы их применения. Языками программирования являются, например, внутренние машинные языки (то есть языки непосредственной интерпретации ЭВМ, задаваемые системами команд этих ЭВМ), которые явились первыми языками программирования.

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

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

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

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

Из наиболее ранних зарубежных я. п., ориентированных на класс вычислительных и научных задач, наибольшее распространение получил язык ФОРТРАН. Значение ФОРТРАНА определяется его широким распространением, реализацией на всех более или менее распространенных ЭВМ, а также наличием огромных библиотек, насчитывающих сотни и тысячи программ, описанных на этом языке. Использование процедурно-ориентированных языков явилось мощным толчком к разработке и созданию систем автоматического программирования как транслирующего, так и интерпретирующего типов.

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

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

Расширение сфер использования ЭВМ привело к необходимости решать задачи, компактное описание которых выходит за рамки одного процедурно-ориентированного языка. Попытки использовать процедурно-ориентированные языки для решения задач, выходящих за пределы их ориентации, привели к практически непреодолимым трудностям. Так возникли проблемно-ориентированные я.п., то есть я.п. предназначенные для описания специальных проблем и решения определенного класса задач. Программа работы на таком языке содержит, помимо описания условия задачи, указания решить задачу данного класса. Примерами таких языков являются язык ЛИСП, предназначенный для описания процессов обработки информации, представленной в виде списков, и язык ПРОЛОГ, предназначенный для разработки программ и систем искусственного интеллекта. Языком такого рода является также язык  STRESS, предназначенный для описания задач конструирования. Программа на языке  STRESS содержит описание общих характеристик системы (размерности, число вершин и др.) и данные, а также указание: решить задачу и представить определенные данные в виде некоторой таблицы. Развитие таких языков имеет весьма важное практическое значение в силу чрезвычайной простоты их использования.

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

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

В связи с этим перед языками программирования, выдвигается новая цель - упростить программирование, быть может, даже за счет известной потери эффективности использования ЭВМ. Задача оптимизации тем самым отделяется от задачи составления работающей программы. Для реализации обширных средств, представляемых новыми объектно-ориентированными языками, первостепенное значение приобретает задача автоматизации процесса проектирования программ и создания соответствующих систем автоматического программирования, а также проблема построения автоматизированных систем обучения языкам пользователей ЭВМ. Такие системы получили название интегрированной среды разработчика приложений. Наиболее известны такие из них как BORLAND C++, BORLAND DELFI, BORLAND C++ BUILDER, MICROSOFT VISUAL C++, MICROSOFT VISUAL BASIC и другие. Каждая из этих систем включает в себя редактор исходных текстов программ, компилятор, компоновщик, отладчик, библиотеки классов и функций, справочную систему помощи и другие элементы. 

Лекция 4

Понятие программы и процедуры

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

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

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

Рекурсивная процедура - процедура в программировании, в описании которой содержится явное обращение к ней самой непосредственно или с помощью другой процедуры. Использование рекурсивной процедуры во многих случаях позволяет придавать алгоритмам компактную и наглядную форму. Рекурсивные процедуры, в частности, используются для описания алгоритмов вычисления значений функций, задаваемых рекуррентными соотношениями, например, вычисление факториала  n!=F(n); F(n)=nF(n-1); F(0)=1.

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

 Основные типы алгоритмов

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

Рассмотрим пять типовых алгоритмов:

СЛЕДОВАНИЕ – это алгоритм, в котором действия (операторы) следуют (выполняются) одно за другим: P1, P2 и т.д.



ЕСЛИ-ТО-ИНАЧЕ – это алгоритм, в котором задано некоторое условие. Если это условие выполняется (то есть оно истинно), то выполняется оператор P1. Если это условие не выполняется (то есть оно ложно), то выполняется оператор P2. Допускается укороченный вариант этого типового алгоритма. ЕСЛИ-ТО – это алгоритм, в котором при выполнении условия выполняется оператор P1, а при невыполнении условия управление просто передается на следующий за данным блок (в данном случае типовой алгоритм ЕСЛИ-ТО не производит никаких действий). 





ДЕЛАТЬ-ПОКА – это алгоритм, в котором оператор P (или группа операторов) выполняется многократно, пока выполняется условие и управление передается на следующий за данным блок, в случае если условие не выполняется. В данном алгоритме возможен случай, когда оператор P не выполняется ни одного раза. В этом случае условие сразу ложно.





ДЕЛАТЬ-ПОКА-НЕ – это алгоритм, в котором оператор P выполняется всегда хотя бы один раз, а затем, пока выполняется условие, выполнение оператора P повторяется. Как только условие станет ложным, повтор выполнения оператора P прекращается и управление передается на следующий блок.



ВЫБОР – это алгоритм, в котором в зависимости от значения некоторой наперед определенной переменной (величины) M выбирается один из операторов    P1,P2,…,PN и после его выполнения управление передается на следующий по порядку блок.



Эти типовые алгоритмы могут быть использованы при проектировании алгоритмов обработки информации (данных) на ЭВМ. Именно эти типовые алгоритмы и реализованы в современных языках программирования, например, в языке Си.

 Способы описания алгоритмов

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



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

Лекция 5

Этапы решения задач на ЭВМ

Решение задач на ЭВМ представляет сложный процесс, который состоит из ряда этапов:

1. Математическая формулировка задачи;

2. Выбор численного метода решения задачи;

3. Разработка алгоритма решения задачи;

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

5. Отладка программы;

6. Решение задачи на ЭВМ.

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

ПРИМЕР. Определить высоту треугольника X по заданной площади C, если известно, что основание больше высоты на величину B.

Известно, что площадь треугольника равна половине произведения основания на высоту, то есть:

C= X(X+B)/2.

Отсюда X определяется как корень уравнения:

X2 + BX- 2C = 0.

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

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

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

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

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

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

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







Далее логическая схема описывается в виде программы на языке, который понимает машина (язык машинных команд), или на языке программирования, который машина понимает после того, как с помощью специальной программы - транслятора, исходная программа будет переведена на язык машины. Такими языками программирования являются АЛГОЛ, КОБОЛ, ФОРТРАН, ПЛ/1, Си, Паскаль и другие.

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

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


Лекция 6

 Принцип действия ЭВМ

Электронные цифровые вычислительные машины предназначены для обработки данных, представленных в дискретной форме. При решении инженерных и экономических задач ЭВМ оперирует с числами и алфавитно-цифровыми словами (операндами), которые в виде исходных данных подаются на вход машины и в виде результата получаются на ее выходе. ЭВМ может выполнять некоторый ограниченный набор арифметических и логических действий (операций), причем в каждый момент времени машина в состоянии выполнить лишь одно из них. Поэтому всякий вычислительный процесс должен быть представлен в виде последовательности инструкций (команд), записанных в том порядке, в котором необходимо выполнять действия. Так, например, вычисление значения функции Y=AX2+B сводится к выполнению действий умножения и сложения в следующем порядке:



Наименование

Участвующие числа (операнды)

результат

Действия

1

2



Умножение

A

X

P1=AX

Умножение

P1

X

P2=AX2

Сложение

P2

B

Y=AX2+B



В таблице через P1 и P2 обозначены числа, равные результату соответствующих действий, а через Y - число, равное значению искомой функции. 



Информация о том, какие именно действия должна выполнять ЭВМ в настоящий момент, над какими операндами и куда следует поместить результат, задается с помощью команд. Команду для ЭВМ можно представить в общем виде следующим образом:



Формат

КОП

Адрес1

Адрес2

Адрес3

Двоичный код

10010

10111

10001

11101



Где КОП – код операции, Адрес1 – адрес первого сооперанда, Адрес2 – адрес второго сооперанда, Адрес3 – адрес результата операции над сооперандами.

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

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

Для выполнения программ компьютер временно записывает программу и данные в основную (оперативную) память. Минимальной единицей информации в ЭВМ является бит. Бит может быть либо “выключен”, при этом его значение равно нулю, либо “включен”, тогда его значение равно единице.

Минимально адресуемой единицей памяти является байт. Байт состоит из восьми информационных бит. Восемь бит обеспечивают основу для двоичной арифметики и для представления символов, таких как буква A или символ *. По соглашению информационные биты в байте пронумерованы от 0 до 7 справа налево. Процессор в персональном компьютере использует 16-битовую архитектуру, поэтому он имеет доступ к 16-битовым значениям как в памяти, так и в регистрах. Шестнадцатибитовое (двухбайтовое) поле называется словом. Биты в слове пронумерованы от 0 до 15 справа налево. В одном байте можно представить 256 различных комбинаций из нулей и единиц от 00000000 до 11111111, то есть в одном байте можно представить коды 256 символов.

С целью стандартизации в компьютерах используется американский национальный стандартный код для обмена информацией  ASCII (American National Standard Code for Information Interchange – читается “аски”-код). Именно по этой причине комбинация битов 01000001 обозначает букву A. Наличие стандартного кода облегчает обмен данными между различными устройствами компьютера. Восмибитовый расширенный ASCII-код, используемый в персональных компьютерах, обеспечивает представление 256 символов, включая символы русского алфавита.

Все байты памяти пронумерованы последовательно от 0 – минимального адреса памяти. Процессор обеспечивает доступ к байтам или словам в памяти. Для задания адреса необходимо двойное поле. Например, в 16-разрядном поле можно задать адрес от 0 до 65635. Таким образом, можно адресоваться к памяти с объемом 65536 байт или 64 Кбайт (1 Кбайт = 1024 байт, а 1 Мбайт = 1024 Кбайт).



 Архитектура компьютеров

В настоящее время сверхбыстродействующих суперкомпьютеров, делающих более 100 млн. операций в секунду насчитывается в мире несколько сотен. Известные модели суперкомпьютеров это CRAY-1 и CYBER-205. Достигнутый уровень возможностей таких машин, безусловно, определяется успехами микроэлектроники, но в такой же степени он зависит от новых концепций в архитектуре компьютеров. Под термином “архитектура” понимается логическая организация ВМ, как ее представляет себе программист. Рассмотрим кратко основные функции компьютера. Компьютер состоит, в сущности, из трех частей: памяти, процессора команд и процессора обработки данных. Для простоты исключим рассмотрение системы ввода-вывода, которая обеспечивает связь с внешней средой. Память содержит как массивы данных, так и команды; обращение к отдельным ячейкам памяти производится при помощи соответствующих им адресов. Каждый элемент данных, хранимых в памяти компьютера это, по сути, операнд, то есть то, над чем можно производить математические действия; к данным относятся и результаты, полученные в процессе предыдущих вычислений. Команды закодированы в виде последовательности битов, которые однозначно определяют выполнение операций и указывают адреса для обращения к памяти (КОП Адрес1 Адрес2 Адрес3 – 00111 10010 11101 10001). Команды организуются в программы. Набор команд, или аппаратно-реализованных операций, закладывает фундамент архитектуры. Основные элементы компьютера представлены на рис.  





Рис. Обобщенная структура компьютера.

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



Лекция 7

Архитектура персонального компьютера

Внешне ПК состоит из системного блока, клавиатуры, устройства отображения информации (дисплея), печатающего устройства (принтера). В системном блоке размещены системная (материнская) плата, блок питания, накопители (или дисководы) для гибких магнитных дисков (НГМД), накопитель на жестком магнитном диске (НМД), а также ячейки расширения для дополнительных плат. Клавиатура подключается к системному блоку с помощью кабеля, по которому подается и питание к ней. Дисплей и принтер также связаны с системным блоком через кабель, но имеют самостоятельное питание. Другие функциональные модули осуществляют управление принтером, дисководами, дисплеем и т.д., выполнены на отдельных печатных платах, которые вставляются в гнездовые разъемы на системной плате. Ячейки расширения обеспечивают подключение периферийных устройств, дисководов, каналов телекоммуникаций, дополнительной памяти, игровых устройств (джойстик), печатающих устройств, устройства-манипулятора “мышь”, а также графопостроителей (плоттеров), графических планшетов для ввода графической информации, сканеров,    дигитайзеров, музыкальных приставок, сетевых адаптеров, стриммеров и других устройств.

Компьютер представляет собой машину, основные задачи которой – восприятие, хранение, обработка и передача информации. Главный элемент компьютера – центральный процессор (ЦП) выполняет основные арифметические и логические действия и управляет работой всей системы, причем в одну секунду осуществляются сотни тысяч или миллионы операций. В персональном компьютере в качестве ЦП используется микропроцессор - интегральная схема. Основная память компьютера реализует хранение команд и данных. Имеется также ряд дополнительных интегральных схем, которые организуют процедуру ввода/вывода информации и обеспечивают функции управления.



Рис.Аппаратное обеспечение ПК.

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

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



Рис.Программное обеспечение компьютера.

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

Чтобы ЭВМ могла выполнять программы пользователя они должны быть представлены на машинном языке (в виде последовательности 0 и 1). Перевод (трансляция) на такой язык осуществляется с помощью программ, называемых ассемблерами, компиляторами и интерпретаторами. Ассемблеры и компиляторы транслируют всю программу до ее выполнения, а интерпретаторы переводят инструкции одну за другой по мере прохождения программы.

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

На системной плате размещены:

	микропроцессор (Intel);

	постоянная память (ROM 40 Кбайт);

	оперативная память (RAM до 512 Кбайт в зависимости от модели);



Основным элементом персонального компьютера является  центральный процессор (ЦП), который построен на базе микропроцессора, реализованного на одном кристалле или “чипе”. Микропроцессор,  используемый  в IBM PC, был разработан  и  создан  фирмой  Intel. 



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

Память, с которой имеет дело программист, представляет собой RAM (Random Access Memory), т.е. оперативная память, доступная как для чтения, так и для записи. Память RAM можно рассматривать как рабочую область для временного хранения программ и данных на время выполнения.

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

Лекция 8

 Представление данных и структур данных в ЭВМ

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

Математический сопроцессор 8087 выполняет вычисления с плавающей точкой в 10—50 раз быстрее, чем 8088. Кроме того, точность представления чисел в этом процессоре много больше, чем в 8088. Помимо четырех действий арифметики, 8087 имеет инструкции для вычисления тригонометрических функций (синус, косинус, тангенс и т.д.), что существенно облегчает программирование математических задач. Еще одним достоинством 8087 является его способность работать с числами в разных форматах: с целыми, с плавающей точкой и даже с двоично-десятичными (см. табл.1). Наконец, 8088 может послать команду в 8087 и продолжить свою работу до тех пор, пока не понадобится результат из 8087.



Таблица 1. Форматы чисел арифметического сопроцессора 8087.

Тип данных

(чисел)

Диапазон от

Диапазон до

Разрядность, бит

Разрядность, цифр

Целое слово

-32767

32767

16

4

Короткое целое

-2E9

2E9

32

9

Длинное целое

-9E18

9E18

64

18

Упакованное десятичное

-99..99

99..99

80

18

Короткое вещественное

8.43E-37

3.37E38

32

6-7

Длинное вещественное

4.19E-307

1.67E308

64

15-16

Промежуточный формат

3.4E-4932

1.2E4932

80

19



Любая модель PC на 8088 (кроме PCjr) может работать с 8087. (AT использует математический сопроцессор 80287 — вариацию 8087, специально предназначенную для 80286). 

Информационные структуры.

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

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

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

Линейные списки. Наиболее простым типом информационных структур являются линейные списки. Линейный список - это множество, состоящее из n  0 узлов X(1), X(2), ..., X(n), которое обладает свойствами: 

1) если n>0, то узел X(1) является первым;

2) если 1<k<n, то узлу X(k) предшествует узел X(k-1) и за ним следует X(k+1);

3) узел X(n) является последним.

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

Операции, которые можно выполнять о линейным списком:

	получить доступ к k-му узлу списка; 

	включить новый узел непосредственно перед k-м узлом;

	исключить k-й узел;

	объединить два (или более) линейных списка в один;

	разбить линейный список на два (или более) списка; 

	сделать копию линейного списка; 

	определить количество узлов в списке;

	выполнить сортировку узлов в возрастающем порядке по некоторым полям в узлах;

	найти в списке узел c заданным значением в некотором поле.

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

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

 Стек - это линейный список, в котором все включения и исключения делаются на одном конце списка (рис. а).

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

Дек (deque: double ended queue - очередь с двумя концами) - это линейки список, в котором все включения и исключения делаются на обоих концах списка (рис. в).

Стек называют еще списком типа LIFO ("last in first out" - "последним вошел - первым вышел"), а очередь - списком типа FIFO ("first in first out" - "первым вошел - первым вышел"). Стеки имеют большое приложение для синтаксического анализа, поэтому они будут рассматриваться более подробно.



Рис. Линейные списки: а – стек; б – очередь; в – дек.

Простейший способ хранения списка в памяти – размещение элементов в последовательных ячейках один за другим. Такой способ называется последовательным распределением. Если LOC(Y(j)) - адрес j-го элемента описка, то при последовательном распределении: LOC(Y(j)) = Lo+cj, где Lo - адрес начала описка, c - длина узла. Последовательное распределение очень удобно при работе со  стеком. 

Более гибкой по сравнению с последовательным распределением является схема, в которой каждый узел содержит связь со следующим узлом списка. Такое распределение называется связанным. FIRST – указатель на первый узел списка.





Рис. Связанное распределение

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





Рис.  Включение элемента 1* в связное распределение (X – означает пустую связь).

Лекция 9

Человеко-машинный интерфейс



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

	аппаратное обеспечение

	программное обеспечение

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

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

В программном обеспечении прослеживается четкая иерархия по отношению к аппаратным ресурсам. Различают программы нижнего и высокого уровней.

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

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

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

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

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

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

 Операционная система MS-DOS

Операционная система MS-DOS корпорации Microsoft была разработана специально для IBM PC и выпускается с 1981 года. Ее характеризует предельная простота и минимальные требования к аппаратным ресурсам ПК: даже последние версии 6.х системы нормально функционируют, если компьютер оснащен оперативной памятью больше 128 Кб, монохромным текстовым дисплеем и любым процессором Intel 80x86.

Операционная система MS-DOS состоит из следующих компонентов: базовая система ввода-вывода (BIOS); блок начальной загрузки (Boot Record); модуль расширения базовой системы ввода-вывода (IO.SYS); модуль обработки прерываний (MSDOS.SYS); командный процессор (COMMAND.COM); утилиты (внешние команды).

Базовая система ввода-вывода находится в постоянном запоминающем устройстве (ПЗУ), установленном внутри системного блока, т.е. имеет аппаратно-программную реализацию. Остальные модули могут находиться на дисках.

Блок начальной загрузки всегда размещается в нулевом секторе нулевой дорожки любого диска. Модули IO.SYS и MS-DOS.SYS также размещаются в определенной области дисковой памяти. При форматировании диска эту область можно зарезервировать для последующей записи модулем операционной системы.

Если проследить эволюцию операционной системы MS-DOS, то можно заметить, что ее развитие шло параллельно с развитием аппаратной части ПК, в то время как идеология оставалась прежней, ориентированной именно на эту часть и сама по себе не представляла какой-либо ценности.

В июне 1991 года фирма Microsoft опубликовала новую версию DOS 5.0. В этой версии в значительной степени учитываются возможности новых микропроцессоров. В настоящее время повсеместно применяется MS-DOS версии 6.22.

Параллельно с DOS фирма Microsoft занималась также разработкой графического интерфейса (оболочки) Windows. Версия Windows 3.0 появилась в мае 1990 года, а в 1992 года на рынке появилась версия Windows 3.1.

Операционная система Windows разрабатывается корпорацией Microsoft с ноября 1983 года, однако ее первая промышленная версия появилась лишь спустя два года – в ноябре 1985 и не вызвала у пользователей и программистов заметного интереса. Положение не исправила и вторая версия Windows (1987 год) и лишь с появлением версии 3.0 (в мае 1990 года) начался настоящий "бум Windows", который продолжается и по сей день.

Фактически системные функции MS-DOS в большинстве прикладных программ используются только на уровне обслуживания файловой системы, которая, кстати доказала свою эффективность. Все остальные функции «нормальных» операционных систем – обслуживание аппаратных ресурсов и их разделение (для многозадачных ОС) – в основном обеспечиваются прикладными программистами. В результате программы становятся аппаратно зависимыми, а любой серьезный пакет сопровождается обязательной программой инсталляции, требующей ответа на многочисленные вопросы об особенностях конфигурации конкретного ПК (в текстовом процессоре WordPerfect, например, предусмотрена встроенная поддержка более чем 200 типов различных принтеров).

В этом смысле название «операционная оболочка» кажется более правильным. В промышленной версий Windows 3.1 реализованы следующие функции, отсутствующие или неразвитые в MS-DOS:

	поддержка графики. В отличие от MS-DOS Windows в принципе ориентирована на графический режим работы дисплея и требует обязательного наличия в ПК графического адаптера типа EGA, VGA, SVGA;

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

	обеспечение независимости прикладных программ от аппаратных ресурсов ПК. Прикладная программа ничего не знает об объеме оперативной памяти, типе графического адаптера, клавиатуры или принтера – согласование ее запросов с наличными ресурсами берет на себя Windows;

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

	объектно-ориентированный диалог с пользователем. Windows избавляет пользователя от заучивания команд, вместо этого в ней используете принцип «указать на объект – указать действие с ним» (приблизительно так же реализуется работа в привычном Norton Conmander);

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

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

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

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

Windows может работать в трех режимах – реальном, стандартном и расширенном (версия 3.1 использует только стандартный и расширенный режимы). Режим выбирается автоматически в момент загрузки Windows на основе анализа типа центрального процессора, но может быть изменен после ее запуска по команде пользователя.

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

Операционная среда Windows 95 состоит из аппаратных устройств компьютера и следующих программных средств:

	диспетчера виртуальных машин (Virtual Machine Manager, VMM);

	виртуальных устройств (Virtual Devices, VxDs);

	ПЗУ (ROM) базовой системы ввода-вывода (Basic Input and Output System, BIOS);

	устанавливаемых драйверов устройств (installable device drivers) и резидентных программ (Terminate and Stay Resident, TSRs);

	программ Microsoft MS-DOS;

	16- и 32-разрядных Windows-приложений.

Лекция 10

Основные понятия системы программирования. Турбо Си

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

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

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

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

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

Система Турбо Си разработана фирмой Borland International для микропроцессоров серии 8086 (в частности, для IBM PC и совместимых с ними ПЭВМ), работающих с операционной системой MS-DOS. В этой системе, согласно концепции Турбо, применяется новая схема быстрой компиляции, проводимой в значительной мере в оперативной памяти с редкими обращениями к магнитным дискам. Качественно новый эффект быстрой компиляции делает экономичной многократную модификацию программ. В системе Турбо Си внесены некоторые изменения в сам язык Си, новая версия которого называется тоже Турбо Си.

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

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

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

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

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

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

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

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

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

Текст на Си или просто текст, заключенный в скобки /* и */, компилятором игнорируется.

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

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

Во многие программы на Си подставляются один или несколько файлов. Появление директив

#include <файл_1>

#include “файл_2”

…

приводит к тому, что препроцессор подставляет на место этих директив тексты файлов файл_1, файл_2, … соответственно.

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

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

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

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

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

main ( int argc, char* argv[] )

Код, задающий тело функции main, заключается в фигурные скобки { и }. Общая структура функции main такова : 

main( )

{

…

}

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

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

int number_of_marbles,

	   number_of_pebbles;

float weight;

int exam_score;

char ch;

В первом описании имеется список переменных, содержащих два имени (number_of_marbles и number_of_pebbles). Обе переменные описываются как целые (int). Переменная exam_score целого типа и описана отдельно, хотя ее можно и добавить к первому списку целых переменных.

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

Переменные можно инициализировать в месте их описания. Поясним сказанное примером

int height = 71;

float income = 26034.12,

        bank_balance = 4052.67,

        time;

Переменным height, income и bank_balance присваиваются начальные значения, а переменной time не присваивается.

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

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

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

double cube ( double x )

{

   return x*x*x;

}

Аргумент x типа double специфицируется вслед за первой открывающей скобкой. В соответствии с более старым стандартом K&R Си описание этой функции выглядело бы так:

double cube ( x )

double x;

{

   return x*x*x;

}

В Турбо Си для достижения совместимости прежних программ на Си вверх разрешено использовать старый стандарт K&R.

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

	

/* Заголовки и комментарии, описывающие программу */



/* Директивы include */

#include имя_файла_1

…

#include имя_файла_n



/* Макро */

#define макро_1 значение_1

…

#define макро_n значение_n



/* Описание глобальных переменных */

тип_данных глобальная_переменная_1;

…

тип_данных глобальная_переменная_k;





main()

{

/* Описание extern, обеспечивающее ссылку вперед на функции и используемые в теле функции main */



/* Описание локальных переменных */

тип_данных локальная_переменная_1;

…

тип_данных локальная _переменная_m;



/* Тело функции main */

…

}



/* Функции, используемые в программе main */



тип_данных имя_функции_1( формальные параметры )

{

/* Описание extern, обеспечивающее ссылку вперед на функции и используемые в теле данной функции */



/* Описание локальных переменных */

тип_данных локальная_переменная_1;

…

тип_данных локальная _переменная_u;



/* Тело функции – 1 */

…

}

…

тип_данных имя_функции_p( формальные параметры )

{

/* Описание extern, обеспечивающее ссылку вперед на функции и используемые в теле данной функции */



/* Описание локальных переменных */

тип_данных локальная_переменная_1;

…

тип_данных локальная _переменная_r;



/* Тело функции – p */

…

}

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

Отметим, что Турбо Си реализует достаточно совершенный стандарт для языка Си. В Турбо Си имеется сильная поддержка работы в среде MS-DOS для процессора 80х86, реализованная в виде расширений языка, которые обычно не представлены в других реализациях Си. Использование указанных расширений делает немобильной часть системы или всю систему, реализованную в Турбо Си. Однако предоставляемые при этом преимущества могут иметь для программиста решающее значение.

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



Лекция 11

Структура простой программы на Си

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

#include<stdio.h>

main( )                   /*Простая программа*/

{

 int num;



num=1;

printf(“Я простая”);

printf(“вычислительная машина.\n”);

printf(“Мое любимое число %d , потому что оно самое первое.\n”,num);

}

	Результат работы программы на экране выглядит следующим образом:

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

	Мое любимое число 1, потому что оно самое первое.

Сделаем просмотр исходного текста программы.  

#include<stdio.h> - включение текстового файла.

Эта строка указывает компилятору, что нужно включить информацию, содержащуюся в файле  stdio.h   

main() – имя функции.

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

/* Простая программа*/ - комментарий.

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

{ - начало тела функции.

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

int num ; - оператор описания.

С помощью такого оператора мы объявляем, что в программе будет использоваться переменная num , принимающая целые (int) значения.

num=1; - оператор присваивания.

Этот оператор присваивает переменной num значение 1.

printf(“Я простая”); - оператор вывода на дисплей.

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

printf(“вычислительная машина.\n”); - оператор вывода на дисплей.

Этот оператор добавляет слова : вычислительная машина в конце предыдущего вывода. Комбинация символов \n указывает функции printf  на начало новой строки.

printf(“Мое любимое число %d , потому что оно самое первое.\n”,num); - оператор вывода на дисплей.

Этот оператор выводит на дисплей значение переменной num 

( равное 1), содержащееся во фразе в кавычках. Символы %d указывают функции printf где и в какой форме выводить значение этой переменной num.

} – конец определения (тела) функции.

Закрывающей фигурной скобкой заканчивается текст программы.



Основные элементы программирования

	Целью большинства программ является обработка данных на ЭВМ по алгоритму, заданному программой. Таким образом для решения задачи (обработки данных) необходимо:

	ввести информацию (данные) в программу (ЭВМ);

	иметь (задать) место в основной памяти для хранения данных;

	задать инструкции (программу) по обработке данных;

	вывести обработанные данные (результат) из программы пользователя (ЭВМ) на внешние машинные носители.

Инструкции по обработке данных можно организовать таким образом, что : 

	некоторые из них выполняются только тогда, когда какое-либо условие (набор условий) истинно;

	другие повторяются некоторое число раз;

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

Мы описали семь основных элементов программирования: ввод, типы данных , операторы, вывод, условное выполнение, циклы и подпрограммы. 

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

Типы данных – это константы, переменные и структуры, которые содержат числа (целые и с плавающей точкой), текст (символы и строки), адреса (переменных и структур).

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

	Ввод – означает чтение (ввод) данных с клавиатуры, магнитного диска или порта ввода-вывода.

	Условное выполнение – выполнение определенного набора инструкций, если указаны условие (выражение) истинно, или пропуск данного набора инструкций, если условие ложно.

	Циклы – выполнение набора инструкций определенное число раз или пока некоторое условие (выражение) истинно.

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

        

Вывод

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

printf (<форматная строка>,<аргумент>,<аргумент>,…);     

Форматная строка – это строка, которая начинается и заканчивается двойными кавычками (“вот так”). Целью функции printf является вывод этой строки на экран. До вывода аргументы функции преобразуются в соответствии со спецификаторами формата, указанными в форматной строке. Например, 

	printf (“Сумма равна %d \n”, sum);

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

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

	%u – беззнаковое целое

	%p – значение указателя

	%f – с плавающей точкой

	%e – с плавающей точкой в экспоненциальной форме

	%c  - символ

	%s  - строка

	%x – целое в шестнадцатиричном формате.

	Ширина поля может быть указаны цифрой, помещенной между знаком % и буквой. Например, десятичное поле шириной 4 символа будет указано так: %4d. Значение будет напечатано выровненным вправо. Итак, между знаком % и буквой можно поместить модификаторы спецификации преобразования. Если одновременно используются несколько модификаторов, то они должны быть указаны в порядке приведенным ниже:

Модификатор 			Значение

_				Аргумент будет печататься с левой позиции

				(%_10d)

строка цифр		Задает минимальную ширину поля (%4d).

Большее поле используется если число не помещается в исходном поле

строка цифр                    Определяет точность для данных с плаваю

щей точкой, т.е. число цифр справа от десятичной точки (%4.2f)

l				Соответствующий элемент данных имеет 

тип long, а не int (%ld).

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

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

puts (“Здравствуй, мир”);  

 Эта функция выводит на экран строку, оканчивающуюся символом перехода на новую строку. Обратите внимание, что символ \n в конце выводимой строки отсутствует, так как он добавляется самой функцией.

	Функция putchar выводит на экран один символ и не добавляет символ \n. Функция имеет формат:

	putchar (‘символ’);

Char x;

putchar (x); эквивалентна printf (“%c”, x);





Лекция 12



Типы данных

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

Данные в Си могут быть четырех основных типов: целые числа, числа с плавающей точкой, текст и  указатели: 

	целые числа – это числа, используемые для счета (1,-21,752)

	числа с плавающей точкой имеют дробную часть (3.14159) или экспоненту (2.579Е+24)

	текст состоит из символов (‘a’,’H’,’s’) и строк (“Привет”)

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

В языке Си переменные целого типа описываются ключевым

словом int, а также short int и long int. В Турбо-Си эти типы  данных занимают 16 бит (short), 16 бит (int), 32 бита (long). Переменную целого типа можно объявить беззнаковой с помощью  модификатора unsigned, например,

 unsigned int х;    

	Данные с плавающей точкой в Си описываются типом float (32 бита) или double (64 бита).

	Тип данных char (8 бит) определяет целые числа без знака в диапазоне от 0 до 255. Обычно такое целое размещается в одном байте памяти. В ЭВМ используется код ASCII для перевода этих чисел в символы и обратно. Таблица кода ASCII  позволяет представлять в памяти машины  256 различных символов (вводимых с клавиатуры или выводимых на печать). Для описания символьных переменных  применяется ключевое слово char , например, 

	char x,y;

	char z = ‘s’;        

Символьные константы в программе пишутся в апострофах (z = ‘t’;).

	Символьная строка – это последовательность из одного или более символов. Например,

	“Строка символов”.

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

	В первом способе используется массив символов, например, 

char msg[30];

Число [30] в квадратных скобках после идентификатора msg указывает компилятору на необходимость зарезервировать место для 29 символов, т.е. организовать массив из 29 переменных типа char 

(30-м  символом будет нулевой символ \0, который называется нуль-символ и отмечает конец строки). Сама переменная msg не содержит символьного значения, в ней находится адрес ячейки памяти в которой хранится первая из 29 переменных типа char. 

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

	Во втором способе используется указатель или ссылка на символ. Например, 

	char *msg;   

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

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

 - char, int, float         - предопределенные типы данных;

 - main		    - основная функция программы;

 - msg, x, y                 - переменные, определенные пользователем;

 - printf, puts              - библиотечные функции.

	Все идентификаторы должны начинаться с буквы (a…z или A…Z) или с символа подчеркивания ( _ ). В идентификаторе могут использоваться и цифры. Идентификаторы зависят от регистра, т.е. компилятор различает буквы верхнего и нижнего регистра. Например, следующие 3 идентификатора: indx, Indx, INDX различны. Идентификаторы различаются по первым 32 символам. 



Лекция 13



Операторы

	Для манипуляции данными в языке Си  имеются многочисленные операторы.

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

           Переменная= выражение;

В языке Си присваивание обозначается знаком равенства ( = ).

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

	Язык Си поддерживает стандартный набор бинарных арифметических операций:

умножение       - ( * )

деление             - ( / )

взятие остатка – (%)

сложение          - ( + )

вычитание        - ( - )

и операцию унарного минуса ( a + ( - b ) ), которая выполняет дополнение до двух.

	Оператор инкремента ( ++ ) позволяет добавить единицу к любому значению, а оператор декремента ( -- ) – вычесть единицу.

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

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

	sum = a + b++;

	sum = a + ++b;

Первая строка производит следующие действия: складываются значения переменных a и b, результат вычисления присваивается переменной sum, затем переменная b увеличивается на единицу. Вторая строка делает следующее: значение b увеличивается на единицу, значение a складывается с b, результат сложения присваивается переменной sum.

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

cдвиг влево   -  ( << )

сдвиг вправо – ( >> )

И – ( & )

ИЛИ – ( I )

исключающее ИЛИ – ( ^ )

НЕ – ( ~).

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

	Язык Си  поддерживает два адресных оператора: 

оператор взятия адреса ( & ) и косвенный оператор ( * ).

	Оператор & возвращает адрес переменной: если sum есть переменная типа int, тогда &sum есть адрес (ячеки памяти) этой переменной. Если msg есть указатель (ссылка) на переменную типа char, тогда *msg есть символ, на который указывает msg.













Лекция 14



Ввод

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

	Функция scanf предназначена для интерактивного ввода данных с клавиатуры. Она имеет формат анологичный функции printf:

	scanf(<форматная строка>,<адрес>,<адрес>,…);

Эта функция использует многие спецификаторы формата, рассмотренные ранее: %d для целых чисел, %f для чисел с плавающей точкой, %s для строк и т.д. Однако у этой функции есть важная отличительная черта: за форматной строкой следуют не значения а адреса. Например,

	scanf(“%d  %d”, &a, &b);

Эта строка означает, что программа ожидает ввода двух десятичных целых значений, разделенных пробелом. Первое значение введется по адресу переменной a (&a), а второе – по адресу переменной b.

	Для ввода строковых данных в языке Си имеется функция gets, имеющая формат

	gets(name);

Эта функция воспринимает любую информацию до тех пор, пока не нажмете клавишу Enter. В конце введенной строки добавляется функцией нулевой символ \0.

	Для ввода единичного символа в языке Си имеется функция getch, которая считывает с клавиатуры один символ. В отличие от функций scanf  и gets функция считанный символ не передает в основную память, а сама принимает значение символа, считанного склавиатуры. Таким образом значение функции getch может быть присвоено переменной типа char например, 

	char x;

	x = getch();





Лекция 15

Условные операторы

	Рассмотрим операторы отношения и логические операторы, которые принимают значения true (истина) и false (ложь).

	Операторы отношения позволяют сравнивать два значения, результат оператора зависит от того, истинно или ложно сравнение. Если сравнение ложно, значение результата равно нулю, если истинно, значение равно единице. В языке Си следующие операторы отношения:

больше чем            -  >

больше или равно  - >=

меньше чем            - <

меньше или равно - <=

равно                      -  = =

не равно                 -  !=

	Например, выражение b < 0 принимает значение true если значение переменной b меньше нуля.

	В языке Си имеются три логических оператора: И(&&), ИЛИ(II) и НЕ(!). Их необходимо отличать от побитовых операторов (&, I, ~). Логические операторы выполняются над логическими значениями true и false, а побитовые операторы – над нулями и единицами, находящимися в битах. Логические операторы дают результат или равный 1 (истина) или равный 0 (ложь).

	Оператор if в языке Си имеет следующий формат:

	if (выражение)

		оператор 1;

	else 

		оператор 2;

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

	if (выражение)

		оператор 1;

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

	Если вместо оператора 1 стоит последовательность операторов, то ее надо записать в фигурных скобках. Это и будет составным оператором в языке Си. Составной оператор имеет вид:

{

оператор

оператор

………..

оператор

}



Циклы.

В языке Си имеются три вида циклов: while, for, do…while. 

Цикл while является наиболее общим видом цикла и имеет формат:

while (выражение)

	оператор;

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

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

	for (выражение1; выражение2; выражение3)

		оператор;

Выражение1 присваивает начальное значение параметру цикла.

Выражение2 проверяет условие продолжения цикла.

Выражение3 модифицирует параметр цикла на шаг.

Оператор может быть простым или составным.

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

	Цикл do … while реализует итерационный циклический вычислительный процесс и имеет следующий формат:

	do  оператор while (выражение);

Выполняется оператор (тело цикла) и вычисляется выражение, если оно принимает значение истина, то тело цикла выполняется вновь, если оно принимает значение ложь - происходит выход из цикла.



Лекция 16



	Подпрограммы

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

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

/*Объявление функций*/

void get_parms (float *p1, float *p2);

float get_ratio (float divident, float divisor);

void put_ratio (float ratio);



const float INFINITY = 3.4E+38



/*Начало программы*/

main()

{

float a, b, ratio;

char ch;

do 

     {

      get_parms (&a, &b);        /*Ввод параметров*/

      ratio = get_ratio(a, b);      /*Вычисление ratio*/

      put_ratio(ratio);               /*Вывод ответа*/

      printf (‘’Нажмите клавишу ’q’ , то выход, любую другую - продолжение ‘’);

     } while ((ch = getch()) != ’q’);

}

/*Конец функции main*/



/*Определение функций*/

void get_parms (float *p1, float *p2)

{

printf(‘’ Введите два числа: ‘’);

scanf (‘’%f %f ‘’, p1, p2);

}         



float qet_ratio(float divident, float divisor)

{

if (divisor = = 0.0)

    return (INFINITY);

else

    return (divident / divisor);      

}



void put_ratio(float ratio)

{

if (ratio = = INFINITY)

    printf (‘’Отношение не определено\n‘’);

else

    printf (‘’Отношение  = %f \n ‘’, ratio);

}

	

	

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

	В следующей строке определяется константа с плавающей точкой INFINITY ( в языке Си принято обозначать глобальные константы символами верхнего регистра). Эта константа имеет очень большое положительное значение и используется для сигнализации об ошибке деления на ноль. Так как она определена здесь, область ее видимости распространяется на все функции, включая main. Далее идет функция main (головной модуль), т.е. основная часть программы. Каждая программа на языке Си имеет функцию main. При вызове программы операционной системой (или запуск из Турбо-Си ) управление передается функции main, из нее же происходит и возврат управления в операционную систему. В процессе выполнения головного модуля (функции main) осуществляется обращение к  подпрограммам (функциям). 	После функции main идут определения трех функций, объявленных в разделе прототипов. 

	Функция get_parms не возвращает значения, поэтому она объявлена типа void. Ее целью является ввод двух значений по некоторым адресам. Мы должны передать функции get_parms два параметра. Эти параметры суть адреса, по которым будут храниться значения переменных. Посмотрите: тип этих параметров не float , ссылка на тип float, т.е. эти параметры считаются адресами переменных типа float. 

	Именно эти адреса мы и передаем при вызове функции get_parms из функции main - &a, &b. Обратите внимание также, что при вызове встроенной функции scanf из функции get_parms перед переменными p1 и p2 нет адресных операторов. Это потому , что p1 и p2 уже являются адресами переменных a и b. 

	Функция get_ratio возвращает значение типа float , вычисленное на основе двух переданных ей значений типа float (divident - делимое и divisor - делитель). Возвращаемое значение зависит от того равен делитель нулю или нет. Оператор return присваивает возвращаемое значение имени функции get_ratio.

	Функция put_ratio не возвращает значение , поэтому она определена   типа void и не имеет оператора return. Ее единственный параметр ratio определяет выводимую на экран информацию.



Глобальные описания

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



Комментарии

	Иногда необходимо вставить в текст программы пояснения, служащие для напоминания (разъяснения) читателю о том , что означают конкретные переменные, что делают некоторые операторы и т.д. Такие пояснения называются комментариями. Начало комментария /*, после такого знака компилятор игнорирует всю информацию до появления знака */ - конец комментария.



Лекция 17

Команды потока управления

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

Оператор return позволяет прервать выполнение функции. Используется в двух случаях:

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

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

Оператор break используется для аварийного выхода из цикла.

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



Массивы

	Язык Си позволяет определять массивы (т.е. индексированные списки) данных определенного типа. Например, 

	int x [20];

объявляет двадцать переменных типа int. Общий вид объявления любого массива:

	тип имя [количество];

Первый элемент массива имеет индекс 0. Например, x[0].



Структура

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

	typedef struct

	{

	char name[25];

	char class;

	short subclass;

	float x, y, z;

	} star;

Таким образом мы объявили структуру (struct) типа star. Поместив это объявление в начале программы, мы можем объявлять в модулях переменные типа star. Эти переменные будут структурами. Например, 

	star a, pol;





Библиографический список

Кривоногов М.Б. Информатика. Учебное пособие. Тула: ТулГУ, 1999.89с.

Уэйт М. И др. Язык СИ. Руководство для начинающих. М.: Мир, 1988. 512c

Берри Р., Микинз Б. Язык СИ. Введение для программистов. М.: Финансы и 

    статистика, 1988. 191c.

	

	

	

	

Рассмотрено на заседании кафедры ПМиИ



Протокол № 3  от  17.11.1999г.



Зав. кафедрой ______________ В.И.Иванов