Лекции по основам программирования на C/C++
Вид материала | Лекции |
СодержаниеРекурсивные функции. Лекция 17.Принципиальные особенности программирования в среде MS DOS и Windows |
- Рабочая программа учебной дисциплины (модуля) Язык программирования Java, 90.39kb.
- Курс лекций по основам программирования Учебно-методическое пособие, 726.7kb.
- Рабочая программа дисциплины: б б 7 Конструирование программного обеспечения для направления, 156.05kb.
- Рабочая программа по курсу "Программирование на языках высокого уровня" Факультет экономический, 113.19kb.
- Тест по алгоритмизации и основам программирования. Фамилия, имя, 41.04kb.
- Программа элективного курса «Программирование на языке Pascal» 10 класс, 63.48kb.
- Учебной дисциплины «Технология программирования и работ на эвм» для направления 010100., 38.85kb.
- Лекция 3 Инструментальное по. Классификация языков программирования, 90.16kb.
- Лекция Языки и системы программирования. Структура данных, 436.98kb.
- Методика обучения основам программирования на уроках информатики X-XI классов, 96.07kb.
Лекция 16. Использование виртуальных методов
Давайте для начала вспомним, как в классическом программировании на С вы можете передать объект данных в функцию. Ничего сложного в этом нет, надо только задать тип передаваемого объекта в то время, когда вы пишете код функции. То есть, чтобы описать поведение объектов, необходимо заранее знать и описать их тип. Сила ООП в этом случае проявляется в том, что вы можете писать виртуальные методы так, чтобы объект сам определял, какой метод ему необходимо вызвать, во время выполнения программы.
Говоря иными словами - с помощью виртуальных методов объект сам определяет свое поведение (собственные действия). Технику использования виртуальных методов как раз и называют полиморфизмом. Буквально полиморфизм означает обладание многими формами. Объект в вашей программе в действительности может представлять не один класс, а множество различных классов, если они связаны механизмом наследования с общим базовым классом. Ну и поведение объектов этих классов в иерархии, конечно же будет разным.
Как известно, согласно правилам С++, указатель на базовый класс может ссылаться на объект этого класса, а также на объект любого другого класса, производного от базового. Понимание этого правила очень важно. Давайте рассмотрим простую иерархию неких классов А, В и С. А будет у нас базовым классом, В - выводится (порождается) из класса А, ну а С - выводится из В. Пояснения смотрите на рисунке.
В программе объекты этих классов могут быть объявлены, например, таким образом.
A object_A; //объявление объекта типа А
B object_B; //объявление объекта типа В
C object_C; //объявление объекта типа С
Согласно данному правилу указатель типа А может ссылаться на любой из этих трех объектов. То есть ,вот это будет верным:
A *point_to_Object; // объявим указатель на базовый класс
point_to_Object=&object_C; //присвоим указателю адрес объекта С
point_to_Object=&object_B; //присвоим указателю адрес объекта В
А вот это уже не правильно:
В *point_to_Object; // объявим указатель на производный класс
point_to_Object=&object_А; //нельзя присвоить указателю адрес базового объекта
Несмотря на то, что указатель point_to_Object имеет тип А*, а не С* (или В*), он может ссылаться на объекты типа С (или В). Может быть правило будет более понятным, если вы будете думать об объекте С, как особом виде объекта А. Ну, например, курица - это особая разновидность птиц, но она все таки остается птицей, хоть и не летает. Конечно, эта взаимосвязь объектов и указателей работает только в одном направлении. Объект типа С - особый вид объекта А, но вот объект А не является особым видом объекта С. Возвращаясь к курице смело можно сказать, что если бы все птицы были особым видом кур - они бы просто не умели летать!
Этот принцип становится особенно важным, когда в классах, связанных наследованием определяются виртуальные методы. Виртуальные методы имеют точно такой же вид и программируются так же, как и самые обычные методы. Только их объявление производится с ключевым словом virtual. Например, наш базовый класс А может объявить виртуальный метод class A
{
public:
virtual void v_function(void);//метод описывает некое поведение объектов //класса А
};
В классе может объявляться столько виртуальных методов сколько вам потребуется. И находится они могут в любой части класса - закрытой, открытой или защищенной.
Если в классе В, порожденном от класса А нужно описать какое-то другое поведение, то можно объявить виртуальный метод, названный опять-таки v_function().
class B: public A
{
public:
virtual void v_function(void);//замещающий метод описывает некое
//новое поведение класса В
};
Когда в классе, подобном В, определяется виртуальный метод, имеющий одинаковое имя с виртуальным методом класса-предка, такой метод называется замещающим. Виртуальный метод v_function() в В замещает виртуальный метод с тем же именем в классе А.
Ну, а теперь самое важное!
Вернемся к указателю point_to_Object типа А*, который ссылается на объект object_В типа В*. Давайте внимательно посмотрим на оператор, который вызывает виртуальный метод v_function()для объекта, на который указывает point_to_Object.
A *point_to_Object; // объявим указатель на базовый класс
point_to_Object=&object_B; //присвоим указателю адрес объекта В
point_to_Object->v_function(); //вызовем метод
Указатель point_to_Object может хранить адрес объекта типа А или В. Значит во время выполнения этот оператор point_to_Object-gt;v_function(); вызывает виртуальный метод класса, на объект которого он в данный момент ссылается. Если point_to_Object ссылается на объект типа А, вызывается метод, принадлежащий классу А. Если point_to_Object ссылается на объект типа В, вызывается метод, принадлежащий классу В. Итак, один и тот же оператор вызывает метод класса адресуемого объекта. Это и есть действие, определяемое во времени выполнения.
^ Рекурсивные функции. Функция называется рекурсивной, если ее значение для данного аргумента определяется через значения той же функции для предшествующих аргументов. В программировании функция называется рекурсивной, если последовательность операторов, составляющих тело функции, включает в себя один или несколько вызовов самой этой функции.
Рассмотрим более подробно организацию и работу рекурсивных подпрограмм.
Рекурсию можно использовать для вычисления факториала n!. Чтобы найти n!, нужно определить (n-1)!. А для этого необходим (n-2)! и так далее.
#include
#include
int z;
int Fact(int n)
{
if (n == 1) return 1;
else return Fact(n - 1) * n; }
main()
{ int n;
printf("Число? \n");
scanf("%d",&n);
z = Fact(n); printf("%d",z);
}
^ Лекция 17.Принципиальные особенности программирования в среде MS DOS и Windows
Поговорим о принципиальных особенностях программирования в среде MS DOS и Windows.
Значительная часть времени в программировании уходит на про-граммирование внешних устройств. Причем под внешними устройствами понимается и работа с памятью, файловой системой, дисплеем, клавиатурой, мышью и т.д. Основным отличием операционной системы Windows от MS DOS является то, что управление всеми внешними устройствами Windows берет на себе. Ниже на рисунке представлена схема взаимодействия приложения с внешними устройствами в системах MS DOS и Windows
Внешние устройства
MS DOS
Прямое обращение к ВУ
Приложение
Системные вызовы
Внешние устройства
Windows
Системные вызовы (API-функции)
Приложение
Беря на себя взаимодействие с внешними устройствами Windows позволяет создавать более надежное и совместимое программное обеспечение.
Вторым преимуществом операционной системы Windows является ее многозадачность. Все задачи, запускаемые в ОС оказываются совершенно равноправными по отношению к рессурсам микропроцессора. Замечательно и то, что многозадачность возможна и в рамках одной задачи, когда две функции могут выполняться параллельно и независимо друг от друга.
Еще одной особенностью програмирования в среде Windows является присутствие только одной модели памяти. в Windows используется так называемая линейная или плоская модели памяти. Суть этой модели заключается в том, что содержание всех сегментных регистров фиксируется, а адресация осуществляется с помощью 32-битных регистров. Такая модель основывается на так называемой страничной адресации в защищенном режиме. Для программирования это дает значительные преимущества, заключающиеся в том, что поскольку сегментом теперь является вся память, то снимаются все ограничения на размер кода, данных, стека и объема отводимого под локальные переменные.
Литература:
1. Б. Керниган, Д. Ритчи. Язык программирования Си. - М.: Финансы и статистика, 1992.
2. Страуструп Б. Язык программирования СИ++. - М.: Радио и связь,1991.352с.
3. Ричард Вайнер, Льюс Пинсон С++ изнутри. - Киев: ДиаСофт,1993.
4. Е.И. Козелл,Л.Ь. Романовская, т,В. Русс и др. От С к С++. М., Финансы и статистика, 1993
5. Шилд Г. Программирование на С и С++ для WINDOWS 95.-К.:Торгово- издательское бюро BHV, 1996.-400с.
6. Шилд Герберт. Самоучитель С++.-BHV.-С.-Петербург.,1997.