Лекция №5. Использование современных интегрированных сред для создания программ.
Особенности различных интегрированных систем разработки программ. Приемы и использование средст автоматизации разработки программных продуктов.
19.2. Структура окна VC++ 6.0
В стандартном окне среды выделяются три области:
· Project Workspace – окно рабочего пространства проекта,
· рабочая область – служит для редактирования модулей проекта,
· Output – окно сообщений, предназначенное для вывода сообщений о результатах компиляции и отладки.
Окно рабочего пространства проекта Project Workspace предназначено для отображения структуры проекта и для организации быстрого доступа к каждому элементу структуры. Термин Workspace (рабочее пространство) обозначает контейнер, куда помещаются связанные между собой проекты. При создании нового проекта можно создать новое рабочее пространство или включить создаваемый проект в созданное ранее рабочее пространство.
Информация, относящаяся к рабочему пространству, сохраняется в файле *.dsw, а информация о конкретном проекте – в файле *.dsp. Открытие в среде любого проекта начинается с открытия рабочего пространства, т. е. с файла *.dsw.
В окне рабочего пространства Project Workspace включаются три панели: ClassView, ResourceView, FileView.
Панель ClassView содержит дерево классов. С помощью этой диаграммы можно получить доступ к объявлению класса, определению метода любого класса или какой-либо самостоятельной функции.
Панель ResourceView отображает ресурсы, используемые проектом; к ресурсам относятся рисунки, иконки, диалоговые панели, меню, горячие клавиши, строки. Диаграмма представляет собой набор папок, каждая из которых соответствует какому-либо одному виду ресурсов. Все ресурсы помещаются в папки, соответствующие виду ресурса.
Панель FileView отображает файловый состав проекта, диаграмма на панели FileView представлена в виде набора папок, содержащих:
Source Files – файлы c кодами программы и имеющими тип *.cpp,
Header Files – заголовочные файлы,
Resource Files – файлы ресурсов.
Двойной щелчок левой кнопкой мыши на любом элементе диаграммы в окне Project Workspace приводит к появлению в рабочей области окна соответствующего файла в текстовом редакторе или изображения ресурса в графическом редакторе ресурсов.
Окна Project Workspace и Output можно активизировать при помощи команды меню View/Workspace и View/Output.
К началу главы
19.3. Создание проекта
Проект представляет собой группу файлов, в которых размещены код и ресурсы программы. Для создания проекта используется специальное приложение – AppWizard – Мастер приложений.
AppWizard позволяет создавать несколько типов приложений, приведем краткую характеристику некоторых из них:
MFC AppWizard(exe) – наиболее часто используемый тип приложения – приложение на базе библиотеки классов MFC,
MFC AppWizard(dll) – динамическая библиотека на базе библиотеки классов MFC,
Win32 Application – приложение, использующее библиотеку Win32 API,
Win32 Console Application – консольное приложение, т. е. приложение с минимальным интерфейсом, использующее для вывода результатов на экран окно, аналогичное окну MS-DOS в текстовом режиме,
Win32 Dynamic-Link Library – динамическая библиотека на базе библиотеки Win32 API,
Win32 Static Library – статическая библиотека на базе библиотеки Win32 API.
Последовательность действий при создании проекта следующая:
· вызвать AppWizard с помощью команды File/New;
· выполнить настройки будущего проекта в окне New/Projects. В этом окне нужно указать, какой тип проекта будет создан, его расположение (диск, каталог) и имя. AppWizard создаст в указанном каталоге каталог с именем проекта и в нем разместит файлы проекта. Также на этом шаге определяется, создается ли новое рабочее пространство WorkSpace или проект включается в рабочее пространство, открытое в данный момент в среде.
Дальнейшие действия будут зависеть от типа выбранного приложения. Создание некоторых типов приложений будет рассмотрено отдельно.
Чтобы закрыть проект, можно воспользоваться командой File/Close Workspace.
К началу главы
19.4. Редактирование проекта
На различных этапах работы с проектом возникает необходимость добавления файлов в проект или исключения их из проекта.
Добавление файла выполняется уже знакомой командой File/New… Эта команда создает новый файл и включает его в соответствующий раздел проекта на диаграмме File View в зависимости от типа создаваемого файла. На экране появляется окно New, но теперь в этом окне активна панель Files. Панель Files позволяет выбрать тип файла, задать его имя, указать расположение файла и проект, в который надо включить файл. По умолчанию файл включается в текущий проект и помещается в его каталог.
Добавление в проект созданного ранее файла можно выполнить командой Add Files to Folder, которая доступна через контекстное меню диаграммы FileView. Этой же командой можно добавить новый файл, при этом он сначала включается в проект, а потом по вашему требованию создается на диске.
Удаление файла из проекта выполняется просто клавишей Delete клавиатуры. Следует отметить, что это действие не приводит к удалению файла с диска.
К появлению новых файлов в проекте приводит также выполнение других команд, например, добавление класса в проект.
Для добавления в проект класса используется команда Insert/New Class… В открывшемся диалоговом окне указываем имя класса и при необходимости базовый класс, если для создания нового класса будем использовать механизм наследования. Результатом этих действий будет появление двух файлов со служебным кодом класса. Первый – заголовочный файл, содержит объявление класса, в раздел public которого включены конструктор без параметров и деструктор. Второй файл *.cpp содержит заготовки для конструктора и деструктора. Размещение кода класса в двух файлах отражает принцип сокрытия данных в модуле: код, помещаемый в заголовочный файл (имена класса и его свойств и методов из разделов public и protected) доступен объектам программы, в то время как прямой доступ к определению методов запрещен, код методов доступен только через заголовочный файл класса.
Пример файлов, генерируемых VC++ 6.0 при создании нового класса с именем person:
Файл person.h
// person.h: interface for the person class.
//
///////////////////////////////////////////////////
#if!defined(AFX_PERSON_H_8B9715F9_A4AA_4628_9547_10684C42D0BD_INCLUDED_)
#define AFX_PERSON_H__8B9715F9_A4AA_4628_9547_10684C42D0BD__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif //_MSC_VER > 1000
class person
{
public:
person();
virtual ~person();
};
#endif //!defined(AFX_PERSON_H__8B9715F9_A4AA_4628_9547_
10684C42D0BD //__INCLUDED_)
Файл person.cpp
//person.cpp: implementation of the person class.
//
///////////////////////////////////////////////////
#include "person.h"
///////////////////////////////////////////////////
// Construction/Destruction
///////////////////////////////////////////////////
person::person()
{
}
person::~person()
{
}
Редактирование класса также выполняется специальными командами. Эти команды доступны через контекстное меню диаграммы классов ClassView и позволяют добавить в класс свойство или функцию. Для добавления свойства надо выделить редактируемый класс и выбрать команду Add Member Variable… , в открывшемся окне указать тип свойства, его имя и раздел класса, куда это свойство следует включить (public, protected или private). Для добавления функции выбирается команда Add Member Function… , для функции указывается тип возвращаемого значения, имя функции и в скобках список параметров, раздел класса, в который надо включить функцию. Если функция без параметров, скобки после имени функции можно не ставить, они будут добавлены автоматически.
При вводе и редактировании программы большую помощь оказывает контекстная подсказка в виде всплывающих примечаний, которые появляются, если навести курсор мыши на какой-либо идентификатор в тексте программы. Такая подсказка дает краткую информацию об элементе программы, например, тип переменной, список аргументов функции. Для получения более подробной справки следует обращаться в специальную справочную библиотеку MSDN (Microsoft Developer Network), которая представляет собой самостоятельный программный продукт и устанавливается в дополнение к среде VC++. Для VC++ 6.0 требуется установка версии MSDN Library 2003. Доступ к информации из библиотеки осуществляется нажатием функциональной клавиши F1.
К началу главы
19.5. Компиляция и выполнение программы
Компиляция проекта может быть запущена с помощью панели инструментов, горячих клавиш или главного меню. Рассмотрим возможности по управлению процессом компиляции с помощью команд меню.
Build/Compile – компиляция файла, находящегося в активном окне,
Build/Build – компиляция всех файлов проекта, которые были созданы или изменены после последней компиляции.
Build/Rebuild All – компиляция всех файлов проекта без исключения. Иногда после внесения изменений в проект и компиляции в режиме Build не удается получить желаемый результат. В этом случае рекомендуется выполнить компиляцию с помощью команды Rebuild All.
Build/Execute – запуск приложения. Если хотя бы один из файлов после последней компиляции был изменен, то среда вначале предложит выполнить компиляцию, при этом на экране появляется сообщение: One or more files are out of date or do not exist. Would you like to build them? Ваш ответ Yes запустит компиляцию, затем выполнение программы, ответ No вызовет выполнение программы без компиляции.
Компиляция и редактирование связей могут выполняться в двух режимах: Debug – режим отладки и Release – режим готового продукта (реализация). При компиляции с использованием режима Debug в объектные и загрузочный модули включается отладочная информация, что увеличивает размер этих файлов. Так, элементарный проект на базе библиотеки MFC в режиме Debug занимает около 7 Мбайт дисковой памяти, тогда как в режиме Release – около 6 Мбайт. Выбор режима компиляции осуществляется с помощью команды Build/Set Active Configuration. По умолчанию среда устанавливает режим Debug. Режим Release используется на завершающем этапе разработки проекта перед передачей готового приложения заказчику.
К началу главы
19.6. Файловая структура проекта
Файлы проекта (рис. 19.1) помещаются (если не задано иначе) в специальном каталоге, имя которого совпадает с именем проекта. В каталог помещаются исходные файлы проекта, содержащие код программы (*.cpp, *.h), файл ресурсов (*.rc) и файлы, организующие проект (*.dsp, *.dsw). Там же создается каталог Debug или Release в зависимости от выбранного режима компиляции, в которые записываются все результаты компиляции, выполняемый (*.exe) файл и отладочная информация. Если в проекте используются ресурсы (например, рисунки или иконки), то для них создается каталог res.
Рис. 19.1. Примерная файловая структура проекта Lab1
Информация в каталогах Debug и Release перезаписывается при каждой компиляции, поэтому содержимое этих каталогов, как и сами каталоги, можно удалить, тем более что они занимают много места на диске.
Замечание. Если вы хотите перенести ваш проект на другой компьютер, не берите с собой не только каталоги Debug или Release, но и файлы *.dsp, *.dsw, так как в них прописаны пути, соответствующие вашему компьютеру, и поэтому эти проекты на новом компьютере, возможно, работать не будут. Просто на новом компьютере создайте новый проект, в который включите в соответствующие разделы файлы, перенесенные с вашего компьютера, откомпилируйте проект, после чего ваша программа должна восстановить свою работоспособность.
К началу главы
19.7. Создание консольного приложения
Как уже было сказано ранее, Win32 Console Application – консольное приложение, используемое для вывода результатов на экран окно, аналогичное окну MS-DOS в текстовом режиме.
Этапы создания консольного приложения:
· выполнение команды File/New…,
· настройка параметров проекта в окне AppWizard/Projects,
· тип приложения – Win32 Console Application,
· имя проекта (Name),
· размещение проекта (Location),
· флажок создания нового рабочего пространства в состоянии «установлен»,
· выбор вида консольного приложения.
Мастер AppWizard позволяет создать четыре вида приложений.
An empty project – пустой проект, для этого вида приложения мастер создает только файлы *.dsp, *.dsw. Файлы с кодом программы не создаются, и их надо добавлять вручную. В окне Project Workspace такого проекта на диаграмме ClassView нет ни одного элемента, а диаграмма FileView содержит пустые папки Source Files, Header Files и Resource Files. Этот вид приложения может быть использован как для создания объектно-ориентированной программы, так и алгоритмической.
A simple application – простое приложение, в которое включен файл, содержащий функцию main(), и служебный модуль со стандартным именем StdAfx, состоящий из двух файлов: заголовка stdafx.h и реализации stdafx.cpp. Такой проект может быть откомпилирован и выполнен несмотря на то, что функция main() не содержит никаких действий. Чтобы это приложение выполняло какие-нибудь действия, надо отредактировать функцию main() и, если надо, добавить в проект модули. Данный вид приложения может быть также использован для создания как объектно-ориентированной программы, так и алгоритмической.
A "Hello, world!" project – готовое приложение, выводящее на экран сообщение "Hello, world!". Имеет такой же файловый состав, что и предыдущее приложение, только тексты файлов stdafx.h и stdafx.cpp несколько изменены. Так, в stdafx.h подключается заголовочный файл stdio.h, необходимый для вывода текста на экран с помощью функции printf(). Этот вид приложения может быть использован как образец готового приложения, а может быть отредактирован для решения какой-либо задачи.
An application that supports MFC – приложение, использующее классы библиотеки MFC, применяется только для разработки объектно-ориентированных программ. Имеет более сложный файловый состав, что связано с особенностями проекта на базе MFC.
Как видно, в проектах используется модуль StdAfx, создаваемый мастером AppWizard для каждого приложения. Этот модуль предназначен для создания так называемых прекомпилированных файлов (*.pch), которые повышают производительность компиляции. Заголовочный файл stdafx.h включается в каждый исходный файл проекта первым и содержит директивы include для подключения библиотек C++. Таким образом, каждый модуль проекта имеет возможность использовать подключенные библиотеки, при этом во время его компиляции не требуется выполнять обработку файлов заголовков, поэтому, он может быть скомпилирован быстрее.
Оба файла модуля StdAfx помещаются в папку проекта. В процессе работы над проектом они могут быть отредактированы пользователем, например, в stdafx.h можно добавить подключение заголовочных файлов с помощью директивы include. Место вставки директив помечено словами:
//TODO: reference additional headers your program requires here.
Рассмотрим два примера создания консольного приложения – на основе пустого проекта и простого приложения, использующего класс пользователя.
Пример 1. Вычислить значение переменной y = log x, где значение переменной x вводится с клавиатуры.
Последовательность действий:
· открыть VC++ 6.0 и выполнить команду File/New;
· в окне File/Projects указать:
- тип приложения – Win32 Console Application,
- имя проекта – lab1,
- место размещения проекта – E:work,
- нажать кнопку ОК;
· на следующем шаге выбрать вид консольного приложения – An empty project;
· соглашаться со всем, что предлагает среда, в результате мы получим каркас проекта, в котором нет ни одного файла. При этом на диске будет создан каталог с именем lab1;
· добавить файл типа *.cpp для размещения функции main(): перейти в окно FileView, выделить папку Source Files (источники) и выполнить команду File/New;
· в окне File/New выбрать тип файла C++ Source File и указать его имя lab1.cpp. Этот файл будет помещен в каталог проекта lab1. На диаграмме файл lab1.cpp будет помещен в папку Source Files;
· на диаграмме Source Files дважды щелкнуть левой кнопкой мыши на файле lab1.cpp, файл будет открыт в текстовом редакторе среды.
· ввести в файл текст программы:
#include <stdio.h>
#include <math.h>
int main(void)
{
puts("Enter number");
float num;
scanf("%f",&num);
float y10=log10(num);
printf("Num=%.2f,Dec.Log=%.2f",num,y10);
return 0;
}
Замечание. В тексте программы неслучайно для сообщений, выводимых на экран, использовались латинские символы. Дело в том, что текстовый редактор использует для кириллицы кодировку Windows, а окно выполнения программы – кодировку ASCII для MS-DOS. Если использовать кириллицу для вывода сообщений, тексты на экране нельзя будет прочитать. Можно тексты сообщений ввести с помощью редактора для MS-DOS, но тогда эти тексты нельзя будет прочитать в редакторе среды. Так что ищите компромисс!
· сохранить текст файла;
· откомпилировать проект, для этого можно воспользоваться кнопкой на панели инструментов с изображением восклицательного знака (команда Execute). Проект сначала будет откомпилирован, затем выполнен. Если в тексте программы компилятор найдет ошибки, то выведет их в окно Output панели Build. Если в панели Build дважды щелкнуть мышью на ошибке, среда покажет место ошибки в тексте программы. Исправление ошибок всегда надо начинать с первой ошибки, так как остальные ошибки могут оказаться следствием первой;
· в окне программы ввести данные, получить результат:
Num=34.00,Dec.Log=1.53 Press any key to continue
· завершить программу нажатием любой клавиши на клавиатуре.
Как видно, остановка программы перед ее завершением специально не программировалась, но тем не менее эта возможность получена.
Пример 2. Разработать класс принтеров, характеризующийся следующими свойствами: наименование модели, год выпуска, цена. Конструктор класса должен обеспечивать создание объектов с различными значениями свойств. Класс также должен обеспечивать изменение цены принтера во время работы программы. В составе класса также надо предусмотреть метод для просмотра характеристик принтера. Результаты работы программы выводить на экран. Для решения задачи использовать консольное приложение A simple application.
Последовательность действий для решения задачи:
o открыть VC++ 6.0 и выполнить команду File/New;
o в окне File/Projects указать:
- тип приложения – Win32 Console Application,
- имя проекта – lab2,
- место размещения проекта – E:work,
- нажать кнопку ОК;
o на следующем шаге выбрать вид консольного приложения A simple application;
o оставить без изменения настройки проекта, предложенные средой. В результате получим каркас проекта, в который будут включены файлы lab2.cpp, stdafx.h и stdafx.cpp, помещенные в каталог проекта с именем lab2, и функция main();
o добавить в проект класс Insert/New Class, в окне New Class указать информацию о классе: имя класса (окно Name) – Printer.
После выполнения этих действий в проект будут включены два файла, образующие модуль класса Printer. Первый файл Printer.h содержит объявление класса Printer, второй Printer.cpp – определения методов класса Printer. Просмотрите эти файлы и изучите состав класса, предлагаемый средой. Класс включает в себя только два члена: конструктор Printer() и деструктор ~Printer(), помещенные в раздел public, причем в файле Printer.cpp эти методы представлены в виде заготовок, которые представляют собой заголовок метода и пустое тело {} функции:
Файл Printer.h:
class Printer
{
public:
Printer();
virtual ~Printer();
};
Файл Printer.cpp:
#include "stdafx.h"
#include "Printer.h"
///////////////////////////////////////////////////
// Construction/Destruction
///////////////////////////////////////////////////
Printer::Printer()
{
}
Printer::~Printer()
{
}
· отредактировать объявление класса Printer – добавим свойства класса, для этого выделим на диаграмме ClassView заголовок класса Printer, вызовем контекстное меню класса, выполним команду Add Member Variable (добавить переменную – член класса), в открывшемся окне укажем тип переменной (свойства) – char, название – model[20] (model – собственно название свойства – модель принтера, [20] – количество элементов типа char в значении свойства), укажем раздел класса, в который надо включить свойство, – private. Аналогично введем в класс свойства year (год выпуска, тип int), cost (цена принтера, тип float). Теперь просмотрим текст файла, он должен быть таким:
class Printer
{
public:
Printer();
virtual ~Printer();
private:
float cost;
int year;
char model[20];
};
· отредактировать конструктор класса – изменим в объявлении класса заголовок конструктора: добавим параметры: _model, _year, _cost, типы которых соответствуют одноименным свойствам класса Printer. Отредактируем определение конструктора – добавим список параметров в заготовке и выполняемые действия (инициализацию переменных класса) в тело конструктора. Так как свойство класса model должно содержать строку текста и заполнить его можно функцией strcpy, в текст файла Printer.cpp добавим директиву include для подключения заголовочного файла string.h. Деструктор оставим без изменения или совсем удалим. В результате мы должны получить следующий текст:
Файл Printer.h:
class Printer
{
public:
Printer(char* _model,int _year,float _cost);
virtual ~Printer();
private:
float cost;
int year;
char model[20];
};
Файл Printer.cpp:
#include "stdafx.h"
#include "Printer.h"
#include <string.h>
///////////////////////////////////////////////////
//Construction/Destruction
///////////////////////////////////////////////////
Printer::Printer(char* _model,int _year,
float _cost)
{
strcpy(model,_model);
year=_year;
cost=_cost;
}
Printer::~Printer()
{
}
· добавим в класс методы: show – для просмотра свойств класса; set_cost – для изменения цены принтера. Добавление метода выполним через диаграмму ClassView: выделим на диаграмме заголовок класса Printer, вызовем контекстное меню класса, выполним команду Add Member Function (добавить функцию – член класса), в открывшемся окне укажем тип функции (function type) – void, заголовок функции (function declaration) – show() (метод для просмотра свойств класса), раздел класса, в который надо включить метод – public. Если функция без параметров, в окне function declaration можно указать имя функции без скобок, скобки будут добавлены автоматически. После нажатия кнопки ОК на экране появится текст файла Printer.cpp с выделенным заголовком только что созданной функции show(). Ввести в тело функции show() следующий код:
cout << model <<" "<< year <<" "<< cost << endl;
· чтобы объект-поток cout был доступен в файле Printer.cpp, подключим через директиву include заголовочный файл iostream.h;
· аналогично добавим второй метод set_cost(), изменяющий значение цены принтера. Этот метод будет иметь параметр – новое значение цены принтера, поэтому при вводе информации в окно function type введите тип функции – void, в окне function declaration укажите следующее: set_cost(float new_cost), включите функцию так же, как и предыдущую, в раздел public. Добавьте код функции:
cost=new_cost;
В результате должен получиться следующий текст файла Printer.cpp:
#include "stdafx.h"
#include "Printer.h"
#include <iostream.h>
#include <string.h>
///////////////////////////////////////////////////
// Construction/Destruction
///////////////////////////////////////////////////
Printer::Printer(char* _model,int _year,
float _cost)
{
strcpy(model, _model);
year = _year;
cost = _cost;
}
Printer::~Printer()
{
}
void Printer::show()
{
cout << model <<" "<< year <<" "<< cost << endl;
}
void Printer::set_cost(float new_cost)
{
cost=new_cost;
}
· отредактировать файл lab2.cpp, содержащий заготовку для функции main: добавим директиву препроцессора include для подключения заголовочного файла Printer.h, без которого невозможно создавать объекты класса Printer, затем добавим в функцию main код, выполняющий следующую последовательность действий: создание объекта класса Printer, просмотр его свойств, изменение цены принтера и повторный просмотр свойств. В результате текст файла lab2.cpp будет следующим:
#include "stdafx.h"
#include "Printer.h"
int main(int argc,char* argv[])
{
Printer printer("Canon",2003,700.0);
printer.show();
printer.set_cost(650.5);
printer.show();
return 0;
}
Замечание. Если бы функция main() использовала для вывода информации поток cout, заголовочный файл iostream.h лучше было бы подключать в файле stdafx.h, тогда поток cout был бы доступен во всех модулях, где подключен stdafx.h, и не требовалось бы дополнительного подключения iostream.h в файле Printer.cpp. Место вставки директив include, подключающих заголовочные файлы, в тексте файла stdafx.h обозначено следующим комментарием: //TODO:reference additional headers your program requires here.