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)
А
также:
Цикл
разработки
ПО с точки зрения
программиста: (?Начальная
идея)
->Подготовка
текста программы
в редакторе
-> Запуск
компилятора
->Возврат:Анализ
и исправление
ошибок
->Получение
загрузочного
модуля
->
Выполнение
загрузочного
модуля
->
Возврат:Анализ
и исправление
ошибок
->…
и так далее
Интегрированная
среда разработки
ПО объединяет
все этапы в
единую технологическую
цепочку, помогает
программисту
на каждом этапе
цикла разработки
ПО.
Не
путать интегрированную
среду и компилятор
языка программирования!
Компилятор
– отдельная
программа для
преобразования
исходного
текста в исполняемый
код программы.
Компилятор
запускается
на одном из
этапов разработки.
Он существует
отдельно от
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)
Рекомендации
по управлению
файлами проекта:
Необходимо
обеспечить
сохранность
исходных файлов
проекта *.cpp,
*.h, *.bpr,
*.bpg, *.bpf. Желательно
располагать
файлы каждого
проекта в отдельной
директории.
Необходимо
хранить одну
или более предыдущих
версий работы
(для этого создается
специальная
директории
архива, традиционное
название - BACUP).
Желательно
перенаправить
промежуточный
вывод *.obj,
и результирующий
вывод *.tds,
*.exe во
вспомогательные
директории
на локальном
диске, т.е. не
смешивать с
исходными
текстами: Project->Options->Directories->Intermediate
output/Final
output Эти
файлы желательно
удалять по
завершении
сеанса работы.
Присваивайте
файлам мнемонически
значимые имена
- это помогают
поддерживать
порядок в работе.
Архивирование
и удаление
файлов рекомендуется
делать по завершении
этапа работ
(занятия).
Отладка
в интегрированной
среде С++ Builder.
Цель
отладки – локализация
и устранение
ошибок, приводящих
к неверному
функционированию
программ.
Т.
е. программа
уже откомпилирована,
|