- •О.Л. Викентьева, А.Н. Гусин, O.A. Полякова
- •ПРОЕКТИРОВАНИЕ ПРОГРАММ И ПРОГРАММИРОВАНИЕ НА C++
- •1. СТРУКТУРНОЕ ПРОГРАММИРОВАНИЕ
- •10.1. Базовые конструкции структурного программирования
- •10.3. Составные операторы
- •10.4. Операторы выбора
- •10.5. Операторы циклов
- •10.6. Операторы перехода
- •11. ПРИМЕРЫ РЕШЕНИЯ ЗАДАЧ С ИСПОЛЬЗОВАНИЕМ ОСНОВНЫХ ОПЕРАТОРОВ C++
- •11.2. Программирование арифметических циклов
- •11.3. Программирование итерационных циклов
- •11.4. Программирование вложенных циклов
- •12. МАССИВЫ
- •12.1. Определение массива в C/C++
- •12.2. Примеры решения задач с использованием массивов
- •13. УКАЗАТЕЛИ
- •13.1. Понятие указателя
- •13.2. Динамическая память
- •13.3. Операции с указателями
- •14. ССЫЛКИ
- •15.3. Динамические массивы
- •СИМВОЛЬНАЯ ИНФОРМАЦИЯ И СТРОКИ
- •16.1. Представление символьной информации
- •16.2. Библиотечные функции для работы со строками
- •16.3. Примеры решения задач с использованием строк
- •17. ФУНКЦИИ В C++
- •17.1. Объявление и определение функций
- •17.2. Прототип функции
- •17.3. Параметры функции
- •17.4. Локальные и глобальные переменные
- •17.5. Функции и массивы
- •17.5.1. Передача одномерных массивов как параметров функции
- •17.5.2. Передача строк в качестве параметров функций
- •17.5.3. Передача многомерных массивов в функцию
- •17.6. Функции с начальными значениями параметров (по умолчанию)
- •17.7. Подставляемые (inline) функции
- •17.8. Функции с переменным числом параметров
- •17.9. Рекурсия
- •17.11. Шаблоны функций
- •17.12. Указатель на функцию
- •17.13. Ссылки на функцию
- •18. ТИПЫ ДАННЫХ, ОПРЕДЕЛЯЕМЫЕ ПОЛЬЗОВАТЕЛЕМ
- •18.1. Переименование типов
- •18.2. Перечисления
- •18.3. Структуры
- •18.3.1. Работа со структурами
- •18.3.2. Битовые поля
- •18.3.3. Объединения
- •19. ДИНАМИЧЕСКИЕ СТРУКТУРЫ ДАННЫХ
- •19.1. Создание элемента списка
- •19.2. Создание списка из п элементов
- •19.3. Перебор элементов списка
- •19.4. Удаление элемента с заданным номером
- •19.5. Добавление элемента с заданным номером
- •19.6. Двунаправленные списки
- •19.7. Очереди и стеки
- •19.8. Бинарные деревья
- •19.9. Обход дерева
- •19.10. Формирование дерева
- •19.11. Удаление элемента из дерева
- •19.12. Обработка деревьев с помощью рекурсивного обхода
- •20. ПРЕПРОЦЕССОРНЫЕ СРЕДСТВА
- •20.1. Стадии и команды препроцессорной обработки
- •20.2. Директива #define
- •20.3. Включение текстов из файлов
- •20.4. Условная компиляция
- •20.5. Макроподстановки средствами препроцессора
- •21.1. Проектирование программы
- •21.2. Кодирование и документирование программы
- •СПИСОК ЛИТЕРАТУРЫ
- •ПРОЕКТИРОВАНИЕ ПРОГРАММ И ПРОГРАММИРОВАНИЕ НА C++
cout<<"\nMAX=f,<<max (al, bl)<<"\n"; cout<<M\nfor float:\n"; cout<<Ma=?,f;cin>>a2; cout<<,fb=?,f;cin>>b2; cout«,,\nMAX=,,«max (a2, b2) «"\n"; cout«"\nfor char* :\n" ; cout<<Ma=?M;cin>>sl; cout<<,fb=?";cin>>s2; cout<<M\nMAX=,,<<max (si, s2)«"Xn";
}
Правила описания перегруженных функций:
•Перегруженные функции должны находиться в одной области видимости.
•Перегруженные функции могут иметь параметры по умолча нию, при этом значения одного и того же параметра в разных функ циях должны совпадать. В разных вариантах перегруженных функ ций может быть разное количество умалчиваемых параметров.
•Функции не могут быть перегружены, если описание их параметров отличается только модификатором c o n s t или нали
чием |
ссылки: функции |
i n t & |
f l ( i n t & , |
c o n s t int&){...} |
и i n t |
f l ( i n t , i n t ) |
{...} |
не являются |
перегруженными, так |
как компилятор не сможет узнать, какая из функций вызывается, потому что нет синтаксических отличий между вызовом функ ции, которая передает параметр по значению, и функции, которая передает параметр по ссылке.
17.11. Шаблоны функций
Шаблоны вводятся для того, чтобы автоматизировать создание функций, обрабатывающих разнотипные данные. Например, алгоритм сортировки можно использовать для массивов различных типов. При перегрузке функции для каждого используемого типа определяется своя функция. Шаблон функции определяется один раз, но определение параметризируется, т.е. тип данных передается как параметр шаблона,
t e m p l a t e C c l a s s им я_типа [ , c l a s s имя _ типа]> з а г ол о в о к_фун кции
{
тел о функции
}
Таким образом, шаблон семейства функций состоит из двух частей - заголовка шаблона: templateCcnncoK параметров шаблона>
и обыкновенного определения функции, в котором вместо типа возвра щаемого значения и/или типа параметров записывается имя типа, опреде ленное в заголовке шаблона.
/*шаблон функции, которая находит абсолютное значение числа любого типа*/
templatecclass type> //type имя //параметризируемого типа
type abs(type х)
{
if(х<0)return -х; else return х;
}
Шаблон служит для автоматического формирования конкретных описаний функций по тем вызовам, которые компилятор обнаружи вает в программе. Например, если в программе вызов функции осу ществляется как abs (-1.5), то компилятор сформирует определе ние функции double abs (double х) {...}.
//шаблон функции, |
которая меняет местами две |
//переменных |
//Т - имя параметризируемого |
template <class Т> |
|
//типа |
|
void change(Т* х, Т* у)
{
Т z=*x;
*х=*у;
*y=z;
}
Вызов этой функции может быть: long k=10, 1=5; change(&k, &1);
Тогда компилятор сформирует определение: void change(long* х, long* у)
{
long z=*x;
*x=*y;
*y=z;
}
/^шаблон функции, которая находит |
номер макси |
||
мального элемента |
в массиве*/ |
|
|
#include<iostream.h> |
|
||
templateCclass |
Data> |
|
|
Data& rmax(int |
n, Data a []) |
|
|
{ |
im=0; |
|
|
int |
|
|
|
for(int i=0;i<n;i++) |
|
||
if(a[im]<a[im]) im=i; |
ссылку |
||
return d[im]; |
//возвращает |
||
} |
|
|
|
void main() |
|
|
|
{ |
n=5; |
|
|
int |
|
|
|
int |
x[]={10,20,30,15}; |
|
//найти номер максимального элемента в массиве
//целых чисел
cout«"\nrmax (п,х) ="«гшах (п,х) <<"\п";
ппах(п,х)=0; //заменить максимальный элемент на 0
for(int i=0;i<n;i++) |
//вывод массива |
cout<<x[i]<<" |
|
cout«"\n"; |
|
//следующий массив |
|
float у []={10.4,20.2,30.6, 15.5}; |
/*найти номер максимального элемента в массиве
вещественных чисел*/
cout«"\nrmax (п,у) ="«rmax (п,у) «"\п"; rmax(4,у)=0;//заменить максимальный элемент на 0
for(in i=0;i<n;i++) |
//вывод массива |
cout<<y[i]<<" "; |
|
cout«"\n"; |
|
}
Результаты работы программы: rmax(n,х)=30
10 |
20 |
0 |
15 |
|
|
rmax(п,у)=30.6 |
|||||
10.4 |
20.2 |
0 |
15.5 |
Основные свойства параметров шаблона функций:
-имена параметров должны быть уникальными во всем опре делении шаблона;
-список параметров шаблона не может быть пустым;
-в списке параметров шаблона может быть несколько парамет ров, каждый из них начинается со слова class.
17.12. Указатель на функцию
Каждая функция характеризуется типом возвращаемого значе ния, именем и списком типов ее параметров. Если имя функции ис пользовать без последующих скобок и параметров, то оно будет вы ступать в качестве указателя на эту функцию и его значением будет выступать адрес размещения функции в памяти. Это значение можно будет присвоить другому указателю. Тогда этот новый указатель можно будет использовать для вызова функции.
Указатель на функцию определяется следующим образом:
тип_функции(*имя_указателя)(спецификация
параметров) |
с) {...} |
//определение |
функции |
|
int fl(char |
||||
int(*ptrfl)(char); |
//определение |
указателя на |
||
//функцию |
fl |
k,char |
с) {...} //определение функции |
|
char* |
f2(int |
|||
char* |
ptrf2 (int,char);//определение указателя |
//на функцию f2
В определении указателя количество и тип параметров должны совпадать с соответствующими типами в определении функции, на которую ставится указатель.
Вызов функции с помощью указателя имеет вид
(*имя_указателя) (список фактических параметров); #include <iostream.h>
void f1 ()
{
cout<<"\nfunction fl";
}
void f2()
{
cout<<"\nfunction f2";
void(*ptr)(); |
//указатель на функцию |
адрес |
ptr=f2; |
//указателю присваивается |
|
//функции f2 |
//вызов функции f2 |
|
(*ptr)(); |
адрес |
|
ptr=f1; |
//указателю присваивается |
|
//функции fl |
|
|
(*ptr) ();//вызов функции fl с помощью указателя
}
При определении указатель на функцию может быть сразу проинициализирован.
void (*ptr) ()=f1;
Указатели на функции могут быть объединены в массивы. На
пример, float (*ptrMas [4] )(char) - описание массива, кото рый содержит четыре указателя на функции. Каждая функция имеет параметр типа char и возвращаетзначение типа float.
Обратиться ктакой функции можно следующим образом: float а=(*ptrMas[1])('f');//обращение ко
//второй функции
#include dost ream. h> #include <stdlib.h> void f1()
{
cout«"\nThe end of work";exit(0);
}
void f2 ()
{
cout<<"\nThe work #1";
}
void f3()
{
cout<<"\nThe work #2";
}
void main()
{
void(*fptr[])()={fl,f2,f3};//массив и указателей //на функции
int n; |
//бесконечный цикл |
while(1) |
{
cout«"\n Enter the number";
cin»n;
fptr[n]();//вызов функции с номером n
}
}
Указатели на функции удобно использовать в тех случаях, когда
функцию надо передать в другую функцию как параметр.
♦include <iostream.h> ♦include <math.h>
typedef float(*fptr)(float);//тип-указатель на //функцию уравнения
/^решение уравнения методом половинного деле ния, уравнение передается с помощью указателя на функцию*/
float root(fptr f, float a, float b, float e)
{
float x; do
{
x=(a+b)/2; //находим середину
//отрезка
if ((*f)(a)*f(x)<0) //выбираем отрезок b=x;
else a=x;
}
while((*f)(x)>e && fabs(a-b)>e); return x;
}
//функция, для которой ищется корень float testf(float x)
{
return x*x-l;
}