Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Алгоритмизация и программирование на языке С++. Ч.1. Учебник
.pdf
8. Массивы
151
TF1=false;
}
if ( ni >= 0 )
cout << "L = " << L << " i,j "<< ni << " "<< nj << endl;
else
cout << " NOT <0" << endl;
Рассмотрим похожую задачу обхода таблицы, которую назовем «вертикальная змейка» (рис. 8.34). В ней обход таблицы также начинается в левом верхнем углу, но после обхода
элементов первого столбца элементы второго перебираются
не с элемента первой строки (сверху), а последней (снизу).
↓ ↑ ↓ ↑
↓ ↑ ↓ ↑
↓ ↑ ↓ ↑
↓ ↑ ↓ ↑
Рис. 8.34. Обход матрицы «вертикальной змейкой»
из правого верхнего угла
Порядок обхода элементов матрицы с указание номеров
строк и столбцов представлен в табл. 8.3.
Таблица 8.3
Порядок обхода элементов матрицы
«вертикальной змейкой»
1) 0,0 8) 0,1 9) 0,2 16) 0,3
2) 1,0 7) 1,1 10) 1,2 15) 1,3
3) 2,0 6) 2,1 11) 2,2 14) 2,3
4) 3,0 5) 3,1 12) 3,2 13) 3,3

152
АЛГОРИТМИЗАЦИЯ ИПРОГРАММИРОВАНИЕ НАЯЗЫКЕ С++
Приведем код программы такой задачи.
int Arr13[n][m]
{ { 1, 5, 0, 0},
{ 2, 6, 0, 0},
{ 3, –7, 0, 0},
{ 4, 8, 1, 0}
};
cout << "Исходный массив:" << endl;
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
cout.width(3);
cout << Arr13[i][j];
}
cout << "\n";
}
int ni, nj, L=0; ni=-1;
for(int j=0; j<m; j++)
{
if ( j%2 == 0)
{
for(int i=0; i<n; i++)
{ L=L+1;
cout << L << " i= " << i << " j= " << j <<
" Arr[i,j]= " << Arr13[i][j] <<endl;
if ( Arr13[i][j] < 0 )
{
ni=i; nj=j; break;
}
}
} // if
else
{

8. Массивы
for(int i=n-1; i>=0; i--)
{ L=L+1;
cout << L << " i= " << i << " j= " << j <<
" Arr[i,j]= " << Arr13[i][j] <<endl;
if ( Arr13[i][j] < 0 )
{
ni=i; nj=j; break;
}
}
} // else
if ( ni >= 0 ) break;
}
if ( ni >= 0 )
cout << "L = " << L << " i,j "<< ni << " "<< nj << endl;
else
cout << " NOT <0" << endl;
Результаты представлены на рис. 8.35.
153
Рис. 8.35. Результаты работы программы
«вертикальная змейка»
Заметим, что такая задача имеет восемь модификаций: из
каждого угла матрицы можно начинать движение в двух направлениях (вертикально или горизонтально).

Функция (программный модуль) – это последовательность
инструкций для решения какой-либо более или менее самостоятельной задачи (подзадачи), оформленная специальным образом. Функция обычно реализует алгоритм в достаточно общем
виде с использованием формальных параметров – абстрактных обозначений величин, участвующих в описании алгоритма. Каждая функция имеет свое имя, по которому осуществляется обращение к нему. Обращение к функции осуществляется
указанием ее имени и фактических параметров. При вызове
функции формальные параметры заменяются на фактические
(конкретизирующие задачу), с которыми функция и выполняется. Заметим, что функции можно рассматривать как аналоги
подпрограмм в других языках программирования.
Функции могут возвращать значение (аналогично подпрограммам-функциям) и не возвращать значение (аналогично
подпрограммам-процедурам).
Использование функций:
• улучшает структуру программы и облегчает ее воспри-
ятие;
• облегчает отладку, так как каждая функция может от-
лаживаться отдельно;
• при решении некоторой подзадачи несколько раз в рамках одной программы позволяет оформлять алгоритм один
раз, а обращаться к нему многократно;
• уменьшает объем программы, если одна и та же функция выполняется несколько раз. Время выполнения при этом
практически не изменяется.
Рассмотрим сначала функции, возвращающие значение.
Описание такой функции содержит следующие элементы:
<возвращаемое значение> ИМЯ (входные параметры)
Приведем пример программы на С++, в котором находится минимальное значение из двух заданных величин. Обратим
внимание на то, что на вход подается два значения, а на выходе получает одно.

9. Функции
int min(int fa, int fb) // 1
{
int M;
if (fa > fb)
M = fb;
else
M = fa;
return M;
}
int main()
{
int a, b; int r;
a = 3; b = 5; int iMin;
iMin = min(a, b);
cout << "Min= " << iMin << endl;
char q = getchar();
}
Результатом работы такой программы является число 3.
Обращение к функции записывается в том месте кода, где
требуется получить значение, возвращаемое функцией.
Рассмотрим второй вариант решения той же задачи.
void min(int a, int b, int c) //2
{
c = (a < b) ? a : b;
cout << c << endl;
}
int main()
{
int a, b; int Min;
a = 3; b = 5; int c=0; Min = 100;
min(a, b, c);
printf("Min= %d ", Min);
155
return 0;
}

156
АЛГОРИТМИЗАЦИЯ ИПРОГРАММИРОВАНИЕ НАЯЗЫКЕ С++
Здесь те же вычисления выполняются в функции, не возвращающей значения. Если функция не возвращает значе-
void
ния, она имеет тип
a, b
входные (
) и выходной (c) параметры.
. В списке параметров перечислены
Однако результат, представленный на рис. 9.1, не является верным!
Рис. 9.1. Функция поиска минимума без возвращаемого
значения (результат не верен!)
Программа выведет 3 (минимальное значение, полученное в
min
функции
main
ции
), но значение переменной с в вызывающей функ-
будет 100 (то есть значение, полученное до обращения
к функции, не изменится). Хотя ожидаемый результат работы
min
функции
ее вызове, но области памяти, выделяемые переменной
min
ции
Для того чтобы в переменной с именем
в программе соответствует третьему параметру при
и переменной с таким же именем в функции
main
с
функции
с
в функ-
, разные.
main
оказалось найденное минимальное значение, надо передать
*
не ее имя, а ссылку на ее адрес. Префикс
(см. п. 8.1) перед
формальным выходным параметром позволяет функции манипулировать единственным экземпляром значения, так как
в этом случае вместо параметра будет передаваться его адрес
(то есть произойдет передача параметра по ссылке).
void min(int a, int b, int* c) // 3
{
*c = (a > b) ? b : a;
cout << *c << endl;
}
int main()

9. Функции
157
{
int a, b; int c;
a = 3; b = 5; c = 100;
min(a, b, &c);
cout << "Min= " << c << endl;
return 0;
}
Теперь результат будет верным – два раза будет выведено 3.
Замечание. Таким образом, передача параметров в функцию может быть осуществлена двумя способами: по значению
и по ссылке. В последней программе это сделано вторым способом. При этом, если значение, передаваемое в функцию, изменится там, то в вызывающей функции такие изменения сохранятся, так как происходит передача не значения, а адреса.
А в первом случае у переменной в вызывающей функции своя
область памяти, а в вызываемой функции – своя, что и привело к неверному результату.
Функция обычно реализует алгоритм в достаточно общем
виде с использованием формальных параметров – абстрактных обозначений величин, участвующих в описании алгоритма. При вызове функции формальные параметры заменяются на фактические (конкретизирующие задачу), с которыми
функция и выполняется.
min
В нашем примере функция
имеет три формальных па-
раметра.
void min(int a, int b, int *c)
А вот фактические замещают их при обращении к функции.
min(a, b, &c);
В примере фактических параметров также три.
Формальные и фактические параметры должны соответствовать по количеству, типу и порядку следования.
Традиционно в программировании функции определялись
следующим способом [3]. (Заметим, что эта программа написана для отладки в стиле классического С.)
#include <stdio.h>

158
АЛГОРИТМИЗАЦИЯ ИПРОГРАММИРОВАНИЕ НАЯЗЫКЕ С++
int max(fa,fb,fc) // 4
int fa, fb, fc;
{ int m;
m = (fa > fb) ? fb : fa;
return m;
}
int main()
{
int a, b, c; int r;
a=3; b=5;
r= max(a, b, c);
printf( "r= %d ", r);
return 0;
}
Как видно из этого примера, типы формальных параметров
задаются вне строки описания функции, где указаны только
их имена. Эти переменные являются глобальными. Они описаны вне области действия какой-то функции. Эту программу
можно откомпилировать только в некоторых средах разработки С++.
А вот второй – более современный – способ описания является правильным и для С++. Здесь типы параметров функции
зафиксированы в ее описании:
int max(int fa, int fb, int fc) // 4а
{
int m;
m = (fa > fb) ? fb : fa;
// return (m > fc) ? m : fc;
return m;
}
Приведем еще один пример функции, возвращающей значение. Здесь у функции нет ни одного входного параметра –
они описаны как глобальные переменные, выходным является возвращаемое значение.

9. Функции
159
int fa, fb;
int max() // 5
{
int m = (fa > fb) ? fb : fa;
return m;
}
int main() {
setlocale(LC_ALL,»Russian»);
int r;
fa=-3; fb=5;
r = max();
cout << "r= " << r << endl;
}
Следующие два примера показывают взаимное располо-
main
жение в программе заданной функции и функции
.
Сначала неверный способ. В нем сначала находится глобальное описание переменных, далее следует код функции
main
, а затем код функции вычисления минимума:
int fa, fb;
// int max(); //5
int main() {
setlocale(LC_ALL, "Russian");
int r;
fa = -3; fb = 5;
r = max();
cout << "r= " << r << endl;
}
int max()
{
int m = (fa > fb) ? fb : fa;
return m;
}

160
АЛГОРИТМИЗАЦИЯ ИПРОГРАММИРОВАНИЕ НАЯЗЫКЕ С++
При попытке компиляции будет выведено сообщение об
ошибке:
[Error] no matching function for call to 'max()'
Для исправления этой ошибки надо добавить описание
min
до функции
main
. Оно приведено в тексте программы как
комментарий.
И наконец приведем несколько примеров программ, в которых использованы функции. Вычислить число сочетаний
из n по m: C = n! / (m!(n – m)!). Для подсчета факториала использовать функцию.
Вначале рассмотрим два варианта функции для подсчета
факториала.
int fact(int n)
{
int f;
if (n > 0)
{
f = 1;
for (int i = 1; i <= n; i++)
{
f = f * i;
}
}
else
f = 1;
return f;
}
int main() {
setlocale(LC_ALL, "Russian");
cout << fact(0) << endl;
}
После выполнения программы будет выведено 1.
А если изменить строку в функции таким образом:
cout << fact(4) << endl;
получим 24.
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
