Препроцессорные средства в C и С++
Основные понятия препроцессорной обработки. Объектно-ориентированные средства С++. Объектные типы данных. Виртуальные функции. Шаблоны функций и классов. Классы для ввода-вывода потоков. Задачи по программированию на Си, по разработке систем объектов.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | курс лекций |
Язык | русский |
Дата добавления | 03.10.2008 |
Размер файла | 53,8 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
ostream _FAR & _RTLENTRY operator<< (short);
ostream _FAR & _RTLENTRY operator<< (unsigned short);
ostream _FAR & _RTLENTRY operator<< (int);
ostream _FAR & _RTLENTRY operator<< (unsigned int);
ostream _FAR & _RTLENTRY operator<< (long);
ostream _FAR & _RTLENTRY operator<< (unsigned long);
ostream _FAR & _RTLENTRY operator<< (float);
ostream _FAR & _RTLENTRY operator<< (double);
ostream _FAR & _RTLENTRY operator<< (long double);
Вывод строк, оканчивающихся нулевым байтом
ostream _FAR & _RTLENTRY operator<< (const char _FAR *);
ostream _FAR & _RTLENTRY operator<< (const signed char _FAR*);
ostream _FAR & _RTLENTRY operator<< (const unsigned char _FAR*);
Вывод значения указателя в символьном формате
ostream _FAR & _RTLENTRY operator<< (void _FAR *);
Извлечение данных их объекта streambuf и вставка в тот же ostream
ostream _FAR & _RTLENTRY operator<< (streambuf _FAR *);
Вывод значений манипуляторов
ostream _FAR & _RTLENTRY operator<<
(ostream _FAR & (_RTLENTRY *_f)(ostream _FAR &));
ostream _FAR & _RTLENTRY operator<<
(ios _FAR & (_RTLENTRY *_f)(ios _FAR &));
Имеется также класс iostream, производный от класса ios и объединяющий возможности классов istream и ostream.
Для рассмотренных выше классов отсутствуют конструкторы копирования и операция присваивания, точнее, они объявлены, но не определены. Для тех случаев, когда конструктор копирования и операция присваивания необходимы, предусмотрены классы istream_withassign, ostream_withassign и iostream_withassign. Как экземпляры объектов этих классов всегда объявляется объект cin (экземпляр istream_withassign), обычно предназначенный для ввода с клавиатуры, и объекты cout, cerr и clog (экземпляры ostream_withassign), обычно предназначенные для вывода на экран.
Ввод-вывод для дисковых файлов обепечивается классами, описания которых содержатся в файле fstream.h.
Класс filebuf, производный от streambuf, предназначен для добавления в streambuf дополнительных средств управления буфером ввода-вывода.
Класс fstreambase, производный от класса ios, служит базой для остальных классов, обеспечивающих файловый ввод-вывод, в нем определены методы:
void _RTLENTRY open(const char _FAR *, int, int = filebuf::openprot);
void _RTLENTRY attach(int);
void _RTLENTRY close();
void _RTLENTRY setbuf(char _FAR *, int);
Назначение этих методов очевидным образом следует из их названий.
Для непосредственной работы с файлами служат классы ifstream, ofstream и fstream, базой для них служат классы fstreambase и, соответственно, istream, ostream и iostream.
6.2. Вывод в файл. Ввод из файла
Для вывода данных в дисковый файл в программе должна присутствовать директива препроцессора
#include <fstream.h>
подключающая описания необходимых классов.
Прежде чем выводить данные необходимо создать объект типа ofstream, для которого имеется несколько конструкторов:
_RTLENTRY ofstream(); // Пустой объект, без привязки к файлу
// С привязкой к файлу, полное имя которого задается первым аргументом:
_RTLENTRY ofstream(const char _FAR *, int = ios::out,
int = filebuf::openprot);
// С привязкой к ранее открытому файлу, заданному своим дескриптором
_RTLENTRY ofstream(int);
// То же, что и предыдущий вариант, но задается новый буфер вывода
_RTLENTRY ofstream(int __f, char _FAR *, int);
Наиболее часто оказывается полезным второй вариант конструктора, в котором указывается только первый параметр - полное имя файла. Этот конструктор создает объект типа ofstream, открывает указанный файл и присоединяет его к потоку вывода.
Собственно операции вывода реализуются вызовом методов put, write или с использованием переопределенных операций <<.
Аналогичным способом обеспечивается и ввод из файла: создается объект типа ifstream и для ввода применяются методы get, read или переопределенные операции >>.
Для типа ifstream имеется набор аналогичных конструкторов:
_RTLENTRY ifstream();
_RTLENTRY ifstream(const char _FAR *,int = ios::in,
int = filebuf::openprot);
_RTLENTRY ifstream(int);
_RTLENTRY ifstream(int __f, char _FAR *, int);
В качестве примера рассмотрим программу, копирующую данные из одного файла в другой.
#include <fstream.h>
#include <process.h> // Для вызова exit
int main ( int argc, char* argv [ ] )
{ char ch;
if ( argc != 3 ) // Проверка числа аргументов
{ cerr << “ Вызов dcopy файл1 файл2 \n” ; exit ( 1 ) ; }
ifstream source( argv [ 1 ] ) ; // Входной поток
if ( ! source )
{ cerr << “ Нельзя открыть входной файл “ << argv [ 1 ] ;
exit ( 1 ); }
ofstream dest ( argv [2 ] ) ;
if ( ! dest )
{ cerr << “ Нельзя открыть выходной файл “ << argv [ 2 ] ;
exit ( 1 ); }
while ((ch = source.get ( ) ) != EOF )
dest.put( ch );
close ( source ); close ( dest );
return 0 ;
}
6.3. Ввод-вывод данных объектных типов
Организация вывода данных определенных программистом объектных типов, в общем случае зависит от предполагаемого дальнейшего использования этих данных. Могут сохраняться в файле все компоненты данные, или только часть из них, может применяться форматированный или бесформатный вывод. Часто возникает необходимость сохранить объектные данные в файле для последующего их восстановления в той же или другой программе.
Для вывода объекта в файл в определение класса может быть включена функция-компонента с параметром ссылкой на объект типа ostream. Часто такой функции назначают имя print или printon. Более изящным считается переопределение оператора << для вывода объектного данного. Если компоненты-данные объекта имеют уровень доступа protected или private, а оператор << не является компонентой класса, его следует объявить как friend-метод.
Пусть, например, в программе определен класс complex:
class complex
{ double re, im ;
public:
complex (double r =0, double i =0 ): re ( r ), im ( i )
{ } // конструктор
double real ( ) {return ( re ); }
double image ( ) { return ( im ); }
/* другие методы */
}
Тогда для форматированного вывода комплексного числа в формате ( вещественная часть, мнимая часть ) можно так переопределить операцию << :
ostream& operator << ( ostream& s, complex c )
{ int old_precision = s.precision ( 4 ); // установка числа дробных цифр
s << “(“ << c.real( ) <<
“, “ << c.image( ) << “)” ;
s.precision ( old_precision ) ; // восстановление числа дробных цифр
return ( s );
}
В данном случае в переопределении << нет обращения к личным переменным класса Complex. Если не использовать методы real и image, переопределение << нужно было бы включить в описание класса Complex с описателем friend.
Ввод объектного данного из файла или стандартного потока организуется аналогично: либо в определение класса включается функция-компонента для инициализации компонент данных их входного потока, либо переопределяется операция >> для ввода компонент-данных из потока. В некоторых случаях оказывается более удобным включить в описание класса дополнительный конструктор с параметром-ссылкой на объект типа istream, при этом все базовые классы должны иметь аналогичные конструкторы.
Пусть в описание класса Complex включена переопределенная операция >>:
class complex
{ double re, im ;
public:
complex (double r =0,double i=0 ): re( r ), im( i ) { } // конструктор
double real ( ) {return ( re ); }
double image ( ) { return ( im ); }
friend istream& operator >> ( istream& , Complex& );
/* другие методы */
}
Если предположить, что комплексные числа поступают из потока либо в виде вещественного числа, возможно заключенного
в скобки, либо в виде пары чисел, разделенных запятой и заключенной в скобки,
то переопределяемую операцию ввода можно описать следующим образом:
istream& operator >> ( istream& s, Complex& c )
{ double re_n = 0, im_n = 0;
char ch = 0;
s >> ch ;
if ( ch == `(` )
{ s >> re_n >> ch ;
if ( ch == `,' ) s >> im_n >> ch;
if ( ch != `)') s.clear ( ios::failbit ); //Установка признака ошибки
}
else { s.putback ( ch ); s >> re_n ; }
if ( s ) { c.re = re_n; c.im = im_n; } // Если не было ошибки
return ( s );
}
Рассмотренные выше примеры сохранения объектов
в потоке и восстановления их из потока иллюстрируют наиболее простые варианты
этих операций. Проблема сохранения объектов в потоке существенно усложняется,
когда требуется сохранять в одном потоке объекты разных типов, когда между
объектами разных типов имеются ссылки и некоторый объект содержит указатель
на объект другого типа, причем на один и тот же объект могут ссылаться
несколько других объектов. В этой ситуации требуется для каждого сохраняемого
в потоке объекта заносить в поток идентификатор типа объекта, гарантировать,
что каждый объект, на который имеются ссылки из других объектов, будет
помещен в поток только один раз. Средства для разрешения этих проблем имеются
в библиотеке классов-контейнеров classlib, содержащей
файл objstrm.h с определениями необходимых
классов и макросов.
Приложение 1. Задачи по программированию на Си
1. Составить функцию для подсчета числа серий положительных, отрицательных чисел и нулей длиной не менее К в одномерном массиве целых чисел. Серией называется последовательность элементов массива, принадлежащих одному классу:
int series ( int n, int *mas, int *kzero, int *kplus, int *kminus, int k);
2. Составить функцию для слияния двух упорядоченных по возрастанию массивов целых чисел:
int merge (int n, int m, int *mas1, int *mas2, int *res);
3. Составить функцию для построения списка индексов (номеров), строк упорядоченного по возрастанию элементов заданного (k-го) столбца матрицы. Элементы матрицы - целые числа:
void sort (int n, int *mas, int k, int* index);
4. Составить функцию для определения элемента матрицы, являющегося седловой точкой. Седловой точкой называется элемент, удовлетворяющий условиям:
a[k,l] = max min{ a[i,j] } = min max { a[i,j] }
i<=n,j<=m j<=m,i<=n
Если седловой точки нет, установить k=l=-1
5. Составить функцию для подсчета количества различных чисел в массиве, содержащем n целых чисел.
int count(int *a, int n);
6. Составить функцию для разделения текста, заданного строкой литер, на отдельные слова и подсчета числа слов. Под словом понимается последовательность литер, отличных от пробела, ограниченная слева началом строки или пробелом и справа - пробелом, знаком препинания или концом строки.
int kwords(char* ss, char * sm, int kmax);
ss - исходная строка,
sm - массив строк длиной до 30 литер каждая (для размещения выделенных слов),
kmax - максимальное количество выделенных слов.
Предусмотреть сигнализацию о случаях, когда функция неприменима ( слишком много слов или слишком длинное слово ).
7. Составить функцию для определения
а) наибольшего простого числа, не превосходящего заданное целое n,
б) наименьшего простого числа, превосходящего заданное n.
int simple (int n);
8. Составить функцию для разложения заданного целого числа на простые множители. Результатом функции должен быть массив, содержащий простые множители, и целое число - количество множителей.
int simplefactor(int n, int *masfactor);
9. Составить функцию для вычисления числа сочетаний из n злементов по m (n и m - целые):
Cnm = n! / ((n-m)! * m!)
Результатом функции должно быть целое число, если Cnm < 32767 и булевское значение true, или вещественное число, если Cnm >=32767 и булевское значение false.
Boolean binom (int n, int m, int *cnm, double *dcnm);
10. Многочлены представляются в памяти ЭВМ целым числом n - степенью многочлена и массивом коэффициентов a[0],a[1],...,a[n].
а) Составить функцию для вычисления значения y=P(x) многочлена для заданного аргумента x.
double valpoly( int n, double *a);
б) Составить функцию для вычисления коэффициентов многочлена-произведения двух других многочленов, заданных своими степенями и массивами коэффициентов. Функция возвращает степень многочлена - произведения.
int polyprod( int n, double *a, int m, double *b, double *res);
в) Составить функцию для вычисления коэффициентов многочлена-суммы двух других многочленов. Функция возвращает степень многочлена - суммы.
int polysum ( int n, double *a, int m, double *b, double *res);
11. В некоторой программе обработки таблиц сведения о динамически образуемых столбцах определяются глобальными описаниями :
const int L_cln = 20; /*длина столбца таблицы*/
const int L_tab=30; /*максимальное число столбцов*/
struct COLUM
{ char name [ 5 ]; /* имя столбца */
double *adr; /* указатель на столбец */
};
COLUM Tabl [ L_tab } /*массив сведений о столбцах */
Для обращения к столбцам используются их индексы в массиве Tabl. Если столбец не размещен в памяти, то значение поля adr равно 0.
а) Составить функцию для выполнения поэлементного сложения двух столбцов с образованием столбца сумм. Входные данные - номера (индексы в Tabl ) столбцов слагаемых и столбца результата. Если столбец-результат не размещен в памяти, то разместить его и отметить зто в Tabl.
int sumcol( int k, int l, int r);
Функция возвращает 0 при успешном выполнении операции или 1, если один или оба столбца-слагаемых не размещены в памяти.
б) Составить функцию для вычисления столбца частных от деления элементов одного столбца на элементы другого столбца. Предусмотреть сигнализацию о случае, когда элемент столбца-делителя равен нулю. Остальные условия - как в варианте (а).
int subcol ( int k, int l, int r);
в) Составить функцию для вычисления элементов столбца относительных приростов в процентах di=(ai-bi)/ai*100 для заданного исходного столбца. Остальные условия - как в вариантах (а) и (б).
int relincr ( int k, int r);
Функция возвращает 1, если встретится делитель, равный 0, в остальных случаях возвращает 0.
г) Составить функцию для печати таблицы, содержащей столбцы, перечень которых задан списком (массивом ) индексов (номеров) столбцов в массиве Tabl.
int tabprint ( int *list, int n);
12. В некоторой программе аналитических преобразований выражения, определяющие формулы, хранятся в виде динамических структур - деревьев с описанием :
enum tpn = { FUNC, OPER, VAR, CNST}; /*типы узлов*/
struct node
{ enum tpn tp_node; /* тип узла */
int cop; /* тип операции или номер функции, константы, переменной */
node *al, *ar; /* указатели на подчиненные узлы */
} ;
а) Составить функцию для обхода дерева, заданного указателем на его корень, в порядке : левое поддерево, корень, правое поддерево. Выводить на экран (печать) тип узла и значение поля cop в узле.
void lkp ( node *root);
б) В условиях пункта (а) выполнить обход дерева в порядке : корень, левое поддерево, правое поддерево.
void klp ( node *root );
в) В условиях пункта (а) выполнить обход дерева в порядке : левое поддерево, правое поддерево, корень.
void lpk ( node *root);
г) Составить функцию для освобождения памяти, занятой некоторым поддеревом. Входной параметр - указатель на корень удаляемого поддерева.
void deltree ( node *root);
13. В некоторой программе сообщения об ошибках хранятся в файле из записей, каждая запись состоит из двух строк по 60 литер. Позиция записи в дисковом файле определяется кодом ошибки - целым числом.
а)Составить функцию для вывода сообщения об ошибке на экран. Входной параметр код (номер) ошибки. Файл с сообщениями об ошибках открывается в главной программе.
б)Составить программу для создания файла сообщений об ошибках. При использовании этой программы пользователь указывает имя файла, максимальное число сообщений об ошибках, а затем задает коды ошибок и соответствующие им сообщения в произвольном порядке.
14. Составить функцию для решения системы линейных уравнений
1<=i<=n
методом исключения неизвестных.
int gauss (int n, double *a, double *b);
Функция возвращает 0 при успешном выполнении и 1, если метод не работает.
15. В памяти хранится массив из n<Nmax вещественных чисел - значений реализации некоторой случайной величины.
а)Cоставить функцию для вычисления оценок математического ожидания и дисперсии случайной величины
void randval( int n, double *a, double *m, double *d);
a - исходный массив, m - вычисляемая оценка математического ожидания, d - оценка дисперсии.
б)Cоставить функцию для построения гистограммы (распределения частот) для реализации случайной величины. Входные данные: n, x -массив значений случайной величины x[1],...,x[n], k - число интервалов, на которые разбивается диапазон значений случайной величины.Результат функции r - массив из k чисел, значения частот попадания в соответствующий интервал.
16. Выполнить варианты 15 (а),(б) для случая,когда значения реализации случайной величины хранятся в текстовом файле, а остальные данные сообщаются пользователем, результаты расчетов выводятся на экран.
17. Значения некоторой функции представлены таблицей с постоянным шагом и в памяти хранятся: число точек таблицы n, массив значений функции y[1],...,y[n], начальное значение аргумента x[1] и шаг по аргументу.
а)Составить функцию для выборки значения функции из таблицы с линейной интерполяцией.
б)Составить функцию для вычисления значения обратной функции для функции,заданной таблицей c постоянным шагом.
18. Составить функцию для выборки значений функции, заданной таблицей с переменным шагом. Таблица хранится в памяти в форме массива из n строк и двух столбцов(аргумент и значение функции).
19. Составить функцию для сортировки (упорядочения) массива mas из n элементов по возрастанию значений элементов:
void sort (int n, int *mas);
20. Составить функцию для сортировки (перестановки строк) матрицы из n строк и m столбцов по возрастанию элементов k-го столбца;
void sortmas ( int n, int m, int *matr, int k);
21. Составить функцию для умножения матрицы matr из n строк и m столбцов на вектор vect (из n элементов) с размещением результата в массиве res:
void matrvect( int n, int m, float *matr, float *vect, float *res);
22. Составить функцию для вычисления произведения матриц a из n строк и m с толбцов и b из m строк и k столбцов с помещением результата в матрицу c:
void matrprod ( int n, int m, int k, float *a, float *b, float *c);
Приложение 2. Задачи по разработке систем объектов
1. Построить систему классов для описания плоских геометрических фигур: круг, квадрат. прямоугольник. Предусмотреть методы для создания объектов, перемещения на плоскости, изменения размеров и вращения на заданный угол.
2. Построить описание класса, содержащего информацию о почтовом адресе организации. Предусмотреть возможность раздельного изменения составных частей адреса. создания и уничтожения объектов этого класса.
3. Составить описание класса для представления комплексных чисел с возможностью задания вещественной и мнимой частей как числами типов double, так и целыми числами. Обеспечить выполнение операций сложения, вычитания и умножения комплексных чисел.
4. Составить описание класса для работы с цепными списками строк (строки произвольной длины) с операциями включения в список. удаление из списка элемента с заданным значением данного. удаления всего списка или конца списка. начиная с заданного элемента.
5. Составить описание класса для объектов - векторов, задаваемых координатами концов в трехмерном пространстве. Обеспечить операции сложения и вычитания векторов с получением нового вектора (суммы или разности), вычисления скалярного произведения двух векторов, длины вектора, cos угла между векторами.
6. Составить описание класса прямоугольников со сторонами, параллельными осям координат. Предусмотреть возможность перемещения прямоугольников на плоскости, изменение размеров, построение наименьшего прямоугольника, содержащего два заданных прямоугольника, и прямоугольника, являющегося общей частью (пересечением) двух прямоугольников.
7. Составить описание класса для определения одномерных массивов целых чисел (векторов). Предусмотреть возможность обращения к отдельному элементу массива с контролем выхода за пределы индексов, возможность задания произвольных границ индексов при создании объекта и выполнения операций поэлементного сложения и вычитания массивов с одинаковыми границами индексов, умножения и деления всех элементов массива на скаляр, печати (вывода на экран) элементов массива по индексам и всего массива.
8. Составить описание класса для определения одномерных массивов строк фиксированной длины. Предусмотреть возможность обращения к отдельным строкам массива по индексам, контроль выхода за пределы индексов, выполнения операций поэелементного сцепления двух массивов с образованием нового массива, слияния двух массивов с исключением повторяющихся элементов, печать (вывод на экран) элементов массива и всего массива.
9. Составить описание класса многочленов от одной переменной, задаваемых степенью многочлена и массивом коэффициентов. Предусмотреть методы для вычисления значения многочлена для заданного аргумента, операции сложения, вычитания и умножения многочленов с получением нового объекта - многочлена, печать (вывод на экран) описания многочлена.
10. Составить описание класса одномерных массивов строк, каждая строка задается длиной и указателем на выделенную для нее память. Предусмотреть возможность обращения к отдельным строкам массива по индексам, контроль выхода за пределы индексов, выполнения операций поэелементного сцепления двух массивов с образованием нового массива, слияния двух массивов с исключением повторяющихся элементов, печать (вывод на экран) элементов массива и всего массива.
11. Составить описание объектного типа TMatr, обеспечивающего размещение матрицы произвольного размера с возможностью изменения числа строк и столбцов, вывода на экран подматрицы любого размера и всей матрицы.
Литература
1. Керниган Б., Ритчи Д. Язык программирования Си. - М., “Радио и связь”, 1989.
2. Пол Ирэ. Объектно-ориентированное программирование с использованием С++: Пер. с англ. - Киев: НИПФ “ДиаСофт Лтд, 1995.
3. Цимбал А.А. и др. Turbo C++, язык и его применение. - М.: Джен Ай Лтд, 1993, - 512с.
4. Bjarne Stroustrup The C++ Programming language, Addison Weasley, 1986.
Подобные документы
Использование программой функции ввода-вывода данных для реализации дружественного интерфейса с пользователем. Функции консоли и особенности их применения для обеспечения аккуратного ввода информации и упорядоченного вывода. Обзор стандартных функций.
лабораторная работа [40,4 K], добавлен 06.07.2009Понятия шаблонов функции и класса, правила описания на языке С++. Разработка и отлаживание в среде программирования программ, содержащих шаблоны функций и классов. Шаблон функции square, возвращающей квадрат переменной. Создание шаблона класса массива.
лабораторная работа [162,6 K], добавлен 25.05.2013Общие сведения о языке С++. Операции и выражения, стандартные функции и структура программы. Использование функций при программировании на С++. Основные алгоритмы обработки массивов. Статические и динамические матрицы. Организация ввода-вывода в C++.
учебное пособие [6,7 M], добавлен 28.03.2014Классификация типов данных, отличия синтаксических конструкций языков C# и C++. Базовые типы: Array, String, StringBuilder. Средства стандартного ввода и вывода и возможности форматирования вывода. Понятие о регулярных выражениях и их применении.
лабораторная работа [148,8 K], добавлен 13.05.2014Виртуальные функции, статические и абстрактные классы, шаблоны: элементы и члены класса, их роль в объектно-ориентированном программировании; механизм осуществления виртуального вызова при выполнении программы; обработка исключительных ситуаций в C++.
реферат [27,2 K], добавлен 06.12.2010В стандарте языка Си отсутствуют средства ввода-вывода. Операции реализуются с помощью функций, находящихся в библиотеке языка Си, поставляемой в составе системы программирования Си. Потоковый, форматный ввод-вывод. Форматный ввод из входного потока.
реферат [98,9 K], добавлен 24.06.2008Концепция объектно-ориентированного программирования. Объектно-ориентированные языки программирования: Smalltalk, Object Pascal, CLOS и C++. Понятие "Объект" и "Класс". Управление доступом к элементам данных классов. Определение функций-членов класса.
реферат [24,5 K], добавлен 28.10.2011Порядок разработки пользовательской документации. Руководство по инсталляции программного средства. Справочник по применению программного средства. Печать с помощью функций файлового ввода/вывода. Печать текстов в обогащенном формате методом Print.
курсовая работа [78,3 K], добавлен 05.02.2016Классы, объекты и объектные ссылки. Особенности статических методов. Конструкторы, специальные переменные, наследование. Создание объектов внутренних классов. Соглашения об именовании. Некоторые методы класса Object. Абстрактные классы и атрибуты.
лекция [130,6 K], добавлен 21.06.2014Основные понятия объектно-ориентированного программирования, особенности описания функций и классов. Разработка программы для работы с универсальной очередью установленного типа, добавления и удаления ее элементов и вывода содержимого очереди на экран.
курсовая работа [187,2 K], добавлен 27.08.2012