Вы находитесь на странице: 1из 49

Одесская Национальная Академия связи им. А.С.

Попова

Кафедра Информационных технологий

ИНФОРМАТИКА

МОДУЛЬ № 2
“Программирование задач с циклами и массивами”

Рабочая тетрадь
для подготовки и выполнения лабораторных работ

для студентов всех специальностей,


изучающих дисциплину «Информатика»

Одесса – 2006
2 “Программирование задач с циклами и массивами”

Автор: доц. Трофименко Е.Г.


Редактор: доц. Леонов Ю.Г.

Рабочая тетрадь рекомендована на заседании кафедры ИТ,


протокол №2 2006 год.
“Программирование задач с циклами и массивами” 3
Каждая из предложенных к выполнению лабораторных работ имеет задания трёх разных
уровней сложности. Студент сам, или по указанию преподавателя, выбирает задания того или ино-
го уровня сложности согласно номеру фамилии студента в списке группы. В дальнейшем при оце-
нивании знаний преподаватель может учитывать уровень сложности выполненной лабораторной
работы, оптимальность алгоритма составленной программы, своевременность подготовки и вы-
полнения работы.
К выполнению лабораторной работы допускается студент, имеющий подготовленный само-
стоятельно заполненный протокол лабораторной работы. В протоколе студент должен ответить на
контрольные вопросы, составить схемы алгоритмов и программы для решения индивидуального
задания этой лабораторной работы. Также необходимо нарисовать форму проекта для данной ра-
боты.
Результаты выполненных вычислений заносятся студентом в протокол. Правильность работы
программы и полученных результатов проверяются преподавателем.

Лабораторная работа № 2.1


Организация циклических вычислений с помощью оператора цикла
FOR
Цель работы: Изучить возможные варианты организации циклических вычислений в програм-
ме с помощью оператора цикла с параметром.
Контрольные вопросы
1 Какой процесс называется циклическим?
2 Какое предназначение операторов цикла и какие операторы цикла используются в языке С++?
3 Какие типы переменных могут быть использоваться в качестве параметра цикла, его начальные
и конечные значения?
4 Укажите ошибки в следующих фрагментах программ:
а) int k, m=2, n=3; б) int n=-7, m=2;
for (k=1; k<=n; k++) n=n+m; for (int k=n; k<=m; k--) k=k+1;
5 Чему равно значение m после выполнения фрагментов программы:
а) int k, m = 1 б) int m = 1, n = 5;
for (k = 1; k <= 5; k++) m++; for(int k=n; k>=1; k--) m*=k;

Теоретические сведения
Оператор цикла с параметром for обычно используется, если заранее известно число повторе-
ний. Синтаксис оператора следующий:
for (выражение1; выражение2; выражение3) оператор;
Сначала выражение1 задает начальное значение переменных, управляющих циклом, затем
проверяется условие в выражении2, которое является условием продолжения цикла. Если условие
истинно (имеет ненулевое значение), то выполняется оператор (или группа операторов в опера-
торных скобках {}), после чего выражение3 изменяет переменные, управляющие циклом, и в слу-
чае истинности условия выполнение цикла продолжается. Если выражение2 равно нулю (ложь),
то управление передается на оператор, следующий за оператором for.
Существенно то, что проверка условия всегда выполняется в начале цикла. Это значит, что те-
ло цикла может ни разу не выполниться, если условие выполнения сразу будет ложным.
Простейший пример иллюстрирует использование оператора for для вы-
10 s=0
числения конечной суммы S   i .
i 1
int s = 0; for (int i = 1; i <= 10; i++) s += i; i  1, 10
Возможно наличие пустого оператора (отсутствие оператор) в теле цикла. s=s+i
Так сумму из предыдущего примера можно вычислить иначе:
for (int s = 0 , i = 1; i <= 10; s += i++);
В этом примере выражение1 включает в себя два оператора, разделенных
4 “Программирование задач с циклами и массивами”
операцией запятая и задающих начальные значения переменным s и i.
Во втором варианте решения отсутствует оператор, а вначале задается Начало
значение двух переменных. В операторе возможны конструкции, когда отсут-
ствует то или иное выражение: выражение1 может отсутствовать, если на- Ввод х
чальное значение задать до этого; выражение2 – если предполагается, что ус-
ловие всегда истинно, т.е. надо обязательно выполнять тело цикла пока не S=0
встретится break; а выражение3 – если приращение параметра осуществлять в
теле цикла или таковое не требуется. Тогда само выражение пропускается, но k  1,7
точка с запятой обязательно должна быть.
k 1
x k 1 S = S + xk
7
Пример 1. Вычислить значение f(x) =  k , 2 k
k 1 2  k
значение х ввести с экрана.
void __fastcall TForm1::Button1Click(TObject *Sender)
{ float x=StrToFloat(Edit1->Text); Вывод S
float s=0;
for (int k=1; k<=7; k++)s=s+pow(x,k+1)/(pow(2,k)+k); Конец
Edit2->Text = FormatFloat("0.000",s);
}
n  1 n 3 k
m
Начало
Пример 2. Вычислить значение S    , значение m
n  2 n k 1 k  1
Ввод m
ввести с экрана.
void __fastcall TForm1::Button1Click(TObject *Sender)
{ int n, k, m=StrToInt(Edit1->Text);
float S=0, p;
for (n=-2; n<=m; n++) n   2, m
if (n!=-1 && !n)
{ p=1; да
for (k=1; k<=n+3; k++) нет n≠-1, n≠0
if (k!=-1 && k!=0) p*=(float) k/(k+1); да
} P=1
S+=(float)(n+1)*p/n;
Edit2->Text=FloatToStrF(S,ffGeneral,4,3); }
i  1,2i  1
Пример 3. Составить схему алгоритма и программу табулирования P=P*k/(k+1)
x k 1  cos 2 x
функции f(x)= , изменяя x от А= 0,4 до В=2,8 с шагом h=0,2.
5k
S=S+P*(n+1)/n
Начало
Ввод
A,B,h Вывод
S
x  A, B , h
Конец
y=0

k  1,10
y=y+ xk 1  cos2 x / 5k

Вывод x,y

Конец
“Программирование задач с циклами и массивами” 5

void __fastcall TForm1::Button1Click(TObject *Sender)


{ float A,B,h,x,y;
A=StrToFloat(Edit1->Text); B=StrToFloat(Edit2->Text);
h=StrToFloat(Edit3->Text);
for(x=A; x<=B +0.1*h; x+=h)
{ y=0;
for (int k=1; k<=10; k++) y+=pow(cos(x),2)*pow(x,k-1)/pow(5,k);
Memo1->Lines->Add(FormatFloat("0.00",x)+" "+ FormatFloat("0.0000",y));
Series1->AddXY(x,y,"",clRed); }
}
void __fastcall TForm1::Button2Click(TObject *Sender)
{ Edit1->Clear(); Edit2->Clear(); Edit3->Clear();
Memo1->Clear(); Series1->Clear();
}
void __fastcall TForm1::Button3Click(TObject *Sender)
{ Close(); }
Лабораторное задание
1 Дать ответы на контрольные вопросы.
2 Составить схему алгоритма и программу вычисления функции f(x) как суммы членов ряда.
Функцию f(x) выбирают из таблиц 3.1-3.3 согласно с номером фамилии студента в списке группы.
3 Составить схему алгоритма и программу табулирования функции f(x), изменяя x от 0,4 до 2,8
с шагом 0,2. При этом функцию f(x) выбирают из таблиц 1.1-1.2 согласно с заданным вариантом
(игнорируя в таблице значения x).

Таблица 1.1 – Индивидуальные задания среднего уровня сложности


7
2k  x k 12
Coskx  3 9
xk
1  ; x  0,52 2  ;x  3  Lnkx ; x  0,84
k 1 k  x k 1 k 5 k 1 k
9
x k 1 8
x 2k 11
x2k
4 
k 1 k  1
; x  1,79 5 
k 1 2 k
; x  1,75 6 
k 3 2 k  1
; x  2,342
12
Sinkx  7
xLn3k ; x  1,35 11
x  12 k ; x  0,81
7 
k 1 k
; x  0,94 8  2k
9  2k 
k 1 k 5
7
xk 8
k 2 xk 10
x 2k 1
10  k
k 1 2 k
; x  0,78 11 
k 1 2k 
; x  1,21 12 
k  2 2k  1
; x  0,84

Sin2kx 
 x Cosk ; x  1,51
9 1
xk 12
13  2k  ; x  2,73 14  2
; x  0,92 15
k x

k 1 k 6 k k 1
7
2 x
k k 9
sin x k 9
x 2k  1
16 k 1 k2
; x  0,52 17  k  0.2 ; x  1,34
k 0
18  sin x  1  1 ; x  0,375
k 2
10
k 2k  1 11
kx k 8
x 2k 1
19  ; x  0,19 20  ; x  1,22 21  ; x  0,99
xk 1 k 1 4 k  1 k 1 2 2k  1
2 k
k 1

6
x  1k 12
x 12k ; x  0,25 14
k 2Coskx
22  lg( 2  k )
k 1
; x  0, 25 23 
k 1  x  1
k
24  
k  3 2k  1
2
; x  1,84

9
tg ( x  k ) x k 1 10
x2k  1 11
k  1x k ; x  1,12
25 
k 2 k  1
; x  1,92 26 
k 1 2k 2 k  1
; x  2,73 27 
k  2 k  13
k

7
2 x 2 k 1 11
x 2k 1 9
x 2k 1
28 
k 1 32 k  1
; x  0,77 29 
k 1 4 k  1
2
; x  0,96 30 
k  2 2k  12
k
; x  2,75
6 “Программирование задач с циклами и массивами”
Таблица 1.2 – Индивидуальные задания высокого у ровня сложности
n
k  1 k 7 m 2  9 P
k
 j  6 j 12 3
i5 k
1  i i 2 k n  i
1 S   2  3 R  
k 1 k  5  m 1 m  2 j 1 j 3 i j i  11 i 1 i  3  n  i n  2

k
 j  2 j k 5  5 i  5  5i  k
 j  4 j 12 3
i5 n
 1k 1 k  7 
4 Z 
j  4 j 3
  i  11
i j 


5 A
j3
 i 1
6 Q
k!
j 1 i j k 1

n
 2 k 1 k  7 i 3  27 P 
k
 j  6 j k
 1i i  32
7 S   i7 8 9 W 
k  3 k  5 i 1 j  2  j  3 j  1! i 1 i!
k
 j  2 j k 5
 i5  n
 1k k  32 A
k
j 2

 4 j 9 i 3
10 Z  
j  3 i  j  i  11
 3,5i 

11 Q 12 
j  k  1 i j i  7
j 3 k 1 k! j 1
k
 1 i  3!
i k
cos(t ) t  i  2  k
 j  6 j 12 3
i5
13 W  
i 4
2
14 U  
t 2
 
t  3 i 1  i  7 
15 P 
j 1 j 3
 i  11
i j
i  2
k
 12n n 2  9  2

S 
n
 3 3 k 1 k n
m3  8 k
n  1 n  9
16 Y 
n  1!
17
k 1 k  2 3 k 1  m1 m  3
18 Z 
n  3!
n 1 n  2
k
 1i 2k n3  8 k
 j  2  j k 5  5 i  5  5i  n
(3i  1)(i  3)
19 W   2  20 Z    i  11 21 p
i 1 i  3 n i n  2 j 4 j 3 i j 

 i 1 2i  1!
k
 j  5 12 i5 k
i  1 i
n  0.8 2 k k
1i 2k n 3  8
22 L    23 Y   2 
24 W   2 
j 1 j3 i k i 1 i 1 3  i  n i ni i 1 i  3 ni n  2

Q
n
n  1k 1 k  3 k
2 j  1 k 5  i5 
27 Y  
k
k  i i i  2 !
25 26 G
4j3
  1  k  j 
k 1 (k  1)! j  3 i j   i  1 i2  4
k
t k t
 3i  2  k
 2 sin
i
(i  3)2 k n  2  n  4
k
28 Z 
t 0
 
cos(t )  3 i 1  i  7 
 29 D
i  3!
30 F 
n !
i  2 n 0

Индивидуальные задания повышенного уровня сложности

1. Из диапазона от 1 до 1000 найти и вывести все числа, заканчивающиеся цифрой 5.


N
2. Ввести натуральное число N. Вычислить s   ai2 , где
i0

i 3 при i кратном 3
ai  
i i  3 при i некратном 3
N i
j!
3. Ввести натуральное число N. Вычислить s   .
i 1 j 1 i!

4. Ввести натуральные числа N и M (до 6). Вычислить F=(M!+N!)/( M+N)!


N
5. Ввести натуральные числа N и M (N > M). Вычислить s  k
k M
2
ln( k!) .
N
i!
6. Ввести натуральное число N (до 6). Вычислить s   .
i 1 ( N  i )!
7. Из диапазона от 1 до 1000 найти и вывести все числа, заканчивающиеся цифрой 2.
8. Ввести натуральное число N. Определить, есть ли среди чисел число равное
i  17i  N  N , (i  1,2,...N ) .
3 2 2

9. Ввести натуральное число N и вещественное число х. Вычислить


(1/1!+|x|)+(1/2!+|x|)+…+(1/N!+|x|).
10. Из диапазона от 1 до 1000 найти и вывести все числа, заканчивающиеся цифрой 4.
“Программирование задач с циклами и массивами” 7
11. Ввести натуральное число N и вещественное число х. Вычислить
(1/2+cos|x|)+(2/3+cos|2x|)+…+(N/(N+1)+cos|Nx|).
15
A 5 при 0  A  15
12. Ввести вещественное число A>0. Вычислить s   ai , где ai  
i 1 A 25 при A  15
13. Ввести натуральное число N и вещественное число х. Вычислить
(1+sin(x)/1!)(1+sin(2x)/2!)…(1+sin(Nx)/N!).
15
14. Ввести вещественное число A. Вычислить s   min( 2 A, 1.95i) .
i 1

K
1 i 2 при i четных
15. Ввести натуральное число K. Вычислить p   , где ai  
i 1 ai i i  2 при i нечетных
N i
i!
16. Ввести натуральное число N. Вычислить s   .
i 1 j 1 ( j  1)!

17. Ввести натуральные числа N и M (N > M). Вычислить F=( N! - M!)/(N - M)!
N
1 k
18. Ввести натуральные числа N и M (N > M). Вычислить s   .
k  M 1  tg ( k!)
N
i!
19. Ввести натуральное число N (до 6). Вычислить s   .
i 1 ( N  i  1)!
6
20. Ввести вещественное число A. Вычислить p   max( A, 2i) .
i 1
21. Ввести натуральное число N и вещественное число х. Вычислить
(x/2+tg|x|)+(x2/3+tg|2x|)+…+(xN/(N+1)+tg|Nx|).
15
 A 3 при 0  A  10
22. Ввести вещественное число A>0. Вычислить s   ai , где ai  
i 1  A 5 при A  10
23. Ввести натуральное число N и вещественное число х. Вычислить
(1+sin(x)/1!)+(1+sin(x2)/2!)+…+(1+sin(xN)/N!).
24. Из диапазона от 1 до 1000 найти и вывести все числа, заканчивающиеся цифрой 3.
N
1  k!
25. Ввести натуральные числа N и M (N > M). Вычислить s   .
k  M ( N  k  1!)
26. Ввести натуральное число N и вещественное число х. Вычислить
(x/2!+ln|x|)+(x2/3!+ln|2x|)+…+(xN/(N+1)!+ln|Nx|).
10
27. Ввести вещественное число A. Вычислить s   max( A  5, 2,5i) .
i 1
28. Из диапазона от 1 до 1000 найти и вывести все числа, заканчивающиеся цифрой 7.
N
1  sin( k!)
29. Ввести натуральные числа N и M (N > M). Вычислить s   .
k  M 1  cos(k!)
9
A
30. Ввести вещественное число A. Вычислить p   min( , i) .
i 1 2

Протокол лабораторной работы №2.1


8 “Программирование задач с циклами и массивами”
“Программирование задач с циклами и массивами” 9
10 “Программирование задач с циклами и массивами”

Лабораторная работа № 2.2


Организация вычислений с использованием условных
операторов цикла
Цель работы: Изучить условные операторы цикла while и do-while. Приобрести навыки их
использования при разработке циклических программ.

Контрольные вопросы
1 Структура оператора циклу while.
2 Порядок выполнения оператора while.
3 Какое значение получит переменная n после выполнения операторов?
int k=0, n=17;
while (k<7) { k++; n--; }
4 Структура оператора цикла do-while.
5 Порядок выполнения оператора do-while.
6 Чем отличаются операторы цикла while и do-while?
7 Какое значение получит переменная р после выполнения операторов?
int i=1, p=1;
do { i++; p*=i; } while (p<7);

Теоретические сведения
Форматы операторов цикла с предусловием while и постусловием do-while:
while (условие) { последовательность операторов };
Последовательность операторов цикла выполняется нуль или бо-
лее раз до тех пор, пока условие истинно (имеет ненулевое значение), а Условие?
выход из цикла осуществляется тогда, когда оно станет ложным (равно
нулю). Операторы
do { последовательность операторов } while (условие);
Последовательность операторов выполняется один или несколько раз
до тех пор, пока условие станет ложным (равным нулю). Оператор цикла
do-while используется в тех случаях, когда необходимо выполнить тело Операторы
цикла хотя бы один раз, т.к. проверка условия осуществляется после вы-
полнения операторов. да
Условие?
Если тело цикла состоит из одного оператора, то операторные скобки
{} не обязательны. Операторы while и do-while могут также завершиться
при выполнении операторов break, goto, return внутри тела. нет
Пример 1. Вычислить сумму знакопеременного ряда
5
(1) i 1 x i 1
S  тремя вариантами, используя разные операторы цикла.
i 1 2i  1!
Здесь (-1)i+1 при нечетных значениях i (1, 3, 5, …) равняется 1, а при
четных значениях i (2, 4, 6, …) – -1, т.е. рассматривается знакочередую-
щийся ряд. Поэтому в программе надо предусмотреть проверку на чет-
ность (i%2==0).
Примеры программ с использованием разных операторов цикла:
void __fastcall TForm1::Button1Click(TObject *Sender) // Оператор for
{ int i,f,k;
float s=0, x=StrToFloat(Edit1->Text);
for( i=1;i<=5;i++)
{ for( k=1,f=1;k<=2*i-1;k++) f*=k;
if( i%2 == 0) s+=pow(x, i+1)/f; else s-= pow(x, i+1)/f ;
}
“Программирование задач с циклами и массивами” 11
Edit2->Text=FloatToStr(s);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender) // Оператор while
{ int i=1,f,k;
float s=0, x=StrToFloat(Edit1->Text);
while( i<=5)
{ f=1; k=1;
while(k<=2*i-1){f*=k; k++; }
if(i%2==0) s+=pow(x, i+1)/f; else s-= pow(x, i+1)/f ;
i++;
}
Edit3->Text=FloatToStr(s);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender) // Оператор do-while
{ int i=1,f,k;
float s=0, x=StrToFloat(Edit1->Text);
do
{ f=1; k=1;
do {f*=k; k++; }while(k<=2*i-1) ;
if(i%2==0) s+=pow(x, i+1)/f; else s-= pow(x, i+1)/f ;
i++;
} while( i<=5);
Edit4->Text=FloatToStr(s);
}

Блок-схемы для разных операторов цикла:


Начало Начало
Начало
S = 0, i=1 S = 0, i=1
S=0
Ввод х Ввод х
Ввод х
нет f=1, k=1
i = 1, 5 i <= 5
да
f = 1, k=1 f=f*k, k=k+1
f=1
нет да
k = 1,2i-1 k<=2i-1 k<=2i-1
да нет
f=f*k, k=k+1 нет да
f=f*k i–четн?
S=S–xi+1/f S=S+xi+1/f
нет да
нет да i–четн? i=i+1
i–четн?
i+1 i+1
S=S–xi+1/f S=S–x /f S=S+x /f да
S=S+xi+1/f i <= 5
i=i+1 нет
Вывод
Вывод
S
S Вывод
S Конец
Конец
Конец

Оператор for Оператор while Оператор do-while


12 “Программирование задач с циклами и массивами”

x 2 k 1
Пример 2. Вычислить сумму ряда S  
k 1 ( 2 k  1 )!
, суммируя члены ряда, значения ко-

торых по модулю больше заданной точности   10 4 . Определить количество слагаемых. Значе-


ние х (-2<x<2) вводить с клавиатуры.
При разработке программы для решения данной задачи неуместно Начало
использовать оператор цикла с параметром for, поскольку заранее неиз-
вестно количество повторений такого цикла. Ввод х
Целесообразным будет использование
оператора цикла с постусловием do-while, по- S = 0, k=0
скольку на момент первой проверки условия
уже необходимо знать значение первого сла- k=k+1, f=1
гаемого.
i  1,2k  1
void __fastcall TForm1::Button1Click(TObject *Sender)
{ float x, a, s=0; // Объявление переменных и f=f*i
int f, i, k=0; // установка их начальных значений
x=StrToFloat(Edit1->Text); // Ввод значения х
do // Цикл с постусловием Вычисл. а
{ k++; // Увеличение переменной k на 1
for(i=1,f=1; i<=2*k-1; i++)f*=i; // Вычисление факториала
S=S+а
a=pow(x, 2*k+1)/f; // Вычисление k-го слагаемого
s+=a; } // Суммирование слагаемых
while(fabs(a)>=1e-4); да
a  10 4
Edit2->Text=FloatToStr(s) ; // Вывод полученной суммы и
нет
Edit3->Text=IntToStr(k); // количества слагаемых
Вывод
}
S, k

 1k x 2 k Конец
Пример 3. Вычислить сумму ряда y   2 k ( 2 k  1)! ,
k 1
суммируя

члены ряда, значения которых по модулю больше заданной точности  . Определить количество
слагаемых. Значения х (-2<x<2) и   10 4 вводить с клавиатуры.
Множитель (-1)k при нечетных k=1,3,5,… равняется (-1), а при четных k=2,4,… равняется 1.
Таким образом представленный ряд является знакочередующимся, где все нечетные слагаемые
будут отрицательными, а все четные – со знаком «+». Для наглядности и контроля правильности в
решении отдельно приведем все слагаемые.
Для того, чтобы сделать алгоритм программы более оптимальным можно его усовершенст-
вовать, но для этого надо вычислить рекуррентный множитель. Это позволит в данной программе
избавится от вложенного цикла для вычисления факториала и оператора проверки на нечетность k.
Остановимся более подробно на выведении рекуррентной формулы.

Представим сумму ряда y  



 1 x 2 k
k 
в виде y   u k , где u k 
 1 x 2k
k
. Рекур-
k 1 2 k ( 2 k  1)! k 1 2k (2k  1)!
рентный множитель – это соотношение двух рядом расположенных членов ряда:
u 2  R  u1 , u3  R  u 2 , …, u k  R  u k 1 .
u
Откуда R k . (1)
u k 1

Для определения R в формулу (1) надо подставить u k 


 1k x 2k и u k 1 . Для вычисления
2k (2k  1)!
u k 1 подставим в выражение для u k вместо k – (k-1):

u k 1 
 1k 1 x 2( k 1) =
 1k 1 x 2( k 1) .
2( k  1)(2(k  1)  1)! 2( k  1)(2k  3)!
“Программирование задач с циклами и массивами” 13

R
uk
=
 1k x 2 k ∙ 2(k  1)(2k  3)! = (1) k  x 2 k  (2k  2)  (2k  3)! =
u k 1 2k (2k  1)!  1k 1 x 2( k 1) (1) k 1  x 2k 2  2k  (2k  1)!
(1) k k 1  x 2 k ( 2 k  2) (2k  2) 1  2  ...  (2k  3) x2
=  =– .
2k 1  2  ...  (2k  3)  (2k  2)  (2k  1) 2k (2k  1)
Кроме рекуррентного множителя R надо вычислить первый член ряда при k=1:

u1 
  1 x 2
1
= 
x2
.
2(2  1)! 2
void __fastcall TForm1::Button1Click(TObject *Sender)
{ float x,y,u,r,eps; Memo1->Clear();
x=StrToFloat(Edit1->Text);
eps=StrToFloat(Edit2->Text);
int i,f,k=1;
u=-x*x/2; y=u;
Memo1->Lines->Add(IntToStr(k)+") "+
FormatFloat("0.00000",u));
do
{ k++;
r = -x*x/(2*k*(2*k-1));
u *= r ;
Memo1->Lines->Add(IntToStr(k)+") "+ FormatFloat("0.00000",u));
y += u; }
while(fabs(u)>=eps) ;
Edit3->Text=FloatToStr(y);
Edit4->Text=IntToStr(k);
}

Лабораторное задание
Индивидуальные задания среднего уровня сложности
Составить схемы алгоритмов и программы вычисления функции f(x) тремя вариантами с ис-
пользованием разных операторов цикла. Функцию f(x) выбирают из таблиц 1.1-1.2. Т.е. задание
заключается в дополнении программы выполнения предыдущей лабораторной работы еще двумя
вариантами решения этой же задачи, но с использованием условных операторов цикла. См. при-
мер № 1.
Индивидуальные задания высокого уровня сложности

Составить схемы алгоритмов и программы вычисления функции бесконечного ряда u k ,
k 1
суммируя члены ряда, значения которых по модулю не превышает заданной точности   10 4 .
Определить количество суммируемых слагаемых. Вычисления выполнить для х=0,5. Использовать
оператор цикла while для нечетных вариантов и do-while для четных. Задания выбрать из таблицы
2.1 согласно индивидуальному варианту. См. пример № 2.
Индивидуальные задания повышенного уровня сложности

Составить схемы алгоритмов и программы вычисления функции бесконечного ряда u k ,
k 1
суммируя члены ряда, значения которых по модулю не превышает заданной точности   10 4 .
Определить количество суммируемых слагаемых. Значения х (-2 < x < 2) ввести с клавиатуры. За-
дания выбрать из таблицы 2.1 согласно индивидуальному варианту. Для достижения большей оп-
тимальности алгоритма в программе использовать рекуррентные формулы для вычисления чле-
нов ряда. См. пример № 3.
14 “Программирование задач с циклами и массивами”
Таблица 2.1 – Индивидуальные задания
 ( 1 )k x 2 k 1  ( 1 )k 1 x 2 k 
( 1 )k 1 x k  ( 1 ) k 1 x 2 k
1  2  3  4 
k 1 ( 2k  1 )! k 1 ( 2k  1 )! k 1 k! k !2 k
k 1
 ( 1 )k x 2 k 1  ( 1)k1 xk1  ( 1 )k x 2( k 1 )  ( 1 )k 1 x 3k 1
5  2k  ( 2k  1 )! 6 ( 2k 1)( k 1)! 7  8 
k 1 k1 k 1 ( k  2 )k ! k 1 ( 2k )!
 k 1 k 2    (1) k 1 x k 3
( 1 ) x ( 1 )k x 2 k 1 ( 1 )k 1 x 3k 1
9  10  11  12 
k 1 k ( 2k  1 )! k 1 ( 2k  1 )! k 1 3k  ( k  1 )! k 1 k 2 (k  2)!
   ( 1) k 1 x 3k 2 
( 1 ) k x 3k 1 ( 1 )k 1 x 3( k 2 ) ( 1 )k x 2 k 1
13  2k( k  3 )! 14  15  16 
k 1 k 1 ( k  3 )( 3k )! k 12 k  1  k! k 1 ( 2k  1 )!
 ( 1 )k 1 x 2 k  ( 1 )k 1 x 2 k  ( 1 )k 1 x k  ( 1 )k 1 x k 1
17  ( 2k  1 )! 18  19  20 
k 1 k!2 k  1
k 1 k 1 ( k  4 )! k 12k( 2k  1 )!
 ( 1 )k x 2k 1  ( 1 )k 1 x 3 k 1  ( 1 )k x 2( k 1 )  ( 1 )k x 2k 1
21  22  23  ( 2k )! 24 
k 1( 2k  1 )( k  1 )! k 1 ( k  2 )k ! k 1 k 1k  ( 2k  1 )!
 ( 1 )k x 2 k 1  ( 1 ) k x 3k 1
( 1 )k 1 x 3k 1  ( 1 ) k x 3k 1
25  26  27  28 
k 1 3k ( 2k  1 )! k 1 k 2 ( k  1 )! k 1( k  3 )( 3k )!  1 )!k 2
k 1( k
    (1)k xk (2k 1)
( 1 )k 1 x 3k  2 ( 1 )k 1 x 3( k 2 ) ( 1) k x 2 k 1
29  30  31  32 
k 1 2k ( k  3 )! k 1 ( k  3 )( 3k )! k 1 k (k  3)! k1 (3k 2)!

Протокол лабораторной работы №2.2


“Программирование задач с циклами и массивами” 15
16 “Программирование задач с циклами и массивами”
“Программирование задач с циклами и массивами” 17
Лабораторная работа № 2.3
Функции
Цель работы: Изучить средства организации функций алгоритмическим языком C++.

Контрольные вопросы
1 Укажите количество результатов, которое может напрямую возвращать функция?
2 Какое значение результата выполнения функции по умолчанию?
3 Какие правила выдвигаются к расположению, типу и количеству формальных параметров в
описании функции и фактических параметров при вызове функции? (Выберите правильные ответы.)
а) тип и порядок расположения свободный;
б) строгое соблюдение типа и порядка расположения;
в) количество фактических и формальных параметров должно быть одинаковым;
г) количество фактических и формальных параметров может отличаться.
4 Составьте два примера функций (с использованием рекурсии и без нее) для вычисления
факториала некоторого числа N.
Теоретические сведения
Процесс разработки программного обеспечения предполагает разделение сложной задачи на
набор более простых задач и заданий. В С++ поддерживаются функции как логические единицы
(блоки текста программы), служащие для выполнения конкретного задания. Функции иногда еще
называют подпрограммами. Подпрограммы решают небольшую и специфическую часть общей
задачи. В отличие от других языков программирования высокого уровня в языке С++ нет деления
на подпрограммы процедуры и подпрограммы функции.
Функция – это совокупность объявлений и операторов, она обычно предназначена для реше-
ния определенной задачи. Каждая функция должна иметь имя, которое используется для ее объяв-
ления, определения и вызова.
При вызове функции ей при помощи аргументов (формальных параметров) могут быть пере-
даны некоторые значения (фактические параметры), используемые во время выполнения функции.
Функция может возвращать некоторое (одно!) значение. Это возвращаемое значение и есть ре-
зультат выполнения функции, который при выполнении программы подставляется в точку вызова
функции, где бы этот вызов ни встретился. Допускается также использовать функции, не имею-
щие аргументов, и функции, не возвращающие никаких значений. Действие таких функций может
состоять, например, в изменении значений некоторых переменных.
Пример 1: Вычислить сумму знакопеременного ряда Вход в sum
5
(1) i 1 x i 1
S  . 1
Начало For S=0
i 1 i!
2
Вычисления по выполнению задания Ввод x i = 1, 5
организуем в функции.
3 f=1
float sum(float x) s=zikl_for(x)
{ int i,f,k; float s=0; 4
k = 1, i
for( i=1;i<=5;i++) Вывод s
{ for( k=1,f=1;k<=i;k++) 5 f=f*k
f*=k; Конец
if(i%2==0)s+=x/f;
else s-=x/f ; Блок-схема для
} кнопки «Решение» нет да
i–четн?
return s;
} S=S–xi+1/f S=S+xi+1/f
void __fastcall TForm1::Button1Click (TObject *Sender)
{ float s, x=StrToFloat(Edit1->Text);
s=sum(x); Выход из sum
Edit2->Text=FloatToStr(s);
} Блок-схема функции sum
18 “Программирование задач с циклами и массивами”

x 2 k 1
Пример 2: Вычислить сумму ряда S  k 1 ( 2 k  1 )!
, суммируя члены ряда, значения ко-

торых по модулю больше заданной точности   10 4 . Значение х (-2<x<2) вводить с клавиатуры.


Эта задача была уже рассмотрена в лекции № 1 примере № 6. Преобразуем решение таким
образом, чтобы в головной программе остались операторы ввода/вывода
данных, а все вычисления по выполнению задания организуем в функции. Вход в sum

S = 0, k=0
Начало

Ввод х, k=k+1, f=1


eps
i  1,2k  1
Вызов
s=sum(х,eps) f=f*i
Вид формы проекта с Вывод s
результатами
Конец Вычисл. а
float sum(float x,float eps)
{ float a,s=0; int f,i,k=0; Блок-схема голов-
do // Цикл с постусловием ной программы S=S+а
{ k++; // Увеличение переменной k на 1
for(i=1,f=1;i<=2*k-1;i++)f*=i; // Вычисление факториала да
a  10 4
a=pow(x,2*k+1)/f; // Вычисление k-го слагаемого
s+=a; } // Cуммирование слагаемых нет
while(fabs(a)>=1e-4); Выход из sum
return s; } Блок-схема функции
void __fastcall TForm1::Button1Click(TObject *Sender) sum
{ float x,eps,s;
x=StrToFloat(Edit1->Text); // Ввод значения х
eps=StrToFloat(Edit2->Text); // Ввод значения точности
s=sum(x,eps); // Вызов функции
Edit3->Text=FloatToStr(s) ; // Вывод полученной суммы
}

Лабораторное задание
Составить схемы алгоритмов, разработать проект формы и программы алгоритмическим
языком C++ для выполнения индивидуального задания согласно индивидуальному варианту. В
проекте предусмотреть ввод исходных данных с клавиатуры и вывод полученных результатов на
форму в компоненты в головной программе, а обработку данных, т.е. все вычисления, организо-
вать в функциях.
Индивидуальные задания согласно уровню сложности по указанию преподавателя выбира-
ются из таблиц предыдущих лабораторных работ № 3 и № 4. То есть, задание заключается в рабо-
те с уже существующими программными проектами таким образом, чтобы в головной программе
остались операторы ввода/вывода данных, а все вычисления по выполнению индивидуального за-
дания организовывались в функциях (см. примеры 1 и 2).

Протокол лабораторной работы №2.3


“Программирование задач с циклами и массивами” 19
20 “Программирование задач с циклами и массивами”
“Программирование задач с циклами и массивами” 21
Лабораторная работа № 2.4
Одномерные массивы
Цель работы: Знакомство с простейшими из структурированных типов данных – одномер-ным
массивом. Изучить средства обработки одномерных массивов в C++.

Контрольные вопросы
1 Что называется массивом в программировании?
2 Что является индексом массива? Переменные каких типов можно использовать для индексов?
Как обозначаются индексы массива?
3 Какие из приведенных ниже описаний одномерного массива из 10 элементов ошибочны?
а) int A [1..10]; б) float A :[10]; в) int A [9]; г) float A [0, 9];
4 Запишите объявление одномерного массива из 25 вещественных чисел.
5 Запишите объявление одномерного констант-массива из последовательности символов Вашей
фамилии.
6 Какие компоненты формы проекта в C++ Builder для вывода значений одномерных массивов
Вы знаете?
7 Какие компоненты формы проекта в C++ Builder для ввода значений одномерных массивов Вы
знаете?
8 Запишите операторы ввода массива из 15 целых чисел с помощью компонентов Memo или
ListBox.
9 Запишите операторы вывода массива из 17 вещественных чисел в пять разных компонентов.
10 Запишите операторы определения среднего значения для массива из 12 вещественных чисел.
Теоретические сведения
Массив (Array) в программировании – это упорядоченная совокупность однотипных элемен-
тов. Массивы широко используют для хранения и обработки однородной информации, например,
таблиц, векторов, матриц, коэффициентов уравнений и др.
Одномерный массив объявляется в программе следующим образом:
тип_данных имя_массива [размер_массива];
Имя_массива – это идентификатор массива. Тип_данных задает тип элементов объявляемого мас-
сива. Размер_массива в квадратных скобках задает количество элементов массива. В отличие от
языка Pascal в С не проверяется выход за пределы массива, поэтому, чтобы избежать ошибок в
программе, следите за размерами описанных массивов.
Каждый элемент массива однозначно определяется именем и индексами. Индексы определя-
ют местоположение элемента в массиве. Например: int A[10];
объявляет массив с именем А, содержащий 10 целых чисел. А[0] – значение первого элемента, А[1]
– второго, А[9] – последнего.
Количество индексов определяет размерность массива. Например, векторы в программах –
это одномерные массивы, матрицы – двумерные.
При объявлении массивов можно элементам массива (не обязательно всем) присваивать пер-
воначальные значения, которые в дальнейшем в программе могут быть изменены. Если количест-
во инициализируемых значений меньше, чем размерность массива, то всем остальным элементам
массива присваивается значение 0.
Например,
int a[5] = {9, 33, -23, 8, 1}; // а[0]=9, а[1]=33, а[2]=-23, а[3]=8, а[4]=1
float Q[10] = {1.5, -3.8, 10}; // Q[0]=1.5, Q[1]= -3.8, Q[2]=10, Q[3]=Q[4]=…=Q[9]=0
char S[3]="Фото"; // S[0]="Ф", S[1]="о", S[2]="т", S[3]="о"
char code[ ] = "abc"; // code[0]= "a", code[1]= "b", code[2]= "c", code[3]= "\0"
В последнем примере инициализируется code как массив символов из четырех элементов. Четвер-
тым элементом является символ "\0", который завершает все строковые литералы. Если строка ко-
роче, чем специфицированный размер массива, то оставшиеся элементы массива инициализиру-
ются нулем (символом "\0").
22 “Программирование задач с циклами и массивами”
Пример 1. Разработать схему алгоритма и 1
Начало
проект программы для ввода элементов одномерного 2
массива из 8 вещественных элементов и вычисления sum=0
суммы всех элементов массива. 3
void __fastcall TForm1::Button1Click(TObject *Sender)
i  0,7
{ float A[8], sum=0;
4
int i; Ввод
for(i=0; i<8; i++) A[i]
{ A[i]=StrToFloat(Memo1->Lines->Strings[i]); 5
sum+=A[i]; } sum=sum+A[i]
Edit1->Text=FormatFloat("0.000",sum) ;}
void __fastcall TForm1::Button3Click(TObject *Sender)
{ Memo1->Clear(); 6
Edit1->Clear(); } Вывод
void __fastcall TForm1::Button2Click(TObject *Sender) sum
{ Close(); } Вид формы с ре- 7
зультатами работы Конец
Блок-схема
Пример 2. Составить схему алгоритма и проект 1
программы для ввода элементов одномерного массива из Начало
7 целых чисел, определения минимального элемента и 2

его порядкового номера. i  0,6


3
Ввод
void __fastcall TForm1::Button1Click(TObject *Sender)
{ int A[15] ; int i;
A[i]
for(i=0; i<7; i++) 4
A[i]= StrToInt(Memo1->Lines->Strings[i]); min=A[0], ind=0
int min=A[0], ind=0; 5
for(i=1; i<7; i++) i  1,6
if(min>A[i]) { min=A[i]; ind=i; }
нет 6
Edit1->Text = IntToStr(min)+" индекс - "+IntToStr(ind+1); Вид формы с ре- min>A[i]
} зультатами работы да
7
Пример 3. Разработать схему алгоритма и проект программы для ввода min=A[i], ind=i
11-ти (или меньше) целых чисел из компонента Мемо и отсортировать их по
возрастанию. 8
min, ind+1
sort(int a[], int n) 9

{ int i,j,tmp; Конец


for (i=0;i<n-1;i++) Блок-схема
for (j=i+1; j<n; j++)
if (a[i]>a[j]) // сравнение элементов
{ tmp=a[i]; // перестановка элементов a[i] и a[j]
a[i]=a[j]; // переменная tmp необходима для
a[j]=tmp; } // временного хранения одного из значений
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{ int n, i, a[11];
// Определение количества реально заполненных строк Memo1
n=Memo1->Lines->Count;
for (i=0; i<n; i++) a[i]=StrToInt(Memo1->Lines->Strings[i]);
ShowMessage("Количество элементов массива "+IntToStr(n)) ;
sort(a,n); // вызов функции
Memo2->Clear();
for (i=0; i<n; i++) Memo2->Lines->Add(IntToStr(a[i]));
} Форма проекта с результатами
“Программирование задач с циклами и массивами” 23
Лабораторное задание
Составить схемы алгоритмов, разработать проект формы и программы для выполнения ин-
дивидуального задания согласно варианту у C++ Builder. В проекте предусмотреть ввод элементов
массива с клавиатуры через компонент Memo и вывод полученных результатов на форму в компо-
ненты Edit, Memo, ListBox или Label (по указанию преподавателя).
Таблица 4.1 – Индивидуальные задания среднего уровня сложности
№ Раз- Тип дан-
вар мер ных
Индивидуальное задание
мас-
сива
1 15 целый Вычислить сумму четных элементов массива
2 10 веществ. Вычислить среднее арифметическое всех элементов массива
3 8 целый Вычислить факториал значения последнего элемента массива
4 12 веществ. Вычислить произведение элементов, значения которых меньше чем 6
5 14 целый Вычислить среднее арифметическое четных элементов массива
6 18 веществ. Упорядочить по возрастанию массив
7 11 целый Расположить элементы массива в обратном порядке
8 14 веществ. Массив содержит положительные и отрицательные элементы. Располо-
жить элементы массива в порядке возрастания значений их модулей.
9 16 целый Вычислить сумму элементов массива, значения которых можно поде-
лить на два без остатка
10 14 веществ. Вычислить сумму элементов, абсолютное значение которых не превы-
шает 1.5
11 17 целый Вычислить полусумму минимального и максимального элементов мас-
сива
12 9 веществ. Вывести количество элементов, больших чем значение первого
элемента массива
13 15 целый Вычислить индексы минимального и максимального элементов массива
14 10 веществ. Вычислить сумму тех элементов массива, значения которых принадле-
жат промежутку [3, 6]
15 8 целый Вычислить произведение нечетных элементов массива
16 12 веществ. Вычислить произведение минимального и максимального элементов
массива
17 20 целый Упорядочить по убыванию массив
18 18 веществ. Вычислить среднее арифметическое положительных элементов
19 11 целый Вычислить количество элементов, меньших чем значение последнего
элемента массива
20 9 веществ. Вычислить разницу между произведением всех положительных элемен-
тов и суммой модулей всех отрицательных
21 16 целый Вычислить среднее арифметическое нечетных элементов массива
22 19 веществ. Вычислить сумму минимального элемента и его индекса
23 17 целый Вычислить количество положительных, отрицательных и нулевых эле-
ментов
24 8 веществ. Вычислить произведение элементов, значения которых меньше значе-
ния последнего элемента
25 7 целый Вычислить произведение положительных элементов, которые не пре-
вышают число 4
26 18 веществ. Вычислить сумму минимального и максимального элементов массива
27 11 целый Вычислить сумму отрицательных элементов массива
28 10 веществ. Вычислить сумму квадратов тех чисел, модуль которых превышает зна-
чения 2.5
24 “Программирование задач с циклами и массивами”
№ Раз- Тип дан-
вар мер ных
Индивидуальное задание
мас-
сива
29 12 целый Вычислить сумму модулей всех отрицательных элементов массива
30 9 веществ. Вычислить произведение тех элементов массива, значения которых
принадлежат промежутку [2, 5]

Таблица 4.2 – Индивидуальные задания высокого уровня сложности


№ Раз- Тип дан-
вар мер ных
Индивидуальное задание
мас-
сива
1 15 целый Вычислить сумму S положительных нечетных элементов и заменить
четные элементы массива на S
2 10 веществ. Поменять местами минимальный элемент с предпоследним элементом
3 12 целый Вычислить факториал первого элемента массива, значения которого
меньше чем 8
4 8 веществ. Проверить является ли массив упорядоченным по возрастанию и выдать
об этом сообщение
5 14 целый Вычислить новый массив разницу элементов исходного массива и их
среднего арифметического
6 18 веществ. Вычислить максимальный элемент и поменять его местами с последним
элементом.
7 11 целый Упорядочить массив по убыванию и определить индекс элемента рав-
ный F. Число F ввести с клавиатуры.
8 14 веществ. Вычислить процентное содержание отрицательных, положительных и
нулевых элементов
9 7 целый Вычислить произведение нечетных элементов и построить новый мас-
сив разницы элементов исходного массива и вычисленного произведе-
ния
10 19 веществ. Вычислить количество элементов, больших чем среднее арифметиче-
ское всех элементов
11 17 целый Из исходного массива построить новый, расположив сначала все положи-
тельные элементы и нули, после чего отрицательные, сохраняя порядок их
следования
12 9 веществ. Заменить все отрицательные элементы максимальным
13 15 целый Определить минимальный элемент и поменять его местами с первым
элементом
14 10 веществ. Вычислить максимальный и минимальный элементы и поменять их мес-
тами
15 8 целый Вычислить факториал индекса максимального элемента
16 12 веществ. Вычислить сумму всех элементов от начала до первого отрицательного.
Если среди элементов нет отрицательных, выдать об этом сообщение и
вычислить сумму всех элементов
17 20 целый Вычислить сумму элементов с четными индексами и построить новый
массив разницы элементов исходного массива и вычисленной суммы
18 18 веществ. Вычислить сумму элементов массива, значение которого больше чем
среднее арифметическое
19 11 целый Вычислить из четных положительных элементов минимальный
20 9 веществ. Вычислить максимальный элемент из числа отрицательных элементов
21 16 целый Построить новый массив остатков от деления нацело элементов массива
“Программирование задач с циклами и массивами” 25
№ Раз- Тип дан-
вар мер ных
Индивидуальное задание
мас-
сива
на 3
22 19 веществ. Заменить все нулевые элементы значением минимального элемента
23 17 целый Вычислить остаток от деления суммы элементов с нечетными индекса-
ми на сумму элементов с четными индексами
24 8 веществ. Поменять местами первую половину массива со второй
25 7 целый Заменить все нечетные элементы массива единицами (нечетные по зна-
чению, а не по индексу)
26 18 веществ. Вычислить разницу между суммой элементов, индексы которых кратны
3, и суммой элементов, индексы которых кратны 4
27 11 целый Заменить четные по значению (а не по индексу) числа на нули.
28 10 веществ. Поменять местами элементы, стоящие в массиве рядом (1 и 2, 3 и 4 и
т.д.)
29 16 целый Определить из нечетных отрицательных элементов наибольший
30 12 веществ. Определить индекс первого отрицательного элемента. При отсутствии
отрицательных элементов выдать об этом сообщение

Таблица 4.3 – Индивидуальные задания повышенного уровня сложности


№ Раз- Тип дан-
вар мер ных
Индивидуальное задание
мас-
сивов
1 до 9 целый Ввести два массива и вычислить количество одинаковых элементов в
них
2 до 10 веществ. Ввести два массива и построить третий из упорядоченных по возраста-
нию значений элементов обоих массивов
3 до 12 целый В массиве, каждый элемент является 0, 1 или 2, переставить элементы
массива так, чтобы сначала были расположены все 0, потом все 1, и, в
конце, все 2
4 до 8 веществ. Ввести массив и число С. Переставить числа в массиве так, чтобы сна-
чала были расположены все элементы меньше или равные значению С,
потом больше чем С, сохраняя порядок их расположения
5 до 14 целый Определить первое число, присутствующее в каждом из трех массивов,
значения в этих массивах расположены по возрастанию
6 до 7 веществ. Ввести два массива и построить третий из общих элементов массивов
7 до 11 целый Ввести массив, в котором только два одинаковых элемента. Определить
их индексы
8 до 14 веществ. Ввести массив и число L. Построить новый массив из элементов мень-
ших, чем L, и упорядочить новый массив по убыванию.
9 до 19 целый Определить пару соседних элементов массива, значения которых бли-
жайшие друг к другу, т.е. значение |xi+1 - xi| минимальна
10 до 12 веществ. Вычислить произведение Р отрицательных элементов с четными индек-
сами, которые не превышают заданного числа L, и поделить все поло-
жительные элементы на Р
11 до 17 целый Ввести массив и на его основе создать два новых массива: первый из
элементов с нечетными индексами, второй из элементов кратных 5
12 до 9 веществ. Ввести массив и число Р. Определить элемент массива, значение кото-
рого самое близкое к Р, т.е. значение |xi - Р| минимальна
13 до 15 целый Упорядочить массив так, чтобы все положительные числа были распо-
26 “Программирование задач с циклами и массивами”
№ Раз- Тип дан-
вар мер ных
Индивидуальное задание
мас-
сивов
ложены сначала по возрастанию, а все отрицательные – в конце по убы-
ванию
14 до 10 веществ. Ввести два массива и определить количество неодинаковых элементов в
них
15 до 8 целый Ввести два массива и заменить нулями те элементы первого массива,
которых нет во втором
16 до 12 веществ. Вычислить сумму S отрицательных элементов, которые не превышают
заданного числа L, и поделить последний положительный элемент на S
17 до 20 целый Ввести массив и число К. Создать два новых массива: первый из эле-
ментов меньших или равных значению К, второй из элементов больших
чем К, сохраняя порядок их расположения
18 до 18 веществ. Ввести массив, содержащий много нулевых элементов. Заменить все
группы подряд расположенных нулей на значения количества нулей
19 до 11 целый Вычислить сумму S положительных нечетных элементов и заменить все
четные элементы массива на S
20 до 9 веществ. Ввести два массива, определить максимальные элементы каждого из
них и поменять их местами
21 до 16 целый Ввести массив и на его основе создать новый из отрицательных и нуле-
вых элементов с четными индексами
22 до 19 веществ. Ввести два массива, определить минимальный элемент первого и мак-
симальный элемент второго каждого из них и поменять их местами
23 до 17 целый Ввести массив и на его основе создать два новых массива: первый из
четных элементов, второй из еле элементов кратных 3
24 до 8 веществ. Ввести два массива и заменить нулями те элементы второго массива,
которые есть в первом
25 до 7 целый Ввести два массива и поменять местами максимальный элемент первого
массива с первым элементом второго, который больше чем 5
26 до 18 веществ. Ввести массив и на его основе создать новый из положительных эле-
ментов, больших чем среднее арифметическое всех элементов
27 до 15 целый Ввести массив и число L. Построить новый массив из элементов боль-
ших чем L и упорядочить новый массив по возрастанию
28 до 10 веществ. Определить пару соседних элементов массива, значения которых мак-
симально разнятся друг от друга, т.е. значение |xi+1 - xi| максимально
29 до 16 целый Ввести массив, содержащий много нулевых элементов. Заменить все
группы подряд расположенных нулей на один нуль
30 до 12 веществ. Ввести два массива, определить минимальные элементы каждого из них
и поменять их местами

Протокол лабораторной работы №2.4


“Программирование задач с циклами и массивами” 27
28 “Программирование задач с циклами и массивами”
“Программирование задач с циклами и массивами” 29
30 “Программирование задач с циклами и массивами”
Лабораторная работа №2.5
Многомерные массивы
Цель работы: Изучить средства использования многомерных массивов в программах C++.
Контрольные вопросы
1 Как определить размерность массива?
2 Какие из приведенных ниже объявлений двумерных массивов неправильны и почему?
а) int C [1..5, 1..5]; в) float C [ 1..5][1..5];
б) float C[5][5]; г) int C: [5][5] ;
3 Матрица целых чисел состоит из 3-х строк и 5-ти столбцов. Напишите фрагмент программы
для ввода ее элементов с компонента StringGrid.
4 Матрица целых чисел состоит из 3-х строк и 2-ти столбцов. Присвойте значения элементам
массива при объявлении.
5 Для матрицы вещественных чисел, из 3-х строк и 5-ти столбцов напишете фрагмент про-
граммы для вывода на форму ее элементов в компонент StringGrid.

Теоретические сведения
Многомерный массив объявляется в программе следующим образом:
тип имя [ размер 1] [ размер 2] … [ размер n];
Количество элементов массива равно произведению количества элементов по каждому индек-
су. Например, int B[3][4];
Объявлен двумерный массив из 3 строк и 4 столбцов (12 элементов) массива целого типа:
В[0,0], В[0,1], В[0,2], В[0,3],
В[1,0], В[1,1], В[1,2], В[1,3],
В[2,0], В[2,1], В[2,2], В[2,3];
Типу массив соответствует память, которая требуется для размещения всех его элементов.
Элементы массива с первого до последнего запоминаются в последовательных возрастающих ад-
ресах памяти. Между элементами массива в памяти разрывы отсутствуют. Элементы массива за-
поминаются друг за другом построчно.
Примеры объявления массивов:
float Mas1 [5][5]; // квадратная матрица 5х5 из 25 элементов вещественного типа,
char Mas2 [10][3]; // двумерный массив из 10х3=30 элементов символьного типа;
double Mas3 [4][5][4]; // трехмерный массив из 4х5х4=100 вещественных элементов
При объявлении массива удобно инициализировать начальные значения его элементов, при
чем не обязательно всех. Примеры инициализации двумерных массивов:
1) int w[3][3] = { { 2, 3, 4 }, { 3, 4, 8 }, { 1, 0, 9 } };
2) float C[4][3]={1.1, 2, 3, 3.4, 0.5, 6.8, 9.7, 0.9};
3) float C[4][3]={{1.1, 2, 3}, {3.4, 0.5, 6.8},{ 9.7, 0.9}};
4) float C[4][3]={{ 1.1, 2}, {3, 3.4, 0.5},{ 6.8},{ 9.7, 0.9}};
В первом примере объявлен и инициализируется массив целых чисел w[3][3]. Элементам мас-
сива присваиваются значения из списка: w[0][0]=2, w[0][1]=3, w[0][2]=4, w[1][0]=3 и т.д. Списки, вы-
деленные в фигурные скобки, соответствуют строкам массива.
Записи второго и третьего примера эквивалентны и в них элементы последней строки не
инициализированы, т.е. не определены. В таких случаях в числовых массивах оставшиеся элемен-
ты инициализируются 0.
Пример 1. Составить схему алгоритма и разработать проект для ввода матрицы вещест-
венных чисел размерностью 3х5 и нахождения максимального элемента матрицы и его индексов.
На форме расположены компоненты StringGrid1, Edit1, Button1, Button2, Button3, Label1 и
Label2, а их новые свойства указаны в таблице.
“Программирование задач с циклами и массивами" 31

Свойства компонентов
Компо- Новые
Свойства
ненты значения
StringGrid1 ColCount 6
StringGrid1 RowCount 4
StringGrid1 Options.goEditing True
StringGrid1 Options.goTabs True
Button1 Caption Решение
Button2 Caption Очистка
Button3 Caption Выход
Form1 Caption Пример 1
Вид формы с результатами
1
Начало
Тексты программ: 2
void __fastcall TForm1::FormCreate(TObject *Sender) // Создание формы i  0,2
{ for (int i=1;i<=3;i++)StringGrid1->Cells[0][i]=IntToStr(i)+"-я строка";
3
for (int j=1;j<=5;j++)StringGrid1->Cells[j][0]=IntToStr(j)+"-й столбец"; j  0,4
} 4
//--------------------------------------------------------------------------- Ввод Ai,j
void __fastcall TForm1::Button1Click(TObject *Sender) // Решение
{ float A[3][5],max; int i, j, ind_i, ind_j;
for (i=0;i<3;i++) 5
max=A00,
for (j=0;j<5;j++)
ind_i=i, ind_j=j
if(StringGrid1->Cells[j+1][i+1] != "") // Проверка на заполненность ячейки
A[i][j]=StrToFloat(StringGrid1->Cells[j+1][i+1]); 6
i  0,2
else
{ ShowMessage("Заполните ["+IntToStr(i+1)+","+ IntToStr(j+1)+"] элемент"); 7
break; } j  0,4
max=A[0][0]; ind_i=0; ind_j=0; нет 8
for (i=0; i<3; i++) max<Aij
for (j=0; j<5; j++) да
if(max < A[i][j]) {max=A[i][j]; ind_i=i; ind_j=j;} 9
max=A00,
Edit1->Text=FormatFloat("0.00",max)+" "+IntToStr(ind_i+1)+"-я строка и "+
IntToStr(ind_j+1)+"-й столбец"; ind_i=i, ind_j=j
}
//--------------------------------------------------------------------------- 10
void __fastcall TForm1::Button2Click(TObject *Sender) // Очистка max,
{ int i,j; ind_i+1,
for (i=0; i<3; i++) ind_j+1
for (j=0; j<5; j++) StringGrid1->Cells[j+1][i+1]="";
Edit1->Clear(); } Конец
//--------------------------------------------------------------------------- Рисунок 4.2 –
void __fastcall TForm1::Button3Click(TObject *Sender) // Выход Блок-схема
{ Close(); }

Пример 2. Из элементов матрицы размерностью 4х7 вещественных чисел вычислить вектор


произведений ненулевых элементов четных (2, 4 и 6) столбцов матрицы.
Поскольку при формировании вектора его индексы не совпадают с индексами четных столб-
цов матрицы, по которым формируется вектор, то возникает необходимость в использовании до-
полнительной переменной, например k для индексов вектора.
На форме расположены компоненты StringGrid1, StringGrid2, BitBtn1, а их новые свойства
указаны в таблице. Компонент BitBtn представляет собой разновидность стандартной кнопки
Button, но с возможностью вывода на кнопку кроме надписи пиктографических изображений с
помощью свойств Kind или Glyph.
32 “Программирование задач с циклами и массивами"

1
Начало
Свойства компонентов 2
i  0,3
Компо- Новые
Свойства
ненты значения 3
j  0,6
StringGrid1 ColCount 7
4
StringGrid1 RowCount 4 Ввод Сi,j
StringGrid1 FixedCols 0
StringGrid1 FixedRows 0
StringGrid1 Options.goEditing True 5
k= 0
StringGrid1 Options.goTabs True
6
StringGrid1 Name SG1 j  0,6
StringGrid2 ColCount 3
нет 7четный стол-
StringGrid2 RowCount 1
бец?
StringGrid2 FixedCols 0
да
StringGrid2 FixedRows 0 8
pk = 1
StringGrid2 Name SG2 9
BitBtn1 Kind bkOK i  0,3
BitBtn1 Caption Вектор
нет 10
Form1 Caption Пример 2 Сij ≠ 0
11
pk= pk * Cij

void __fastcall 12
TForm1::BitBtn1Click(TObject *Sender) Вывод pk
{ int i,j; float C[4][7], p[3];
13
for (i=0; i<4; i++) k=k+1
for (j=0; j<7; j++)
C[i][j] = StrToFloat(SG1- 14
>Cells[j][i]); Конец
int k = 0; Блок-схема для
for(j=0; j<7; j++) кнопки «Вектор»
if((j+1)%2 == 0) // проверка на
Вид формы с результатами четный столбец
{ p[k] = 1;
for (i=0; i<4; i++)
if(C[i][j] != 0) // если элемент ≠ 0
p[k] *= C[i][j];
SG2->Cells[k][0]=FormatFloat("0.00",p[k]);
k++; }
}

Лабораторное задание
Составить схемы алгоритмов, разработать проект формы и программы алгоритмическим
языком C++ для выполнения индивидуального задания согласно варианту. В проекте предусмот-
реть ввод элементов матрицы с клавиатуры через компонент StringGrid (значения произвольные) и
вывода полученных результатов на форму.

Индивидуальные задания среднего уровня сложности


1 В матрице вещественных чисел из 5-ти строк и 4-х столбцов определить количество поло-
жительных, отрицательных и нулевых элементов.
2 В матрице целых чисел размерностью 45 определить номер строки, которая содержит
наибольший элемент.
“Программирование задач с циклами и массивами" 33
3 Определить минимальный элемент главной диагонали квадратной матрицы размерностью
55 и номер строки, в котором он находится.
4 Поменять местами элементы первой строки матрицы вещественных чисел размерностью
44 и элементы ёё неглавной диагонали.
5 В матрицы целых чисел размерностью 35 заменить отрицательные элементы нулями.
6 Определить максимальный и минимальный элементы матрицы вещественных чисел раз-
мерностью 66 и поменять их местами.
7 Определить наибольший элемент из числа отрицательных элементов четных столбцов мат-
рицы целых чисел размерностью 46.
8 Вычислить сумму элементов неглавной диагонали матрицы 55 целых чисел.
9 Для матрицы целых чисел размерностью 55 получить транспонированную матрицу.
10 Определить номер столбца матрицы вещественных чисел размерностью 36 с наимень-
шим элементом.
11 Определить минимальный элемент неглавной диагонали матрицы целых чисел размерно-
стью 55 и номер столбца, в котором он находится.
12 Вычислить вектор сумм элементов строк матрицы целых чисел размерностью 73.
13 Заменить в нечетных строках матрицы вещественных чисел размерностью 74 отрица-
тельные элементы нулями, а положительные элементы единицами.
14 Вычислить разницу сумм элементов главной и неглавной диагоналей матрицы вещест-
венных чисел размерностью 55.
15 В матрице вещественных чисел размерностью 75 вычислить сумму всех отрицательных
элементов четырех строк.
16 В матрице целых чисел размерностью 45 заменить все отрицательные элементы нулями.
17 Вычислить произведение минимального элемента матрицы целых чисел размерностью
45 на его среднее арифметическое.
18 В матрице целых чисел размерностью 64 вычислить среднее арифметическое положи-
тельных элементов.
19 В матрице целых чисел размерностью 54 заменить в нечетных строках положительные
элементы на 1, а в четных – отрицательные на -1.
20 В матрице вещественных чисел размерностью 63 вычислить произведение всех отрица-
тельных элементов четных строк.
21 В матрице целых чисел размерностью 35 определить количество элементов меньших,
чем среднее арифметическое.
22 В матрице вещественных чисел размерностью 53 заменить все элементы большие, чем
2.5 на -1.
23 Вычислить вектор модулей сумм элементов строк матрицы вещественных чисел размер-
ностью 45.
24 Определить в матрице целых чисел размерностью 74 наименьший элемент из числа по-
ложительных и наибольший из числа отрицательных и поменять их местами.
25 Вычислить вектор элементов главной диагонали матрицы вещественных чисел размерно-
стью 55.
26 Вычислить вектор сумм квадратов элементов столбцов матрицы вещественных чисел
размерностью 35.
27 В матрице целых чисел размерностью 55 поменять местами элементы главной и неглав-
ной диагоналей.
28 В матрице целых чисел размерностью 55 заменить все четные элементы на нули.
29 Вычислить разницу сумм элементов первой строки и последнего столбца матрицы веще-
ственных чисел размерностью 46.
30 Получить вектор сумм элементов главной и неглавной диагонали матрицы вещественных
чисел размерностью 66.
34 “Программирование задач с циклами и массивами"
Индивидуальные задания высокого уровня сложности
1 Получить вектор сумм элементов нечетных столбцов матрицы 37 целых чисел.
2 Получить вектор скалярных произведений строк матрицы вещественных чисел размерно-
стью 44 на ёё последний столбец.
3 Получить вектор произведений нечетных элементов четных строк матрицы целых чисел
размерностью 64.
4 Получить вектор скалярных произведений элементов первой строки матрицы целых чисел
размерностью 44 на столбцы этой матрицы.
5 Определить номер столбца матрицы вещественных чисел размерностью 45 с наименьшей
суммой элементов.
6 Получить вектор скалярных произведений строк матрицы целых чисел размерностью 55
на ёё неглавную диагональ.
7 Вычислить вектор произведений четных элементов нечетных столбцов матрицы целых чи-
сел размерностью 45.
8 Определить номер строки матрицы целых чисел размерностью 45 с наибольшей суммой
элементов.
9 Получить вектор сумм нечетных элементов четных строк матрицы целых чисел размерно-
стью 66.
10 Получить вектор скалярных произведений элементов столбцов матрицы вещественных
чисел размерностью 33 на ёё главную диагональ.
11 Сформировать вектор из наименьших элементов столбцов матрицы вещественных чисел
размерностью 46.
12 В матрице вещественных чисел размерностью 73 определить номер строки с наимень-
шей суммой модулей элементов.
13 Заменить элементы главной диагонали матрицы целых чисел размерностью 55 суммами
элементов столбцов.
14 Получить вектор среднеарифметических положительных элементов четных строк матри-
цы целых чисел размерностью 78.
15 Сформировать вектор из наибольших элементов строк матрицы вещественных чисел
размерностью 76.
16 Заменить элементы неглавной диагонали матрицы целых чисел размерностью 44 сума-
ми элементов ёё строк.
17 Получить вектор произведений элементов столбцов матрицы целых чисел размерностью
36.
18 Получить вектор из строки матрицы, содержащей наибольший элемент матрицы целых
чисел размерностью 56.
19 Заменить элементы главной диагонали матрицы целых чисел размерностью 66 суммой
максимального и минимального элементов матрицы.
20 Заменить элементы неглавной диагонали матрицы вещественных чисел размерностью
44 значением минимального элемента матрицы.
21 Заменить нулевые элементы матрицы вещественных чисел размерностью 55 ёё макси-
мальным элементом.
22 В матрице вещественных чисел размерностью 73 поменять местами первый и послед-
ний отрицательные элементы.
23 Получить вектор сумм положительных элементов строк матрицы целых чисел размерно-
стью 65. Упорядочить полученный вектор по возрастанию.
24 Среди строк матрицы целых чисел размерностью 54 найти ту, для которой сумма нечет-
ных элементов буде минимальной и построить из этой строки вектор.
25 Если в матрице вещественных чисел 64 сумма положительных чисел больше модуля
суммы отрицательных, то заменить угловые элементы большей из сумм. Иначе видать сообщение.
“Программирование задач с циклами и массивами" 35
26 Получить вектор скалярных произведений столбцов матрицы вещественных чисел раз-
мерностью 44 на ёё неглавную диагональ.
27 Сформировать вектор из наибольших элементов строк матрицы вещественных чисел
размерностью 56.
28 Сформировать вектор из среднеарифметических элементов строк матрицы вещественных
чисел размерностью 54.
29 Получить вектор среднеарифметических первого и последнего элементов четных строк
матрицы целых чисел размерностью 78.
30 Получить вектор квадратов элементов минимальных элементов нечетных столбцов мат-
рицы вещественных чисел размерностью 65.

Индивидуальные задания повышенного уровня сложности


1 Из заданной матрицы вещественных чисел размерностью 57 получить новую матрицу, в
которой каждый элемент вычисляется как полусумма среднеарифметических соответствующих
строки и столбца.
2 В матрице вещественных чисел размерностью 77 вычислить определитель.
3 Получить вектор максимальных элементов строк матрицы вещественных чисел размерно-
стью 55.
4 Получить произведение матрицы целых чисел размерностью 55 на ёё транспонирован-
ную матрицу.
5 В матрице вещественных чисел размерностью 73 определить номер строки, длина кото-
рой (как вектор) максимальна.
6 Сформировать вектор из строки матрицы вещественных чисел размерностью 83, наиме-
нее удаленной от второй строки, если расстояние между строками вычисляется по формуле
n
d i   aij  a2 j .
j 1

7 Упорядочить по возрастанию (слева направо) элементы всех строк матрицы веществен-


ных чисел размерностью 44, а затем по возрастанию (сверху вниз) элементы всех столбцов.
8 Наименьшую по длине строку матрицы вещественных чисел размерностью 54 заменить
на наибольшую по длине.
9 Сформировать вектор из строки матрицы вещественных чисел размерностью 55, наибо-
лее удаленной от первой строки, причем в качестве расстояния от первой строки матрицы до і-ой
n
взять величину d i   aij  a1 j , i  1.
j 1

10 Сформировать вектор из строки матрицы вещественных чисел размерностью 64 с наи-


n
меньшей суммой a
j 1
2
ij .

11 Сформировать вектор из столбца матрицы вещественных чисел размерностью 37 с наи-


n
большим весом, где вес столбца матрицы вычисляется так W j   aij .
i 1

12 Каждый отрицательный элемент матрицы вещественных чисел размерностью 48 заме-


нить суммой положительных элементов той строки, в которой расположен этот элемент.
13 Сформировать вектор из столбца матрицы вещественных чисел размерностью 86 с наи-
n
большей суммой a
j 1
ij  aij .
36 “Программирование задач с циклами и массивами"
14 Сформировать вектор из столбца матрицы вещественных чисел размерностью 68, наи-
менее удаленного от первого, причем за расстояние между столбцом j и первым считать величину
n
d j   aij  ai1 , j  1.
i 1

15 Сформировать вектор из строки матрицы вещественных чисел размерностью 53 с наи-


n
меньшим весом, а вес строки матрицы считать равным Wi   aij .
j 1

16 Вывести элемент матрицы с наибольшим расстоянием до диагонали. Расстояние вычис-


n m
ляется по формуле d ij    aij  a jj  aii .
i 1 j 1

17 В матрице целых чисел размерностью 66 определить минимальный элемент в секторе


над главной диагональю и минимальный элемент в секторе под главной диагональю. Наибольшим
из этих значений заменить элементы главной диагонали.
18 Из матрицы целых чисел размерностью 45 сформировать вектор положительных эле-
ментов.
19 Матрица целых чисел размерностью 55 состоит из чисел от 0 до 9. Если количество по-
вторений элемента матрицы совпадает с самим элементом, то заменить его на нуль.
20 Сформировать вектор из строки матрицы целых чисел размерностью 75, наиболее уда-
ленной от третей строки, причем в качестве расстояния между строками взять величину
n
d i   aij  a3 j .
j 1

21 Сформировать вектор из матрицы вещественных чисел размерностью 36 с наименьшей


n
величиною W j  a
i 1
2
ij .

22 Матрица целых чисел размерностью 35 состоит из чисел от 0 до 9. Определить процент-


ное содержание каждого из этих чисел в матрице.
23 Матрица целых чисел размерностью 64 состоит из чисел от 0 до 9. Сформировать век-
тор длиной 10, элементы которого будут числа повторов этих констант в матрице.
24 Сформировать вектор из наиболее удаленного от (n-1)-го столбца матрицы вещественных
n
чисел размерностью 65, причем за расстояние считать величину d j   aij  ai ,n1 .
i 1

25 В матрице целых чисел размерностью 67 определить строку с минимальной суммой и


поменять местами эту строку с первой.
26 Ввести матрицу вещественных чисел 55 и вектор из пяти вещественных чисел. Заменить
все строки массива, в которых есть два или больше отрицательных чисел на элементы вектора.
27 Вывести координаты элемента матрицы вещественных чисел размерностью 57 с наи-
n m a
меньшим весом, а вес рассчитывать по формуле Wij   ij .
i 1 j 1 i  j

28 Если в матрице вещественных чисел 45 сумма положительных чисел больше модуля
суммы отрицательных, то заменить угловые элементы средним арифметическим элементов мат-
рицы. Иначе выдать сообщение.
29 Если в матрице целых чисел 56 содержится четное количество отрицательных чисел, то
заменить любую половину из этих чисел на нуль. Иначе заменить все отрицательные элементы на
значение их количества.
30 Ввести две матрицы вещественных чисел 45. Если максимальный элемент первой мат-
рицы меньше чем максимальный элемент второй матрицы, то поменять местами строки матриц,
содержащие максимальные элементы. Иначе выдать сообщение.
“Программирование задач с циклами и массивами" 37

Протокол лабораторной работы №2.5


38 “Программирование задач с циклами и массивами"
“Программирование задач с циклами и массивами" 39
40 “Программирование задач с циклами и массивами"

Лабораторная работа № 2.6


Указатели и динамическое управление памятью
Цель работы: Изучить средства организации работы с указателями и динамическим
распределении памяти алгоритмическим языком C++.
Контрольные вопросы
1 Какое предназначение динамического распределения памяти?
2 Что называют указателем в программировании?
3 Что называют операциями адресации и разадресации?
4 Перечислите известные Вам операции над указателями.
5 Какое значение переменной Q будет после выполнения блока операторов:
int a[5] = {9, 33, -23, 8, 1}, *ptr, Q;
ptr=a;
Q=*(a+3);
6 Назовите известные Вам функции для работы с динамическим распределением памяти.
Теоретические сведения
Оперативная память ПК представляет собой совокупность ячеек для хранения информации,
каждая из которых имеет собственный номер. Эти номера называются адресами, они позволяют
обращаться к любому байту памяти. Существует два способа закрепления оперативной памяти за
величинами, которые будут использоваться в программах. Обычно применяют так называемый
статический способ. При использовании этого способа память для каждой величины остается за-
нятой ею в течение всего времени работы программы. При таком способе при объявлении массива
надо учитывать максимально возможное количество его элементов. А это приводит к неэффектив-
ному использованию памяти.
При динамическом способе закрепления оперативной памяти сама программа может выде-
лять и освобождать необходимую память для данных, т.е. управлять размещением используемых в
ней данных в оперативной памяти. При этом оперативная память используется более эффективно.
Такая возможность связана с наличием в C++ особенного типа данных – указателей.
Область оперативной памяти, в которой можно выделять отдельные участки для размещения
данных, называется динамической областью памяти, или динамической памятью.
Указатель – переменная, которая указывает на другую переменную (содержит местоположе-
ние другой переменной в форме адреса). В этом смысле имя переменной «отсылает» к ёё значе-
нию непосредственно, а указатель – косвенно. Ссылка на значение указателя называется косвенной
адресацией.
Формат объявления указателя:
тип_данных *имя_указателя
* – означает, что следующая за ней переменная является указателем. Переменная, объявлен-
ная как указатель, хранит адрес памяти. Примеры:
char *mes; // объявляется переменная-указатель mes на величину типа char
int (*p2)[10]; // объявлена указатель p2 на массив из 10 элементов типа int
В С++ Builder указатели используются очень широко. В частности, все компоненты, формы и
т.д. объявляются именно как указатели на соответствующий объект.
Указатели должны инициироваться либо при своем объявлении, либо с помощью оператора
присваивания. Указатель может получить в качестве начального значения 0, NULL или адрес.
Указатель с начальным значением 0 или NULL ни на что не указывает.
Операция адресации "&" (амперсанд) присваивает указателю адрес некоторой переменной.
Операцию "&" также часто используют для передачи в функции параметров по ссылке.
Операция разадресации (или разыменования, или косвенной адресации) (*) применяется для
обращения к переменной по указателю, т.е. для того, чтобы получить значение, на которое адресу-
“Программирование задач с циклами и массивами" 41
ет указатель, например:
double y, *py=&y; // объявленному указателю py присваивается адрес y
*py = 7.5; // эквивалентно y = 7.5
С указателями может выполняться ограниченное количество арифметических операций. Ука-
затель можно увеличивать (++), уменьшать (--), складывать с указателем целые числа (+ или +=),
вычитать из него целые числа (- или -=) или вычитать один указатель из другого.
Арифметические операции, применяемые к указателю, имеют осмысленный результат, толь-
ко когда указатель адресует массив памяти, а целая величина представляет смещение адреса в
пределах этого массива. Преобразование целой величины к адресному смещению предполагает,
что в пределах смещения плотно расположены элементы одинакового размера. Это предположе-
ние справедливо для элементов массива. Массив определяется как набор величин одного и того же
типа; его элементы расположены в смежных ячейках памяти. Сложение и вычитание адресов,
ссылающихся на любые величины, кроме элементов массива, дает непредсказуемый результат,
поскольку в таком случае не гарантируется плотное заполнение памяти.
Пример 1: int i=4, j; float x[15]; float * px;
px = &x[4]+i; // px =адресу x[8] элемента массива
j = &x[i] - &x[i-2]; // j = адрес x[4] - адрес x[2] = 2
Пример 2: int *ptr, a[10];
ptr=&a[5];
ptr++; /* равно адресу элемента a[6] */
ptr--; /* равно адресу элемента a[5] */
Значения двух указателей на одинаковые типы можно сравнивать в операциях ==, !=, <, <=,
>, >= при этом значения указателей рассматриваются просто как целые числа, а результат сравне-
ния равен 0 (ложь) или 1 (истина). Сравнение указателей на равенство истинно, если они ссылают-
ся на один и тот же адрес в памяти.
Пример: int *ptr1, *ptr2, a[10];
ptr1=a+5; ptr2=a+7;
if (prt1>ptr2) a[3]=4;
В этом примере значение ptr1 меньше значения ptr2 и поэтому оператор a[3]=4 не будет выполнен.
Передача параметров в функции может происходить при помощи указателей. При вызове
функции в нее в качестве аргумента должна передаваться не сама переменная, а адрес, получае-
мый при помощи операции адресации &. Например:
void sum(int *a, int *b); // Заголовок функции
{ *a +=*b; } // Изменение значения параметра
............
int x = 5, y = 10;
sum(&x, &y); // Вызов функции

Указатели на одномерные массивы


Массивы и указатели в С++ тесно связаны и могут использоваться почти эквивалентно. На-
пример, когда объявляется массив в виде int mass[25], то этим определяется не только выделение
памяти для двадцати пяти элементов массива, но и для указателя с именем mass, значение которо-
го равно адресу первого по счету (нулевого) элемента массива, т.е. сам массив остается безымян-
ным, а доступ к элементам массива осуществляется через указатель с именем mass. Поскольку
имя массива является указателем допустимо, например, такое присваивание:
int mass[25], *ptr;
ptr=mass;
Здесь указатель ptr устанавливается на адрес первого элемента массива, причем присваива-
ние ptr=mass можно записать в эквивалентной форме ptr=&mass[0]. Для того, чтобы получить зна-
чение 16 элемента массива mass, можно записать mass[16] или *(mass+16). Результат один и тот
же. При реализации на компьютере первый способ приводится ко второму, т.е. индексное выра-
жение преобразуется к адресному. Т.о. операции над указателями обрабатываются быстрее, по-
этому, если элементы массива обрабатываются по порядку, то выгоднее использовать второй спо-
соб. Если же выбор элементов случайный, то во избежание ошибок предпочтительнее первый спо-
42 “Программирование задач с циклами и массивами"
соб. Кроме того, первый способ более наглядный, что способствует лучшей читаемости программ.
Для доступа к начальному элементу массива (т.е. к элементу с нулевым индексом) можно ис-
пользовать просто значение указателя mass или ptr. Любое из шести присваиваний
* mass = 2; *ptr = 2;
mass [0] = 2; ptr[0] = 2;
*( mass +0) = 2; *(ptr+0) = 2;
присваивает начальному элементу массива значение 2, но быстрее всего выполнятся присваивания
*mass=2 и *ptr=2, так как в них не требуется выполнять операции сложения.
Пример 1. В одномерном массиве из 8 целых чисел определить количество положительных
элементов.
int fun(int a[8])
{ int c=0,*pa;
pa=a;
for(int i=0; i<8; i++)
if (*(pa+i)>0) c++;
return c; }
void __fastcall TForm1::Button1Click(TObject *Sender)
{ int i,a[8];
for(i=0; i<8; i++)
*(a+i)=StrToInt(Memo1->Lines->Strings[i]); // обращение *(a+i) аналогично a[i]
int k=fun(a);
Edit1->Text=IntToStr(k);
}
Пример 2. Ввести матрицу из 3 строк и 3 столбцов. При помощи подпрограммы транспони-
ровать матрицу и вывести ее на экран. В задаче использовать передачу параметров при помощи
указателей.
const int n=3;
void transp(int *u) // функция транспонирования матрицы
{ int i,j;
for(i=0;i<n;i++)
for(j=i+1;j<n;j++)
{ int p=*(u+n*i+j);
*(u+n*i+j)=*(u+n*j+i);
*(u+n*j+i)=p; }
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{ int i,j,a[n][n];
for(i=0;i<n;i++)
for(j=0;j<n;j++) a[i][j]=StrToInt(StringGrid1->Cells[j][i]);
transp(&a[0][0]);
for(i=0;i<n;i++)
for(j=0;j<n;j++) StringGrid2->Cells[j][i]=IntToStr(a[i][j]);
}
Работа с динамической памятью. Динамическое размещение массивов
Некоторые функции для выделения и освобождения памяти:
1) malloc(s);
Выделяет блок оперативной памяти длиной s байт и возвращает указатель на этот блок памя-
ти. При неудачном завершении возвращается значение NULL.
2) calloc(n, m);
Выделяет блок оперативной памяти для размещения n элементов по m байт каждый и воз-
вращает указатель на начало этой области памяти. При неудачном завершении возвращается зна-
чение NULL.
3) free(p);
Освобождает ранее выделенный блок оперативной памяти, на который ссылается указатель
p. Эта область становится свободной для дальнейшего использования в других целях, а указатель
“Программирование задач с циклами и массивами" 43
p – не определенным (NULL), т.е. ни на что не ссылается.
4) realloc(bl, ns);
Изменить размер ранее выделенной памяти с адресом начала bl на ns байт.
При динамическом распределении памяти для массивов следует описать соответствующий
указатель и присваивать ему значение при помощи функций malloc или calloc. Два аналогичных
примера выделения памяти под одномерный массив a[10] из элементов типа:
float *a; float *a;
a=(float*) malloc(10); a=(float*)(calloc(10,sizeof(float));
Примеры создания двумерного массива a[n][m]:
int *p, n=3, m=5; int *p, n=3, m=5;
p=(int*)malloc(n*m*sizeof(int)); p=(int*)calloc(n*m, sizeof(int));
Аналогичным образом можно распределить память и для трехмерных массивов.
Для иллюстрирования работы функции realloc приведем пример изменения размера ранее
выделенной памяти под одномерный массив из 10 вещественных элементов до 20 элементов:
a = (float*) realloc(a, 20);
Следует только помнить, что ненужную для дальнейшего выполнения программы память
следует освобождать при помощи функции free, например: free(а);
Использование указателей совместно с вышеназванными функциями дает возможность
управлять распределением динамической памяти.
Пример 1: Разработать программу для ввода элементов вектора (до 15 вещественных чисел) и
определения:
– произведения ненулевых элементов вектора;
– количества отрицательных элементов вектора;
– элементов вектора, являющихся результатом перестановки местами значений первого и
минимального элементов в исходном векторе.
Вариант решения 1: Функция может явно возвращать только один результат, в данном слу-
чае результат – количество отрицательных элементов. Остальные результаты (их 3) передаются по
ссылке. Значение элементов преобразованного массива в качестве передаваемого результата ука-
зывать не надо, поскольку массив передается по ссылке, то любые изменения в функции сразу
отображаются и головной вызывающей программе.

int fun (double mass[], int n, double &p, double


&min, int &ind)
{ int i, k=0;
ind=0; p=1; min=mass[0];
for (i=0; i<n; i++)
{ if (mass[i]<0) k++;
if (mass[i]!=0) p *= mass[i];
if (mass[i]<min) { min=mass[i]; ind=i; }
} mass[ind]=mass[0];
mass[0]=min;
return k; }
void __fastcall TForm1::Button1Click(TObject *Sender)
{ int i, n, otr, ind;
double A[15], p, min;
n = StrToInt(Memo1->Lines->Count);
for(i=0; i<n; i++) A[i]=StrToFloat(Memo1->Lines->Strings[i]);
otr = fun(A,n,p,min,ind);
Edit1->Text = FloatToStr(p);
Edit2->Text = IntToStr(otr);
Edit3->Text = FormatFloat("0.000",min)+" индекс "+ IntToStr(ind);
Memo2->Clear();
for(i=0; i<n; i++) Memo2->Lines->Add(FormatFloat("0.000",A[i]));
44 “Программирование задач с циклами и массивами"
}
Вариант решения 2: Функция не возвращает никаких значений – тип void опущен. Все ре-
зультаты (их 4) передаются по ссылке.
fun (double mass[], int n, double &p, int &k, double &min, int &ind)
{ int i; k=0; ind=0; p=1; min = mass[0];
for (i=0; i<n; i++)
{ if (mass[i]<0) k++;
if (mass[i]!=0) p *= mass[i];
if (mass[i]<min)
{ min=mass[i]; ind=i; }
}
mass[ind]=mass[0];
mass[0]=min;
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{ int i, n, otr, ind;
double A[15], p, min;
n = StrToInt(Memo1->Lines->Count);
for(i=0; i<n; i++)
A[i] = StrToFloat(Memo1->Lines->Strings[i]);
fun(A,n,p,otr,min,ind);
Edit1->Text = FloatToStr(p);
Edit2->Text = IntToStr(otr);
Edit3->Text = FormatFloat("0.000",min)+" индекс "+ IntToStr(ind);
Memo2->Clear();
for(i=0; i<n; i++)
Memo2->Lines->Add(FormatFloat("0.000",A[i]));
}

Вариант решения 3: Указатели. В качестве массива – параметра функции указывается адрес


начального (нулевого) элемента массива. Доступ к i-му элементу массива можно организовывать с
помощью выражения mass[i] или как смещение от начала массива на i элементов *(mass+i).

fun (double *mass, int n, double &p, int &k, double &min, int &ind)
{ int i;
k=0; ind=0; p=1; min = *mass; // или min=mass[0]
for (i=0; i<n; i++)
{ if (*(mass+i)<0) k++; // *(mass+i) эквивалентно mass[i], но не
if (*(mass+i)!=0) p*=*(mass+i); // требует последующего преобразования
if (*(mass+i)<min) // компилятором, а, значит, работает быстрее
{ min=*(mass+i); ind=i; } }
*(mass+ind)=*mass; // mass[0] эквивалентно *mass
*mass=min;
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{ int i, n, otr, ind;
double A[15], p, min;
n = StrToInt(Memo1->Lines->Count);
for(i=0; i<n; i++) A[i] = StrToFloat(Memo1->Lines->Strings[i]);
fun(&A[0],n,p,otr,min,ind); // вызов функции
Edit1->Text = FloatToStr(p); Edit2->Text = IntToStr(otr);
Edit3->Text = FormatFloat("0.000",min)+" индекс "+ IntToStr(ind);
Memo2->Clear();
for(i=0; i<n; i++) Memo2->Lines->Add(FormatFloat("0.000",A[i]));
}
“Программирование задач с циклами и массивами" 45
Вариант решения 4: Динамическое распределение памяти
fun (double *mass, int n, double &p, int &k, double &min, int &ind)
{ int i; k=0; ind=0; p=1; min = *mass;
for (i=0; i<n; i++)
{ if (*(mass+i)<0) k++;
if (*(mass+i)!=0) p* = *(mass+i);
if (*(mass+i)<min) { min=*(mass+i); ind=i; }
}
*(mass+ind) = *mass;
*mass = min;
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{ int i, n, otr, ind;
double *A, p, min;
n = StrToInt(Memo1->Lines->Count);
A = (double*)malloc(n*sizeof(double)); // выделить память для вектор
for(i=0; i<n; i++) A[i] = StrToFloat(Memo1->Lines->Strings[i]);
fun(A,n,p,otr,min,ind);
Edit1->Text = FloatToStr(p);
Edit2->Text = IntToStr(otr);
Edit3->Text = FormatFloat("0.000",min)+" индекс "+ IntToStr(ind);
Memo2->Clear();
for(i=0; i<n; i++)
Memo2->Lines->Add(FormatFloat("0.000",*(A+i))); // вывод A[i]
free(A); // освободить память
}

Лабораторное задание
Составить схемы алгоритмов, разработать проект формы и программы алгоритмическим
языком C++ для выполнения индивидуального задания согласно варианту. В проекте предусмот-
реть ввод исходных данных с клавиатуры и вывод полученных результатов на форму в компонен-
ты в головной программе, а обработку данных, т.е. все вычисления, организовать в функциях с ис-
пользованием указателей и динамическим распределением памяти под массивы.
Индивидуальные задания соответствующего уровня сложности по указанию преподавателя
выбирается из таблиц предыдущих лабораторных работ № 5 и № 6. Т.е. задания состоит в пере-
делке уже существующих проектов обработки одномерных и двумерных массивов таким образом,
чтобы в головной программе остались операторы ввода/вывода данных и динамического распре-
деления памяти под массивы, а все вычисления по выполнению индивидуального задания органи-
зовать в функциях с использованием указателей.
46 “Программирование задач с циклами и массивами"
Протокол лабораторной работы №2.6
“Программирование задач с циклами и массивами" 47
48 “Программирование задач с циклами и массивами"
“Программирование задач с циклами и массивами" 49

Вам также может понравиться