Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Алгоритмизация и программирование на языке С++. Ч.1. Учебник

.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
2 Мб
Скачать
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.
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]