Открыть Электронные книги
Категории
Открыть Аудиокниги
Категории
Открыть Журналы
Категории
Открыть Документы
Категории
Попова
ИНФОРМАТИКА
МОДУЛЬ № 2
“Программирование задач с циклами и массивами”
Рабочая тетрадь
для подготовки и выполнения лабораторных работ
Одесса – 2006
2 “Программирование задач с циклами и массивами”
Теоретические сведения
Оператор цикла с параметром 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
Sin2kx
x Cosk ; 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 k2
; 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 1k 12
x 12k ; x 0,25 14
k 2Coskx
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 1x 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 13
k
7
2 x 2 k 1 11
x 2k 1 9
x 2k 1
28
k 1 32 k 1
; x 0,77 29
k 1 4 k 1
2
; x 0,96 30
k 2 2k 12
k
; x 2,75
6 “Программирование задач с циклами и массивами”
Таблица 1.2 – Индивидуальные задания высокого у ровня сложности
n
k 1 k 7 m 2 9 P
k
j 6 j 12 3
i5 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
i5 n
1k 1 k 7
4 Z
j 4 j 3
i 11
i j
5 A
j3
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
1i i 32
7 S i7 8 9 W
k 3 k 5 i 1 j 2 j 3 j 1! i 1 i!
k
j 2 j k 5
i5 n
1k k 32 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
i5
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
12n 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 m1 m 3
18 Z
n 3!
n 1 n 2
k
1i 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 i5 k
i 1 i
n 0.8 2 k k
1i 2k n 3 8
22 L 23 Y 2
24 W 2
j 1 j3 i k i 1 i 1 3 i n i ni i 1 i 3 ni n 2
Q
n
n 1k 1 k 3 k
2 j 1 k 5 i5
27 Y
k
k i i i 2 !
25 26 G
4j3
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
i 3 при i кратном 3
ai
i i 3 при i некратном 3
N i
j!
3. Ввести натуральное число N. Вычислить s .
i 1 j 1 i!
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
Контрольные вопросы
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);
}
члены ряда, значения которых по модулю больше заданной точности . Определить количество
слагаемых. Значения х (-2<x<2) и 10 4 вводить с клавиатуры.
Множитель (-1)k при нечетных k=1,3,5,… равняется (-1), а при четных k=2,4,… равняется 1.
Таким образом представленный ряд является знакочередующимся, где все нечетные слагаемые
будут отрицательными, а все четные – со знаком «+». Для наглядности и контроля правильности в
решении отдельно приведем все слагаемые.
Для того, чтобы сделать алгоритм программы более оптимальным можно его усовершенст-
вовать, но для этого надо вычислить рекуррентный множитель. Это позволит в данной программе
избавится от вложенного цикла для вычисления факториала и оператора проверки на нечетность k.
Остановимся более подробно на выведении рекуррентной формулы.
u k 1
1k 1 x 2( k 1) =
1k 1 x 2( k 1) .
2( k 1)(2(k 1) 1)! 2( k 1)(2k 3)!
“Программирование задач с циклами и массивами” 13
R
uk
=
1k x 2 k ∙ 2(k 1)(2k 3)! = (1) k x 2 k (2k 2) (2k 3)! =
u k 1 2k (2k 1)! 1k 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)k1 xk1 ( 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 k1 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)! k1 (3k 2)!
Контрольные вопросы
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 )!
, суммируя члены ряда, значения ко-
S = 0, k=0
Начало
Лабораторное задание
Составить схемы алгоритмов, разработать проект формы и программы алгоритмическим
языком C++ для выполнения индивидуального задания согласно индивидуальному варианту. В
проекте предусмотреть ввод исходных данных с клавиатуры и вывод полученных результатов на
форму в компоненты в головной программе, а обработку данных, т.е. все вычисления, организо-
вать в функциях.
Индивидуальные задания согласно уровню сложности по указанию преподавателя выбира-
ются из таблиц предыдущих лабораторных работ № 3 и № 4. То есть, задание заключается в рабо-
те с уже существующими программными проектами таким образом, чтобы в головной программе
остались операторы ввода/вывода данных, а все вычисления по выполнению индивидуального за-
дания организовывались в функциях (см. примеры 1 и 2).
Контрольные вопросы
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
Теоретические сведения
Многомерный массив объявляется в программе следующим образом:
тип имя [ размер 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(); }
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 (значения произвольные) и
вывода полученных результатов на форму.
28 Если в матрице вещественных чисел 45 сумма положительных чисел больше модуля
суммы отрицательных, то заменить угловые элементы средним арифметическим элементов мат-
рицы. Иначе выдать сообщение.
29 Если в матрице целых чисел 56 содержится четное количество отрицательных чисел, то
заменить любую половину из этих чисел на нуль. Иначе заменить все отрицательные элементы на
значение их количества.
30 Ввести две матрицы вещественных чисел 45. Если максимальный элемент первой мат-
рицы меньше чем максимальный элемент второй матрицы, то поменять местами строки матриц,
содержащие максимальные элементы. Иначе выдать сообщение.
“Программирование задач с циклами и массивами" 37
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