Главная              Рефераты - Информатика

Объектно-Ориентированное программирование - реферат

I. Развитие языков программирования

Определения:

ANSI – American National Standards Institute - Национальный Институт Стандартизации США

ISO - International Organization for Standardization - Международная организация по стандартизации

Цель развития языков программирования - более рациональная разработка ПП.

Схема развития:

Коды процессора а assembler а языки высокого уровня (ЯВУ)
Сначала из истории:

При разработке процессоров(П)/микропроцессоров – для каждого П разрабатывается набор команд, полный набор насчитывает ~150 команд: арифметика, логика, работа с памятью, ввод и вывод.

Команда для процессора – это цифровой код команды и операнд (операнды):

ячейки памяти, регистры, порты ввода/вывода...

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

Разработка программ в кодах была характерна для самых первых ВМ – это очень неудобно для человека-программиста.

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

Assembler использует мнемоническое обозначение кодов команд процессора и переменных памяти, что облегчает процесс программирования по сравнению с кодированием:
JUMP - переход, ADD - сложение, IN - ввод, OUT – вывод, и т.д. для всех команд процессора.
Assembler позволяет использовать весь набор команд процессора и напрямую работать с регистрами.
Используется там, где необходима высокая эффективность: ядро ОС, драйверы, программы, работающие в реальном времени.

Недостатки – высокая трудоемкость разработки, привязка программы к конкретному типу процессора.

Языки высокого уровня – FORTRAN, ALGOL, COBOL, PL/I, ADA, Prolog, PASCAL, C, C++, Perl, JavaScript, ASP, PHP, Java, С#, SQL…

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

Среди ЯВУ есть специализация: научные расчеты (FORTRAN), для обучения (ранний Basic, Pascal), экономические рачеты (COBOL), работа с БД (dBase, FoxPRO, SQL) ,
целое семейство сравнительно молодых языков для Internet (JavaScript, ASP, PHP),
языки системного программирования (ранний С, assembler’ы).
Некоторые языки считаются универсальными (поздний Pascal (Delphi), C/C++)

II. Развитие технологий разработки программ
Схема:

Низкоуровневое программирование (коды, Assembler’s) а
аПроцедурное/Cтруктурное программирование (Algol, Pascal, C) а

аООП (C++,Object PASCAL, Java, C#…) а

а…(что дальше?)

Вспоминаем, как обстояло дело с разработкой программ в 60-е – 70-е годы,
технологическая ступенька называлась:

Процедурное программирование

Основная идея – выделение части кода в отдельную процедуру (подпрограмму, функцию) (SUBROUTINE в FORTRAN, PROCEDURE и FUNCTION в PASCAL).

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

Пример:
real sin(real x){

// здесь реализация

}

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

  • передача параметров в процедуру и возврат значений,

  • рекурсивность, т.е. возможность процедуры вызывать саму себя (известная задача о Ханойской башне),

  • хранение подпрограмм в отдельных библиотеках.


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

  • Последовательность операторов/блоков,

  • Ветвление или выбор if, if..else, swith-case

  • Циклы: с постусловием (do while), цикл с предусловием (while)


Каждая из базовых конструкций имеет один вход и один выход.

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

Причем, любую программу можно и нужно писать без использования оператора GoTo, который очень запутывает структуру программы (аналог – команда перехода JMP в assembler).
Для исключения оператора GoTo достаточно применять базовые конструкции “цикл” - не всегда это удобно, но почти всегда оправдано.

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

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

На базе принципов структурного программирования (СП) был создан новый, элегантный язык PASCAL (примерно 1968 г, Никлаус Вирт)
Проанализируем программирование на PASCAL с позиций СП.
Базовые конструкции СП внесены в язык: IF..[ELSE], CASE, WHILE, REPEAT..UNTIL.
Для описания сложных типов данных в языке есть массивы, записи (RECORD), множества.

!Важно:

Структура программы на Pascal состоит из разделов:

  • Uses - включение модулей

  • Const – раздел констант

  • Type – описание новых типов данных (конструирование)

  • Var – объявление (выделение памяти под реальные переменные)

  • Процедуры – реализуют автономные фрагменты вычислений

  • Главная программа – Реализует полный алгоритм решения задачи.

PASCAL жестко навязывал программистам использование стиля СП – это был переход на новый технологический уровень в разработке программ общего назначения (обработка данных, научные расчеты) – это был технологический прорыв.
Пожалуй, все последующие реализации ЯВУ, включали конструкции СП.
Разработка в стиле СП имеет накладные расходы (по сравнению с assembler), код программы получается больше за счет избыточных проверок в циклах и отсутсвия GoTo – это был основной аргумент противников СП (в основном, противниками были программисты на assemblere).


Cтруктурное программирование на С/С++

На прошлом занятии говорили о СП, акцентировали основные положения:
процедурное П, П с исп. базовых конструкций СП, структура программы на PASCAL.

Сложнее всего следовать стилю СП было на assembler’s.

Язык С(Си) создан в конце 60-х - начале 70-х для разработки системного ПО в рамках проекта ОС Unix (Деннис Ричи – один из авторов).

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

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

С дает большую свободу действий, но требует от программиста большей самодисциплины.
Многие программисты на assembler в 80-е годы перешли на C.

В настоящее время С универсальный язык программирования для разработки системного ПО (Unix и Windows), графических интерфейсов, сложного прикладного ПО (например, СУБД) - задач, где необходима эффективность выполнения программ.

С – распространен, компиляторы реализованы в большинстве ОС.

В каждой реализации UNIX есть компилятор С/С++ как важная часть ОС.
C++ является объектно-ориентированным расширением языка C.

Первая широко известная реализация принципов ООП – это описание языка С++, начало 80-х, автором является Бьярне Страуструп.

Кроме компиляторов в каждой Unix-подобной системе распространены компиляторы
Borland C++ и Microsoft C++ для платформы Windows,

В 1997 г был принят международный стандарт ANSI C/C++ - итог 20-тилетнего развития

Существующий стандарт ANSI C++ - это классическое описание ООП.

Сейчас язык С++ является языком публикаций по вопросам ООП.

Практикум на С/С++:
Фактически С++ содержит 2 языка:
Полностью включает низкоуровневый Си, поддерживающий конструкции СП, и, собственно, С++ (Си с классами) – язык объектно-ориентированного программирования (ООП).

Мы находимся сейчас на технологической ступени структурного программирования, поэтому начинаем с Си:

Знакомство с С, некоторые конструкции СП:


0.Программа выводит на экран строку "Hello? World".

#include // подключение заголовочного файла, в котором описаны функции i/o printf и getc

void main(){ // в программе всегда д.б. функция main, с нее начинается выполнение

printf("Hello, World!");

getc();

}

1.// Комментарий до конца строки

/* Комментарий много-

строчный. В С/С++ отличаются прописные и строчные буквы.

*/


2.Операторные скобки {} задают программный блок.


int i=5; // выделение памяти и присваивание значения
{

int i=7;

..

if(i<7){...}; // не выполнится

}

if(i<7){...} // выполнится

// i внутри блока и i вне блока – это разные переменные


3. Цикл
for(int i=0; i<100; i++){

...

if(...)

break; // прервать цикл

}


if(i<99){...} //error, i не определено


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

bool fOk=true; // true/false

int a, b=7;

...

fOk=(a==b); // вычисляется логическое значение a==b и присваивается

...

if(fOk){

//... выполняется, когда логическое выражение true

}

else{

//... выполняется, когда логическое выражение false

}


5. Цикл с постусловием и выбор.


char c; // 1 byte

bool fOk;

do{ // Начало цикла с постусловием

fOk=true;

printf(”Вы любите программировать?\n”);

printf(”Ответ Д/Н/?:”);

c=getc();


switch(c){ //

case ‘Д’: printf(“Yes, sir”);

break;

case ‘Н’: printf(“No”);

break;

case ‘?’: printf(“Не знаю”);

break;

default:

printf(“*Ошибка, повторите ввод”);

fOk=false;

}

}

while(!fOk); // Конец цикла с постусловием


6. Структуры.
Структуры в Си служат для конструирования новых типов сложных данных
(Павловская с.67, Березин. с 124)
struct Student{ // описание нового типа данных Student

char Name[51];

int Age;

char Course;

char Group[4]; // ПЭ2х
float Ball; //Average; // Средняя оценка

float S; // Стипендия

}; //! Важно, в конце описания структуры ставится точка-с-запятой;


Student S1, S2; // Объявление двух переменных (выделение памяти)

// Занесение значений в элементы структуры:

S1.Age=21;

S1.Kurs='2';

S1.S=550.5;

strcpy(S1.Name,"Мистер Х."); // Копирование строки в строку структуры


Student PE21[50]; // Массив структур

strcpy(PE21[0].Name,"Lady Y");

PE21[0].Age=17;

...

for(int i=0; i<50; i++){ // Начисление стипендии

if(PE21[i].Ball>=4.0)

PE21[i].S=400.0;

else

PE21[i].S=0.0;

}

Недостатки массивов – жесткие рамки

Усложнения:
Повышенная стипендия при 4.5
Расчет среднего бала по группе

расчет суммы стипендии по группе


C/C++ Функция. Модуль. Проект. Заголовочный файл.


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

Процедура – выполняет часть кода, не обязательно возвращает результат.


В С/С++ нет процедур – только функции. Функции не могут быть вложенными.

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


[<тип возвр.значения>] <имя функции>([список параметров]){

// тело функции (body)

return [<возврашаемое значение>];

}

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

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


// Пример функции вычисления среднего:

float Average(float a, float b){

return (a+b)/2;

}

void main(){

//…

float A=10.5, B=11.7, C=0.0;

C=Average(A, B); // Вызов функции

//…

}

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

В качестве описания можно применить объявление прототипа (прототип/заголовок/интерфейс функции - синонимы), т.е. указать имя функции, список передаваемых параметров и тип возвращаемого значения, например:
float Average(float a, float b); // Прототип функции вычисления среднего


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

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

int Summ(int A, int B); // вычисление суммы для int

float Summ(float A, float B); // вычисление суммы для float


В программе С/С++ должна быть функция main (главная) – именно она вызывается при запуске программы на выполнение:

int main(int argc, char* argv[]){ // ДЗ: разобраться с параметрами main

// int argc – число параметров в командной строке
//
char* argv[] – массив строк, где каждая строка – параметр из
// командной строки.
argv[0] – имя программы.
//...
Здесь реализация, и возврат значения, например так:

if(fOk)

return 0; //возвращение кода завершения

else

return -1; //возвращение кода завершения

}

Параметры функций.


Параметр, или аргумент – это значение, передаваемое в функцию.

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

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

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


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

Это неудобно в следующих случаях:

  • когда передается большой массив, структура (создание копии параметра занимает много времени и памяти).

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


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

Изменение значения параметра приводит к изменению исходной переменной.


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


Примеры:


// 1.Функция сохраняет значения структуры в файле

bool SaveToFile(TStudent S){ // Это передача параметра по значению,

//... // создается локальная копия параметра

FILE *outS;

outS=fopen(PathOutFile, "at");

//...

fprintf(outS, "%s %s \n",S.Name, strAge );

//...

fclose(outS);

return true;

}


// 2.Функция читает значения из файла в структуру и возвращает ввод

bool InputFromFile(TStudent &S){ // Это передача параметра по ссылке,

//... // иначе ввод будет потерян

FILE* inS;

inS=fopen(PathInFile,"rt");

scanf(inS,"%s", &S.Name);

//...

return true;

}


ДЗ Самостоятельно: функции, параметры, возвращаемые значения; функция main;
в книга: Паловская, стр 73, Березин, стр. 108.


Модуль.
Модуль в С/С++
– это отдельно компилируемый файл, который может содержать: описание типов, объявлений переменных и констант, код функций.
Имя модуля есть имя файла c расширением *.cpp (*.c).

Оптимальный размер модуля, удобный для разработки и отладки – 200-400 строк текста.
Если текст программы велик, то его делят на несколько модулей и объединяют модули в проект.

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


Здесь схема модуля C++, сравнение со структурой программы на Pascal

Проект C/C++ - это средство для объединения модулей в единую программу или библиотеку. Целью разработки проекта может быть не только программа, но и библиотека функций, библиотека классов.

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

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


В IDE Borland C++ есть средства ведения проекта: окно проекта, пункт меню Project.

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

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


Заголовочные файлы. Препроцессор С/С++.

Обычно для модуля C/C++ разрабатывается заголовочный файл, в котором описываются общие константы, типы данных, и объявляются прототипы функций.
Заголовочные файлы имеют расширение *.h или *.hpp (от Header - заголовок).

Имя заголовочного файла может совпадать или не совпадать с именем модуля.


Пример заголовочного файла (Student.h)

//-----------------------------------------------------------------

#define MIN_AGE 12 // Константы, часто используются такие описания

#define MAX_AGE 99


struct TStudent {

//... Описание нового типа данных TStudent

};


bool InputDataStudent(TStudent* S); // Прототипы функций

void OutputDataStudent(TStudent* S);

int AverageAge();

//-----------------------------------------------------------------


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


#include <имя заголовочного файла.h>


Препроцессор был разработан для языка C.

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

Например, на место #include <файл.h> подставляется содержимое этого файла,

по тексту программы производится замена макросов из #define MIN_AGE на 12, и т. д.


С системой программирования C/C++ поставляется множество библиотек, содержащих предопределенные константы, макросы, функции и классы.
Библиотеки поставляются вместе с заголовочными файлами. Заголовочные файлы многих библиотек находятся в директории ...\Include.
Текст заголовочных файлов является самой точной документацией по использованию функций, поставляемых в библиотеках. а Значит, необходимо уметь анализировать Header-файлы:


Приложение:

// Пример заголовочного файла (Student.h)

#ifndef STUDENT_H

#define STUDENT_H


#define MIN_AGE 12 // Константы, часто используются такие описания

#define MAX_AGE 99

typedef struct s{ // Описание новых типов данных

char Name[20];

int Age;

//...

} TStudent;

bool InputDataStudent(TStudent* S); // Прототипы функций

void OutputDataStudent(TStudent* S);

int AverageAge();

#endif

//-----------------------------------------------------------


#include

#define EOF (-1) /* End of file indicator */

#define MAX(a,b) ((a>b)? a : b) // Макрос


Макросы ненадежны, их контроль компилятором ограничен.

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


Ввод/вывод C/С++.

Ввод/вывод (Input/Output, I/O) – это операции обмена данными между программой и внешними устройствами.

Операции ввода/вывода инициирует программа, поэтому:

  • ввод – перемещение данных с внешнего устройства в программу (в структуру данных в ОП)

  • вывод - перемещение данных из программы на внешнее устройство (в файл, на экран, на печать)

Операции Assembler:

IN: взять байт из порта и поместить в ОП

OUT: взять байт из ОП и поместить в порт

Потоки и файлы

Файл (file) – это способ хранения информации на физическом устройстве:
дисковый файл, МЛ, распечатка, вывод на дисплей – это все файлы.

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

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

function I/O в программе а

а stream (поток) а

а file (файл на устройстве)

Поток (stream) – это абстрактный уровень взаимодействия между программой и физическим устройством.
Информация выводится в поток (вводится из потока) как последовательность байтов – символ за символом.
В момент открытия потока он связывается с файлом на конкретном устройстве.

В Си (не в С++) для этого служит управляющая структура потока FILE.

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

Потоки бывают буферизованные (блокированные) и небуферизованные (НЕблокированные).

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

Буферизованные потоки ввода производят опережающее чтение в буфер потока.

Буферизация служит для оптимизации вв/вывода (размер сектора на диске 512 байт, кластер. Для вв/вывода даже 1 байта необходимо записать/перезаписать сектор/кластер).

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

Для принудительного вывода при работе с буферизованными потоками есть специальная операция: fflush(...) – выравнивание, сброс на диск

Ввод/вывод в С

В описании языка Си нет операций ввода/вывода, они реализованы через функции.

Ключевые слова в названиях функций:

read/write – неформатированный вв/вывод, сплошной массив байт

get/put,

scan/print,

open/close

например:

printf, fprintf, sprintf - ключевые слова используются с различными префиксами – вывод в стандартный поток, вывод в файл, вывод в область памяти.


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

Охватить все в рамках занятий нереально, поэтому, ограничимся общими рекомендациями:

Что-то все-равно нужно знать аДокументация (общее представление) а Help а Заголовочный файл

Пример Си, вывод данных структуры в текстовый файл:


struct Student{

char* Name;

int Age;

};

Student AS[43];

//...


FILE *outS; // Объявление потока


outS=fopen("D:\\Data\\Person.dat", "wt"); // Открытие потока, связывание с файлом
//
режим write,text

for(int i=0; i<43; i++){

fprintf(outs,"%s, - ему %s лет\n", AS[i].Name, itoa(AS[i].Age) );

}


fclose (outS);

//--------------------------------


//--------------------------------

Student P;

FILE*InP=fopen("Person.dat", "rt"); // Открытие потока, связывание его с конкретным
//
файлом "Person.dat"

char* cAge[3]; //Временная переменая для ввода символьного числа, соответств. Age

fscanf(InP,"%s %s", &P.Name, cAge); // Ввод из файла через поток


//или

fgets(InP,P.Name);

fgetc(InP,cAge);


fclose(InP); // закрытие потока и файла.


Ввод/вывод в С++(начальные сведения)

Функции Си можно использовать в С++.

В С++ ввод/вывод определен через базовый набор классов, поставляемых с компилятором.

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

istream – поток для ввода

iostream - поток для ввода/вывода


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

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


Cтандартные потоки С++:

cin – стандартный поток ввода (консоль)

cout – стандартный поток вывода (консоль)

cerr – стандартный поток вывода ошибок небуферизированный

clog – стандартный поток вывода ошибок буферизированный

Стандартные потоки объявлять не надо.


Операция ввода из потока >> , операция вывода в поток <<
(это двойные угловые скобки)


Пример:

cout<<"Введите имя:"; // Вывод строки на консоль (в поток cout)

cin>>P.Name; // Ввод значения с клавиатуры через поток cin
// в переменную структуры
P

cout<<"\n"<<"Введено имя: "<<P.Name<<"\n";

Для освоения темы ввода/вывода в С++ необходимо разобраться с переопределением операций ввода/вывода для классов (см. "Практическую работу №2")

Потоковые классы, стандартные потоки, файловые потоки С++: Павловская, стр 265.


Схемы иерархии модулей в типичном проекте программы обработки данных.

Проект-проектирование.

Структура проекта – состав модулей и их взаимодействие.


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

Здесь типичная схема программы обработки данных:

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

Ввод данныха Обработка а Диалог с оператором а Сохранение данных


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


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

Далее вызывается модуль обработки, ему передаются данные ввода,

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

Диалог с оператором ведется по мере необходимости.


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

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


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


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


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


Рассмотрим процесс разработки программы.

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


TextС/С++-> PreProc-> Compile-> ObjectModule(*.obj)-> Link-> EXEModule

Edit Library(*.lib)->

(*.c,*.cpp,*.h) ЯDebugЯ

(см. также Павловская, стр 17)

TextEditor – создание текста исходных модулей проекта на языке программирования – "кодирование"( "кодировщики" - жаргон) Кодированию предшествует проектирование..

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

Object module(obj) – операторы исходного текста программы, преобразованные во внутреннее машинное представление – "код", инструкции процессора.
(формат кода отличается для каждой архитектуры).

Obj содержит откомпилированные операторы языка + вызовы функций.
Вызовы функций внутри obj называются “неразрешенные ссылки”:

например, это вызовы библиотечных функций printf, scanf, …, или вызовы разработанных ранее функций из другого модуля проекта.

Link – редактор связей, сборщик программы - производит сборку исполняемого модуля - execute module, exe - из одного или нескольких объектных модулей и библиотек.

При сборке в ехе -модуль из библиотек и других obj-модулей проекта заносится код функций, вызовы которых указаны в исходном тексте программы
– этот процесс называется “разрешение ссылок”.

Далее *.ехе запускается на выполнение, тестируется, отлаживается.


Замечания по стилю разработки и оформлению текстов программ

Комментирование

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

// Автор, ПЭ21, ДВГТУ, ООП, dd.mm.yy

// Проект, назначение модуля


Каждую функцию также следует предворять комментарием, если ее код не тривиален.

Тест для комментария – понятность для не посвященного в проблему специалиста.

Комментирование программ – профессиональный навык.
Хороший прием – сначала создавать скелетный код модуля из текстов комментариев и заголовков функций с пустым блоком реализации (функции заглушки).

Фрагмент текста программы (строку), который уже не используется, а удалять еще жалко – можно закомментровать.

Правила именования переменных

Имя может состоять из нескольких слов: каждое слово пишется с большой буквы, слова пишутся слитно;
Имя переменной/функции должно быть мнемонически значимо:

TCar, TAutobus

InputFromFileToPerson

Разумное комментирование и выбор имен придает текстам программы свойство самодокументированности.
Отступы как средство структурирования текстов:

Текст программы легче анализировать, когда он структурирован, разбит на блоки
Блок в программе – это фрагмент текста внутри фигурных скобок {…}.

Например: описание структуры, функция, тело цикла и др.
Любой вложенный в блок должен быть сдвинут вправо на табуляцию (обычно от 2 до 8 символов).

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

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

Комбинация клавиш < Ctrl+ {> и < Ctrl }> – позволяет контролировать блоки.

!Все без исключения практические работы необходимо оформлять по этим правилам
(см. также Павловская, стр 102-114)

C/C++. Интегрированная среда разработки фирмы Borland
(Используется в С/С++ Builder и в Delphi)

IDE - Integrated Development Environment

IDE для разных платформ разработки ПО:
Borland:
среда turbo-vision -> Turbo Pascal, Turbo C, СУБД Paradox
Delphi и Builder (Visual Component Library) СУБД Interbase, JBuilder -> Borland Studio

MS Visual Studio
IBM Visual Age

Linux (?) (Emacs)

Основные компоненты IDE:

  • специализированный редактор текста программ (многодокументное окно )

  • средства ведения проекта, состоящего из нескольких модулей (окно проекта)

  • система запуска компилятора (пункт меню, комбинация клавиш)

  • окно просмотра сообщений компиляции.

  • Help-система (!)

  • встроенный отладчик (Debuger)

А также:

  • визуальный конструктор форм

  • инспектор объектов (ООП)

  • Class explorer

  • Клиент для работы с БД

  • Графический редактор

  • и много других вспомогательных функций


Цикл разработки ПО с точки зрения программиста:
(?Начальная идея)

->Подготовка текста программы в редакторе

-> Запуск компилятора

->Возврат:Анализ и исправление ошибок

->Получение загрузочного модуля

-> Выполнение загрузочного модуля

-> Возврат:Анализ и исправление ошибок

->… и так далее


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


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

Компилятор – отдельная программа для преобразования исходного текста в исполняемый код программы.
Компилятор запускается на одном из этапов разработки.
Он существует отдельно от IDE, и может запускаться из командной строки (Unix).
Интегрированная среда не является обязательной – возможна разработка ПО отдельными инструментами: редактор текста, компилятор, редактор связей, отладчик.


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


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

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

Borland IDE – это современная профессиональная среда разработки, весьма сложная в освоении.


Начало работы в IDE:

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


Первоначально будем создавать программы, работающие в стиле DOS (WIN32) – текстовый режим консоли.Их называют также console applications.

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

Создание программ с графическим интерфейсом Windows – в перспективе, на следующей дсциплине.


Последовательность действий в IDE по созданию приложеня Console application:
Меню File->New-> Console Wizard - создание проекта (создается скелетная схема проекта, заготовка функции main), далее
->Собственно разработка текста программы

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

–> выполнение ЗМ с возможностью отладки.

Типы файлов (расширения), создаваемые системой IDE в проекте:


*.cpp, *.h - исходные тексты программы, исходные модули; этим файлам необходимо обеспечить максимальную защиту.

*.bpr, *.bpg, *.bpf – файлы проекта и группы проектов; (желательно сохранять, но проект легко можно собрать и заново из исходных модулей)

*.~cpp, *.~h *.~bpr - backup files (со знаком "тильда") – содержат копию исходного текста/проекта, предшествующую последней корректировке.

*.obj – объектные модули, промежуточный формат, создаются каждый раз при компиляции исходных модулей (опция настройки Intermediate output)

*.tds – временный файл отладчика, обычно это самый большой файл в проекте.

*.exe – загрузочный модуль, исполняемый модуль (опция настройки Final output)


Рекомендации по управлению файлами проекта:


  1. Необходимо обеспечить сохранность исходных файлов проекта *.cpp, *.h, *.bpr, *.bpg, *.bpf.
    Желательно располагать файлы каждого проекта в отдельной директории.
    Необходимо хранить одну или более предыдущих версий работы (для этого создается специальная директории архива, традиционное название - BACUP).

  2. Желательно перенаправить промежуточный вывод *.obj, и результирующий вывод *.tds, *.exe во вспомогательные директории на локальном диске, т.е. не смешивать с исходными текстами:
    Project->Options->Directories->Intermediate output/Final output
    Эти файлы желательно удалять по завершении сеанса работы.

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


Отладка в интегрированной среде С++ Builder.


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

Т. е. программа уже откомпилирована,