Міністерство транспорту та зв'язку...

40
Министерство транспорта и связи Украины Государственный департамент по вопросам связи и информатизации Одесская национальная академия связи им. А. С. Попова Кафедра информационных технологий ИНФОРМАТИКА Модуль 2 Программирование задач с циклами и массивами Часть 2 Методические указания для лабораторных и практических работ УТВЕРЖДЕНО методическим советом факультета информационных систем Протокол № 10 от 5.04.2007 г. Одесса – 2007

Upload: others

Post on 28-Jul-2020

4 views

Category:

Documents


0 download

TRANSCRIPT

Министерство транспорта и связи Украины

Государственный департамент по вопросам связи и информатизации

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

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

ИНФОРМАТИКА

Модуль 2

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

Часть 2

Методические указания

для лабораторных и практических работ

УТВЕРЖДЕНО

методическим советом факультета

информационных систем

Протокол № 10 от 5.04.2007 г.

Одесса – 2007

2

УДК 004.43 План УМИ 2007 г.

Составитель Е.Г. Трофименко

Данное методическое пособие содержит краткие теоретические сведения и примеры состав-

ления программных проектов средствами С++ Builder для решения задач с циклами и массивами.

Эта (вторая) часть пособия будет полезной для студентов при подготовке к лабораторным и прак-

тическим занятиям по дисциплине «Информатика» в модуле 2 и содержит контрольные вопросы и

индивидуальные задания разных уровней сложности для выполнения на компьютере.

Методическое пособие предназначено для приобретения навыков программирования студен-

тами разных специальностей академии, которые изучают дисциплину «Информатика» с целью

дальнейшего использования этих навыков в своей повседневной и будущей профессиональной де-

ятельности; также оно будет полезным для пользователей персональных компьютеров, желающим

научиться программировать в вреде С++ Builder.

ОДОБРЕНО

на заседании кафедры

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

рекомендовано к печати

Протокол № 9 от 11.06.2007 г.

3

Введение

С++ Builder – популярная среда разработки приложений для операционной системы

Windows. Среда объединяет средства языка программирования С++ и компонентно-

ориентированный подход к разработке программ. Сочетание простоты освоения визуальной среды

разработки и поддержка широчайшего спектра технологий делают С++ Builder универсальным

инструментом разработки приложений любого уровня сложности.

В практике программирования важную роль играют циклы, которые обеспечивают возмож-

ность многократного выполнения группы одних и тех же простых или составных операторов.

Циклические вычислительные процессы являются наиболее распространенными и незаменимыми

при обработке массивов.

В данном методическом пособии представлены краткие теоретические сведения, примеры

составления программных проектов средствами С++ Builder для решения задач с циклами и мас-

сивами, контрольные вопросы и варианты индивидуальных заданий. Эта (вторая) часть пособия

будет полезной для студентов при подготовке к лабораторным и практическим занятиям по дис-

циплине «Информатика» в модуле 2.

Каждая из предложенных к выполнению лабораторных работ имеет задания трех разных

уровней сложности. Студент сам или по указанию преподавателя выбирает задания того или иного

уровня сложности согласно порядковому номеру студента в списке группы. В дальнейшем при

оценивании знаний преподаватель может учитывать уровень сложности выполненной лаборатор-

ной работы, оптимальность алгоритма составленной программы, своевременность подготовки и

выполнения работы.

Перед выполнением лабораторного задания студенту необходимо:

уточнить у преподавателя индивидуальное задание;

выучить соответствующие разделы теоретического курса согласно с лекционными запи-

сями и учебной литературой;

составить схемы алгоритма решения задачи;

изобразить форму проекта и составить таблицу значений свойств ее компонентов;

написать тексты программ в С++ Builder;

подготовить протокол выполнения лабораторной работы и показать его преподавателю

для проверки.

К выполнению лабораторной работы допускается студент, имеющий подготовленный само-

стоятельно заполненный протокол лабораторной работы.

Содержание протокола лабораторной работы:

название темы и цель лабораторной работы;

короткое изложение основных теоретических положений;

ответы на контрольные вопросы;

схемы алгоритмов для решения индивидуального задания;

форма проекта и таблица значений свойств ее компонентов;

тексты программ в С++ Builder;

результаты вычислений на компьютере.

Правильность работы программы и полученных результатов проверяются и оцениваются

преподавателем.

4

Структура модуля 2

Дисциплина “Информатика” изучается в I – II семестрах и предназначена для обучения сту-

дентов работе на персональном компьютере с целью его использования в будущей профессио-

нальной деятельности.

Программа курса состоит из четырех модулей:

модуль 1 – Основные сведения о персональном компьютере и организации вычислительных

процессов;

модуль 2 – Программирование задач с циклами и массивами;

модуль 3 – Программирование задач со структурированными типами данных;

модуль 4 – Основы объектно-ориентированного программирования.

Целью изучаемого модуля «Программирование задач с циклами и массивами» – является

формирование у студентов таких знаний и умений:

Знания по темам:

циклические вычислительные процессы;

операторы цикла с параметром, предусловием и постусловием;

массивы. Векторы и матрицы.

Умения:

Разрабатывать и выполнять на компьютере алгоритмы и программы для решения задач:

вычисление конечных и бесконечных сумм;

вычисление произведений;

вычисление таблиц значений функции по заданной формуле;

вычисление с вложенными циклами;

вычисление элементов вектора или матрицы по формуле;

вычисление сумм и произведений элементов вектора или матрицы;

вычисление количества элементов вектора или матрицы по условию;

вычисление минимальных или максимальных значений элементов вектора или матрицы;

сортировка элементов массивов.

В соответствии с учебным планом структура модуля 2 имеет вид:

Вид занятий Количество часов

Лекции 8

Практические занятия 16

Лабораторные работы 16

Всего аудиторного времени: 40

Индивидуальная и самостоятельная работа студентов 27

Всего часов: 67

5

7,1k

S = 0

Начало

Конец

Вывод S

S = S + k

xk

k

2

1

Ввод х

1 Организация циклических вычислений

с помощью оператора цикла FOR

Оператор цикла с параметром for обычно используется, если заранее известно число повто-

рений. Синтаксис оператора следующий:

for (выражение1; выражение2; выражение3) оператор;

Сначала выражение1 задает начальное значение переменных, управляющих циклом, затем

проверяется условие в выражении2, которое является условием продолжения цикла. Если условие

истинно (имеет ненулевое значение), то выполняется оператор (или группа операторов в опера-

торных скобках {}), после чего выражение3 изменяет переменные, управляющие циклом и, в слу-

чае истинности условия, выполнение цикла продолжается. Если выражение2 равно нулю (ложь),

то управление передается на оператор, следующий за оператором for.

Существенно то, что проверка условия всегда выполняется в начале цикла. Это значит, что

тело цикла может ни разу не выполниться, если условие выполнения сразу будет ложным.

Простейший пример иллюстрирует использование оператора for для вычисления конечной

суммы

10

1i

iS .

int s = 0; for (int i = 1; i <= 10; i++) s += i;

Возможно наличие пустого оператора (отсутствие оператора) в теле цик-

ла. Так, сумму из предыдущего примера можно вычислить иначе:

for (int s = 0 , i = 1; i <= 10; s += i++);

В этом примере выражение1 включает в себя два оператора, разделенных

запятой и задающих начальные значения переменным s и i.

Во втором варианте решения отсутствует оператор, а вначале задается значение двух пере-

менных. В операторе возможны конструкции, когда отсутствует то или иное выражение: выраже-

ние1 может отсутствовать, если начальное значение задать до этого; выражение2 – если предпола-

гается, что условие всегда истинно, т. е. надо обязательно выполнять тело цикла, пока не встре-

тится break; а выражение3 – если приращение параметра осуществлять в теле цикла или таковое

не требуется. Тогда само выражение пропускается, но точка с запятой обязательно должна быть.

Задача 1.1 Вычислить значение f(x) =

7

1

1

,2k

k

k

k

x значение х ввести с экрана.

Текст программы:

void __fastcall TForm1::Button1Click(TObject *Sender) { float x = StrToFloat(Edit1->Text); 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); }

10 ,1i

s = s + i

s = 0

6

BAx , , h

y=y+ kk xx 5/cos21

Начало

Конец

Вывод x,y

10,1k

y=0

Ввод

A,B,h

Задача 1.2 Вычислить значение

i

k

m

i kk

k

i

iS

11 )1(

3

2, значение m

ввести с экрана.

Текст программы:

void __fastcall TForm1::Button1Click(TObject *Sender) { int i, k, m = StrToInt(Edit1->Text); float S = 0, p; for (i = 1; i <= m; i++) if ( i != 2 && i != 0)

{ p = 1; for (k = 1; k <= i; k++) if (k != 1 && k != 0) p *= (float) (k +3.0) / (k * (k - 1)); S += (float) i / (i - 2) * p; }

Edit2->Text = FloatToStrF(S, ffGeneral, 4, 3); }

Задача 1.3 Составить схему алгоритма и программу табулирова-

ния функции f(x) =

10

1

21

5

cos

kk

k xx, изменяя x от А = 0,4 до В = 2,8

с шагом h = 0,2.

Текст программы:

void __fastcall TForm1::Button2Click(TObject *Sender) { Edit1->Clear(); Edit2->Clear(); Edit3->Clear(); Memo1->Clear(); Series1->Clear(); }

void __fastcall TForm1::Button3Click(TObject *Sender) { Close(); }

void __fastcall TForm1::Button1Click(TObject *Sender) { float A, B, h, x, y; Series1->Clear(); Memo1->Clear(); Memo1->Lines->Add(" 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); } }

mi ,2

P=P(k+3)/(k(k+1))

Начало

Конец

Вывод S

ik ,1

P = 1

S=S+P*i/(i – 1)

Ввод m

i≠1, i≠0

да

да

нет

S = 0

7

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

Оператор цикла с параметром FOR Цель работы: Изучить возможные варианты организации циклических вычислений

в программе с помощью оператора цикла с параметром.

Контрольные вопросы 1 Какой процесс называется циклическим?

2 Укажите ошибки в следующих фрагментах программ:

а) 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;

3 Чему будет равно значение s после выполнения фрагментов программы:

а) int k, s=1; б) int k, s=1, n=5; в) float s=0.6;

for (k=1; k<=5; k++) s++; for (k=n; k>=1; k--) s *= k; for (int n=5; n<=7; n++) s++;

г) int n, j, s=0; д) int s, k, j; e) int s=0, k, j;

for (n=8; n>5; n--) for (s=0, k=1; k<=3; k++) for (k=1; k<=3; k++)

for (j=5; j>=n; j++) s+=n; for (j=1; j<=k; j++) s+=j; for (j=1; j<=k; j++) s++;

Лабораторное задание 1 Дать ответы на контрольные вопросы.

2 Составить схему алгоритма и программу вычисления функции как суммы членов ряда.

Функции выбирают из таблиц 1.1...1.3 согласно номеру фамилии студента в списке группы. Для

задач среднего уровня сложности рекомендуемое значение переменной x, приведенное в таблице

1.1, ввести с помощью компонента Edit (см. задачу 1.1).

3 Составить схему алгоритма и программу табулирования функции f(x), изменяя x от 0,2

до 14,8 с шагом 0,2. При этом функцию f(x) выбирают из таблицы 1.1 в соответствии с заданным

вариантом, игнорируя в таблице значения x (см. задачу 1.3).

4 Оформить протокол лабораторной работы и записать результаты работы программы.

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

1 52.0;)1(

)sin(27

1

xx

kx

kk

k

11

12

1

88.1;)cos(

k

xk

kx 21

8

1

));2cos()((sink

k xkx х=1.1

2

9

1

1

79.1;1k

x

k

xk

x 12

8

1

75.1;4

sin

k

k

xk

x 22

10

2

3

39.1;)ln(2.1

2arctg

k

xxk

kx

3

12

1

94.0;61.0

)sin(

kk

xkx

kkx 13

7

1

35.1;)2(

)3(ln

kk

k

xx

x 23

11

1

81.0;2

3.0sin

kk

k

xx

4

84.3;

1ln9

1

xkx

x

kk

14

8

1

21.1;)1ln(k

k xx 24

6

1

222

8.0;e

)/(sin

kkx

xkxkxk

5

9

1

73.2;52

2.02sin

k

xk

kx 15

1

623

92.0;k

k

k

xxk

x 25

12

1

51.1;)5(

)cos(

kk

k

xkx

x

6

7

1

85.1;2)2ln

)cos(

k

xkx

kxkx 16

11

12

2.5;14

)1sin(

k

k

xk

x 26

9

2

37.0;1.2)5lg(

5.1)1sin(

k

xkx

x

7

6

2

34.1;2

)17.0sin(

k

k

xxk

x 17

8

1

12

4.0;)12(2

ln

kk

k

xk

x 27

7

13

3

22.1;)1(

12

kx

k

xkk

x

8

8

12

25.0;)2arctg(

2ln5

k

xkx

kx 18

9

22

25.5;13

)etg(

k

x

xk

28

10

1

3 73.2;5

cosk

xkx

k

9

9

22

2

92.1;1

/)tg(

k

xk

kxx 19

10

3

1

84.1;112

cos

kk

k

xxx

29

7

12

12.2;e

)sin(

kx

xk

kxx

10

7

12

77.0;3.0ln

)sin(

k

k

xk

x 20 342.2;

12

cos11

3

2

xk

x

k

k

30

6

2

2.2;)5/sin(

4.4arctg

k

xkxx

kxx

8

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

1

n

k

k

m m

m

k

kS

1

1

12 9

2

5

1 11

k

j ji i

i

j

jjP

1

12 3

11

5

3

6 21

k

i

k

in

i

n

in

i

iR

0

2

23

1

2

k

j

k

ji i

i

j

jZ

4

5 5

11

5

3

2 12

k

j

j

i i

i

jj

jA

1 0 1

4

4

3 22

n

k

k

k

kkQ

1

1

!

71

3

n

k

k

i

k

i

i

kS

3

1

1

21

7

16

5

2 13

k

j jj

jjP

2 !13

6 23

k

i

i

i

iW

1

2

!

31

4

k

j

k

ji i

i

j

jZ

2 53 14

n

k

k

k

kQ

1

2

!

31 24

k

j ji i

i

kj

jjA

1

92

7

3

1

4

5

k

i

i

i

iW

12 4

!11 15

k

t

t

i i

i

t

tU

1 1 7

2

3

)sin( 25

k

j ji i

i

j

jP

1

10

4

)5sin(

3

6

6

k

n

n

n

nY

1

222

!1

91 16

n

k

nk

mk

k

m

m

kS

1 1213

13

25

3

2

3 26

k

n n

nnZ

2 !3

91

7

k

i

i

n

i

n

n

iW

1

2

1

2

2 2

4

3

1 17

k

j

k

ji i

i

jj

jZ

4

5

11

5

3

2 27

n

i i

iip

1 !12

)3)(12(

8

k

j ki i

i

j

jL

1

12

1

5

3

5 18

k

i

k

in

i

in

n

i

iY

1

2

2

8.0

3

4 28

k

i

i

n

i

n

n

iW

1

2

1

2

2 2

4

3

1

9

n

k

k

k

kkQ

1

1

)!1(

31 19

k

j

k

ji ji

i

j

jG

3

5

1

5

34

1 29

k

i

i

i

iikY

12 4

!2

10

k

t

t

i i

i

t

tkZ

1 1 7

23

3)cos(

1 20

k

i

i

i

iD

2

2

!3

)3(sin2 30

k

n

k

n

nnF

0 !

42

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

№ вар. Индивидуальное задание

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

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

N

i

ias0

2 , где

.3 íåêðàòíîì ïðè3

3; êðàòíîì ïðè3

iii

iiai

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

N

i

i

j i

js

1 1 !

!.

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

5 Ввести натуральные числа N и M (N > M). Вычислить

N

Mk

kks )!ln(2 .

6 Ввести натуральное число N (до 6). Вычислить

N

i iN

is

1 )!(

!.

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

8 Ввести натуральное число N. Определить, есть ли среди чисел число, равное 223 17 NNii )...,,2,1( Ni .

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

(1/1! + |x|) + (1/2! + |x|) + … + (1/N! + |x|).

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

9

Окончание табл. 1.3

№ вар. Индивидуальное задание

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

(1/2 + cos|x|) + (2/3 + cos|2x|) + … + (N/(N + 1) + cos|Nx|).

12 Ввести вещественное число A > 0. Вычислить

15

1i

ias , где

15.ïðè25

15;0ïðè5

AA

AAai

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

(1 + sin(x)/1!)(1 + sin(2x)/2!) … (1 + sin(Nx)/N!).

14 Ввести вещественное число A. Вычислить

15

1

)95.1,2min(i

iAs .

15 Ввести натуральное число K. Вычислить

K

i iap

1

1, где

íå÷åòíûõ. ïðè2

÷åòíûõ; ïðè2

iii

iiai

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

N

i

i

j j

is

1 1 )!1(

!.

17 Ввести натуральные числа N и M (N > M). Вычислить F = (N! – M!)/(N – M)!

18 Ввести натуральные числа N и M (N > M). Вычислить

N

Mk k

ks

)!tg(1

1.

19 Ввести натуральное число N (до 6). Вычислить

N

i iN

is

1 )!1(

!.

20 Ввести вещественное число A. Вычислить

6

1

)2,max(i

iAp .

21

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

(x/2 + tg|x|) + (x2/3 + tg|2x|) + … + (x

N/(N + 1) + tg|Nx|).

22 Ввести вещественное число A > 0. Вычислить

15

1i

ias , где

.10ïðè5

;100ïðè3

AA

AAai

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

(1 + sin(x)/1!) + (1 + sin(x2)/2!) + … + (1 + sin(x

N)/N!).

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

25 Ввести натуральные числа N и M (N > M). Вычислить

N

Mk kN

ks

)!1(

!1.

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

(x/2! + ln|x|) + (x2/3! + ln|2x|) + … + (x

N/(N + 1)! + ln|Nx|).

27 Ввести вещественное число A. Вычислить

10

1

)5,2,5max(i

iAs .

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

29 Ввести натуральные числа N и M (N > M). Вычислить

N

Mk k

ks

)!cos(1

)!sin(1.

30 Ввести вещественное число A. Вычислить

9

1

),2

min(i

iA

p .

10

Условие?

Операторы

Да

Нет

2 Организация вычислений

с использованием условных операторов цикла

Форматы операторов цикла с предусловием while и постусловием

do-while:

while (условие) { последовательность операторов };

Последовательность операторов цикла выполняется нуль или более раз

до тех пор, пока условие истинно (имеет ненулевое значение), а выход из

цикла осуществляется тогда, когда оно станет ложным (равно нулю).

do { последовательность операторов } while (условие);

Последовательность операторов выполняется один или несколько

раз до тех пор, пока условие станет ложным (равным нулю). Оператор

цикла do-while используется в тех случаях, когда необходимо выполнить

тело цикла хотя бы один раз, так как проверка условия осуществляется

после выполнения операторов.

Если тело цикла состоит из одного оператора, то операторные скобки

{} необязательны. Операторы while и do-while могут также завершиться

при выполнении операторов break, goto, return внутри тела.

Задача 2.1 Вычислить сумму знакопеременного ряда

5

1

1

!12

)1(

i

ii

i

xS тремя вариантами, ис-

пользуя разные операторы цикла. Схемы алгоритмов приведены на рис. 2.1.

Условие?

Операторы

Нет

Да

i = 1, 5

Начало

S = 0

Ввод х

f = 1

k = 1,2i-1

f = f * k

Вывод

S

S=S+(–1)i+1

xi /f

Конец

а

Начало

S = 0, i = 1

Ввод х

f = 1, k = 1

f=f*k, k=k+1

б

Конец

i <= 5

Вывод

S

i = i + 1

k<=2i-1

Да

Нет

Да

Нет

S=S+(–1)i+1xi /f

Начало

S = 0, i = 1

Ввод х

f = 1, k = 1

f=f*k, k=k+1

в

Конец

i <= 5

Вывод

S

i = i + 1

Да

Нет

k<=2i-1

Да

S=S+(–1)i+1

xi /f

Нет

Рисунок 2.1 – Блок-схемы функций:

а – zikl_ for; б – zikl_ while; в– zikl_do

11

Тексты программ с использованием разных операторов цикла:

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; s += pow(-1, i +1) * pow(x, i) / f; } Edit2->Text = loatToStr(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++; } s += pow(-1, i +1) * pow(x, i) / 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) ; s += pow(-1, i +1) * pow(x, i) / f; i++; } while (i <= 5); Edit4->Text = FloatToStr(s); }

Задача 2.2 Вычислить сумму ряда

1

12

)!12(3kk

k

k

xS , суммируя

члены ряда, значения которых по модулю больше заданной точности 410 . Определить количество слагаемых. Значение х (– 2 < x < 2) вво-

дить с клавиатуры.

При разработке программы для решения

данной задачи неуместно использовать оператор

цикла с параметром for, поскольку заранее неиз-

вестно количество повторений такого цикла. Це-

лесообразным будет использование оператора

цикла с постусловием do-while, поскольку на мо-

мент первой проверки условия уже необходимо

знать значение первого слагаемого.

Текст программы:

void __fastcall TForm1::Button1Click(TObject *Sender) { float x, a, s = 0; // Объявление переменных и 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; // Вычисление факториала a = pow(x, 2*k+1)/( pow(3, k)*f); // Вычисление k-го слагаемого s += a; // Суммирование слагаемых

Вычисл. а

S = 0, k=0

f = f * i

Начало

Конец

Вывод

S, k

k=k+1, f=1

S = S + а

Ввод х

10,1k

10,1k

Да

Нет

12

} while(fabs(a) >= 1e-4); Edit2->Text = FloatToStr(s) ; // Вывод полученной суммы и Edit3->Text = IntToStr(k); // количества слагаемых }

Задача 2.3 Вычислить сумму ряда

1

1

)!3)(1(

1

k

kk

kk

xy , суммируя члены ряда, значения ко-

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

(– 2 < x < 2) и 410 вводить с клавиатуры.

Множитель (–1)k

при нечетных k = 1, 3, 5, … равняется (-1), а при четных k = 2, 4, … равня-

ется 1. Таким образом, представленный ряд является знакочередующимся, где все нечетные слага-

емые будут отрицательными, а все четные – со знаком «+». Для наглядности и контроля правиль-

ности в решении отдельно приведем все слагаемые.

Для того чтобы сделать алгоритм программы более оптимальным, можно его усовершен-

ствовать, но для этого надо вычислить рекуррентный множитель. Это позволит в данной програм-

ме избавиться от вложенного цикла для вычисления факториала и оператора проверки на нечет-

ность k.

Остановимся более подробно на выведении рекуррентной формулы.

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

1

1

)!3)(1(

1

k

kk

kk

xy в виде

1k

kuy , где

)!3)(1(

11

kk

kk

k

xu

. Рекур-

рентный множитель – это соотношение двух рядом расположенных членов ряда:

12 uRu , 23 uRu , …, 1 kk uRu ,

откуда 1

k

k

u

uR .

Для определения R в эту формулу надо подставить

)!3)(1(

11

kk

kk

k

xu

и 1ku . Для вычисления

1ku подставим в выражение для ku вместо k – (k – 1):

))!1(3(

1

1

1

kk

kk

k

xu =

)!33(

11

kk

kkx

;

1

k

k

u

uR =

)!3)(1(

11

kk

kk

k

xu

∙ 11

)!33(

kk

x

kk=

)!3()1()1(

)!33()1(1

1

kkx

kkxkk

kk

=

=kkkk

k

k

kx kkkk

3)13()23()33(...21

)33(...21

)1(

)1( )1(1

= –)13)(23)(1(3 kkk

x.

Кроме рекуррентного множителя R, надо вычислить первый член ряда при k = 1:

)!3(2

2

1

1

xu =

12

x.

Текст программы:

void __fastcall TForm1::Button1Click(TObject *Sender) { float x, y, u, r, eps; int i, f, k = 1; x = StrToFloat(Edit1->Text); eps = StrToFloat(Edit2->Text); u = x/12; y = u; do { k++; r = -x/(3*(k+1)*(3*k-2) *(3*k-1)); u *= r ; y += u; } while(fabs(u) >= eps); Edit3->Text = FloatToStr(y); Edit4->Text = IntToStr(k); }

13

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

Условные операторы цикла

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

Контрольные вопросы

1 Структура и порядок выполнения оператора цикла while.

2 Какое значение получит переменная s после выполнения следующих операторов?

а) int k = 0, s = 17; б) float s = 0.5; int i = 0;

while (k < 7) { k++; s--; } while (i < 4) {i =i+2; s += 1./ i; }

3 Структура и порядок выполнения оператора цикла do-while.

4 Чем отличаются операторы цикла while и do-while?

5 Какое значение получит переменная s после выполнения следующих операторов?

а) int i = 1, s = 1; б) float s = 0.2; int i = 0;

do { i++; s *= i; } while (s < 7); do { i++; s += 1./i } while (i <= 1);

6 Какое значение получит переменная s после выполнения следующих операторов?

а) for(s=0, k=1; k<=2; k++) б) float s = 0; int i = 0;

{ m=k; while (i < 5) i++;

do { m++; s+=m;} while( m <= 2); } s =s + 1.0/i;

Лабораторное задание

1 Дать ответы на контрольные вопросы.

2 Составить схему алгоритма и программу вычисления функции как суммы членов ряда со-

гласно указанному преподавателем уровню сложности.

3 Оформить протокол лабораторной работы и записать результаты работы программы.

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

Составить схемы алгоритмов и программы вычисления функции f(x) тремя вариантами с ис-

пользованием разных операторов цикла. Функцию f(x) выбирают из таблиц 1.1–1.2. Т. е. задание

заключается в дополнении программы предыдущей лабораторной работы еще двумя вариантами

решения этой же задачи, но с использованием условных операторов цикла (см. задачу 2.1).

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

Составить схемы алгоритмов и программы вычисления функции бесконечного ряда, сумми-

руя члены ряда, значения которых по модулю не превышает заданной точности 410 . Опреде-

лить количество суммируемых слагаемых. Вычисления выполнить для х = 0,5. Использовать опе-

ратор цикла while для нечетных вариантов и do-while для четных. Задания выбрать из таблицы 2.1

согласно индивидуальному варианту (см. задачу 2.2).

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

Составить схемы алгоритмов и программы вычисления функции бесконечного ряда, сумми-

руя члены ряда, значения которых по модулю превышают заданной точности 410 . Определить

количество суммируемых слагаемых. Значения х (–2 < x < 2) ввести с клавиатуры. Задания вы-

брать из таблицы 2.1 согласно индивидуальному варианту. Для достижения большей оптимально-

сти алгоритма в программе использовать рекуррентные формулы для вычисления членов ряда (см.

задачу 2.3).

14

Таблица 2.1 – Индивидуальные задания

1

1 )!12(

)1( 12

k k

kk x

6

1 )!1(

)1(2

12

k kk

kk x

11

1 !)2(

)1( 131

k kk

kk x

16

1 )!12(

)1( 12

k k

kk x 21

1 )!12(

)1( 21

k kk

kk x

26

1 )!1()12(

)1( 11

k kk

kk x

2

1 12!

)1( 21

k kk

kk x

7

1 )!12(

)1( 21

k k

kk x

12

1 )!3)(3(

)1( 13

k kk

kk x

17

1 )!4(

)1( 1

k k

kk x

22

1 )!2(

)1( )1(2

k k

kk x

27

1 1 !2

)1( 231

k k k

kk x

3

1 !

)1( 1

k k

kk x

8

1 )!2(

)1( 131

k k

kk x

13

1 )!1(3

)1( 131

k kk

kk x

18

12

13

)!1(

)1(

k kk

kk x 23

1 )!12(

)1( 12

k kk

kk x

28

1 )!12(2

)1( 11

k kk

kk x

4

1 )!12(

)1( 12

k k

kk x

9

1 )!2(

)1(2

31

k kk

kk x

14

1 !)2(

)1( )1(2

k kk

kk x

19

1 2!

)1( 21

k kk

kk x

24

1 )!3(2

)1( 231

k kk

kk x

29

1 )!12(3

)1( 131

k

k

kk

xk

5

1 )!3(

)1( 12

k kk

kk x

10

1 )!12(

)1( 21

k k

kk x

15

1 )!3)(3(

)1( )2(31

k kk

kk x

20

1 )!3(2

)1( 13

k kk

kk x

25

1 )!23(

)12()1(

k k

kkk x

30

1 )!12(2

)1( 12

k kk

kk x

15

i = 1, 5

f = 1

k =1,i+1

f = f * k

Выход из sum

S=S + (–1) ixi-1/f

Вход в sum

S = 0

Блок-схема функции sum

3 Функции в С++

Процесс разработки программного обеспечения предполагает разделение сложной задачи на

набор более простых задач и заданий. В С++ поддерживаются ф у н к ц и и как логические еди-

ницы (блоки текста программы), служащие для выполнения конкретного задания. Функции иногда

еще называют п о д п р о г р а м м а м и. Подпрограммы решают небольшую и специфическую

часть общей задачи. В отличие от других языков программирования высокого уровня, в языке С++

нет деления на подпрограммы-процедуры и подпрограммы-функции.

Функция – это совокупность объявлений и операторов, обычно предназначенных для реше-

ния определенной задачи. Каждая функция должна иметь и м я, которое используется для ее объ-

явления, определения и вызова.

При вызове функции ей при помощи аргументов (формальных параметров) могут быть пере-

даны некоторые значения (фактические параметры), используемые во время выполнения функции.

Функция может возвращать некоторое (одно!) значение. Это возвращаемое значение и есть ре-

зультат выполнения функции, который при выполнении программы подставляется в точку вызова

функции, где бы этот вызов ни встретился. Допускается также использовать функции, не имею-

щие аргументов, и функции, не возвращающие никаких значений. Действие таких функций может

состоять, например, в изменении значений некоторых переменных.

Задача 3.1 Вычислить сумму знакопеременного ряда

5

1

1

)!1(

)1(

i

ii

i

xS .

Вычисления по выполнению задания организуем в функции.

Текст функции и ее вызова в основной программе:

float sum(float x) { int i, f, k; float s = 0; for( i=1; i<=5; i++) { for( k=1, f=1; k <= i+1; k++) f *= k; s+= pow (-1, i)*pow(x, i-1)/f; } return s; }

void __fastcall TForm1::Button1Click (TObject *Sender)

{ float s, x=StrToFloat(Edit1->Text); s=sum(x); Edit2->Text=FloatToStr(s); }

Задача 3.2 Вычислить сумму ряда

1

12

!k

k

k

xS , суммируя члены ряда, значения которых

по модулю больше заданной точности 410 . Значение х (– 2 < x < 2) вводить с клавиатуры.

Начало

Конец

Блок-схема для

кнопки «Решение»

s = zikl_for(x)

Вывод s

Ввод x

16

Подобная задача была рассмотрена в лекции 1 (задача 1.6). Организуем решение таким обра-

зом, чтобы в головной программе были прописаны операторы ввода/вывода данных, а все вычис-

ления по выполнению задания вынесем в функции.

Текст функции и ее вызова в основной программе:

float sum(float x, float eps) { float a, s = 0; int f, i, k = 0; do { k++; for(i=1, f=1; i <= k; i++) f *= i; a = pow(x,2*k +1)/f; s += a; } while(fabs(a) >= 1e-4); return s; }

void __fastcall TForm1::Button1Click(TObject *Sender)

{ float x, eps, s; x = StrToFloat(Edit1->Text); eps = StrToFloat(Edit2->Text); s = sum(x,eps); Edit3->Text = FloatToStr(s) ; }

Задача 3.3 Вычислить сумму знакопеременного ряда

5

1

11

!

)1(

i

ii

i

xS тремя вариантами,

используя разные операторы цикла.

Подобное задание уже было рассмотрено в задаче 2.1. Организуем решение таким образом,

чтобы в головной программе остались операторы ввода/вывода данных, а все вычисления по вы-

полнению задания организуем в функциях.

Блок-схемы функций:

а – zikl_ for; б – zikl_ while; в– zikl_do

Начало

Конец

Вывод s

Ввод х,

eps

Вызов

s = sum(х, eps)

Блок-схема

основной программы Вычисл. а

S = 0, k=0

f = f * i

Вход в sum

Выход из sum

k=k+1, f=1

S = S + а

|a| ≥ eps

10,1k

Нет

Блок-схема

функции sum

Да

i = 1, 5

f = 1

10,1k

f = f *k

Выход из zikl_for

S=S+(–1)i+1xi+1/f

Вход в zikl_for

S = 0

a

Вход в zikl_while

S = 0, i=1

f = 1, k=1

f=f*k, k=k+1

Выход из zikl_while

i <= 5

i = i + 1

k <= i Да

Нет

Да

Не

т

б

S=S+(–1)i+1xi+1/f

Вход в zikl_do

S = 0, i=1

f=1, k=1

f=f*k, k=k+1

Выход из zikl_do

i <= 5 Да

Нет

k <= i Да

Нет

в

S=S+(–1)i+1xi+1/f

i = i + 1

17

Блок-схемы с вызовом функций для кнопок:

а – For; б – while; в – do_while

Тексты функций и их вызова в основной программе:

float zikl_for (float x) { int i, f, k; float S = 0; for( i = 1;i <= 5;i++) { for(k = 1, f = 1; k <= i; k++) f *= k; S += pow(-1, i +1) * pow(x, i + 1) / f ; } return S; }

float zikl_while (float x) { int i = 1, f, k; float S = 0; while( i <= 5) { f = 1; k = 1; while(k <= i) { f *= k; k++; } S += pow(-1, i +1) * pow(x, i + 1) / f ; i++; } return S; }

float zikl_do(float x) { int i = 1, f, k; float S = 0; do { f = 1; k = 1; do { f *= k; k++; } while(k <= i) ;

S += pow(-1, i +1) * pow(x, i + 1) / f ; i++; } while( i <= 5); return S; }

void __fastcall TForm1::Button1Click(TObject *Sender)

{ float s, x=StrToFloat(Edit1->Text); s=zikl_for(x); Edit2->Text=FloatToStr(s); }

void __fastcall TForm1::Button2Click(TObject *Sender)

{ float s, x=StrToFloat(Edit1->Text); s=zikl_while(x); Edit3->Text=FloatToStr(s); }

void __fastcall TForm1::Button3Click(TObject *Sender)

{ float s, x=StrToFloat(Edit1->Text); s=zikl_do(x); Edit4->Text=FloatToStr(s); }

Начало do_while

Конец

в

s=zikl_while(x)

Вывод s

Ввод x

Начало For

Конец

а

s=zikl_for(x)

Вывод s

Ввод x

Начало while

Конец

б

s=zikl_while(x)

Вывод s

Ввод x

18

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

Создание функций пользователя

для организации циклических вычислений

Цель работы: Изучить средства организации функций алгоритмическим языком C++.

Контрольные вопросы

1 Укажите количество результатов, которые может напрямую возвращать функция?

2 Каково значение результата выполнения функции по умолчанию?

3 Какие требования выдвигаются к расположению, типу и количеству формальных парамет-

ров в описании функции и фактических параметров при вызове функции? Выберите верные отве-

ты:

а) тип и порядок расположения свободный;

б) строгое соблюдение типа и порядка расположения;

в) количество фактических и формальных параметров должно быть одинаковым;

г) количество фактических и формальных параметров может отличаться.

4 Составьте два примера функций (с использованием рекурсии и без нее) для вычисления

факториала некоторого числа N.

Лабораторное задание

1 Дать ответы на контрольные вопросы.

2 Составить схемы алгоритмов, разработать проект формы и программы для выполнения ин-

дивидуальных заданий, которые выбираются из таблиц предыдущих лабораторных работ № 2.1 и

№ 2.2, согласно уровню сложности по указанию преподавателя. В проекте предусмотреть ввод ис-

ходных данных с клавиатуры и вывод полученных результатов на форму в компоненты в головной

программе, а обработку данных, т. е. все вычисления, организовать в функциях. Т. е. задание за-

ключается в переделке уже существующих программных проектов таким образом, чтобы в голов-

ной программе оставались операторы ввода/вывода данных, а все вычисления по выполнению ин-

дивидуального задания были организованы в функциях (см. задачи 3.1 и 3.2).

3 Оформить протокол лабораторной работы и записать результаты работы проекта програм-

мы.

19

4 Одномерные массивы

М а с с и в (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 b[10] = {1.5, -3.8, 10}; // b[0]=0.5, b[1]= -3.8, b[2]=10, b[3]=b[4]=…=b[9]=0

char c[6]="Builder"; // c[0]="B", c[1]="u", c[2]="i", c[3]="l", c[4]="d", c[5]="e", c[6]="r"

char ss[ ] = "abc"; // ss[0]= "a", ss[1]= "b", ss[2]= "c", ss[3]= "\0"

В последнем примере инициализируется ss как массив символов из четырех элементов. Четвер-

тым элементом является символ "\0", который завершает все символьные массивы (строки) в С++.

Если строка короче, чем специфицированный размер массива, то оставшиеся элементы массива

инициализируются нулем (символом "\0").

Задача 4.1 Разработать схему алгоритма и проект программы для ввода элементов одномер-

ного массива из 10 вещественных элементов и вычисления произведения всех ненулевых элемен-

тов массива.

Текст программы:

void __fastcall TForm1::Button1Click(TObject *Sender)

{ float a[10], P = 1; for(int i = 0; i < 10; i++) { a[i] = StrToFloat(Memo1->Lines->Strings[i]); if(a[i] != 0) P *= a[i]; } Edit1->Text = FormatFloat("0.000", P); }

void __fastcall TForm1::Button2Click(TObject *Sender)

{ Memo1->Clear(); Edit1->Clear(); }

void __fastcall TForm1::Button3Click(TObject *Sender)

{ Close(); }

P = 1

10,1k

Ввод a[i]

P=P*a[i]

Начало

Вывод P

Конец

a[i]0 Да

Нет

20

Задача 4.2 Составить схему алгоритма и проект программы для ввода

элементов одномерного массива из 7-ми целых чисел, определения мини-

мального элемента и его порядкового номера.

Текст программы:

void __fastcall TForm1::Button1Click(TObject *Sender)

{ int A[7] ; int i; for(i=0; i<7; i++) A[i]= StrToInt(Memo1->Lines->Strings[i]); int min=A[0], ind=0; for(i=1; i<7; i++) if(min>A[i]) { min=A[i]; ind=i; } Edit1->Text = IntToStr(min)+" индекс - "+IntToStr(ind+1); }

Задача 4.3 Разработать схему алгоритма и проект программы для ввода 11-ти (или меньше)

целых чисел из компонента Memo и отсортировать их по возрастанию.

Значения элементов преобразованного массива в качестве передаваемого результата указы-

вать не надо. Поскольку массив передается по ссылке, то любые изменения в функции сразу отоб-

ражаются и в вызывающей программе.

Текст программы:

sort(int a[ ], int n) { 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; if (n > 11) n = 11; 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])); }

min=A[0], ind=0

10,1k

min=A[i], ind=i

Начало

min, ind+1

Конец

min>A[i]

Да

Нет

410a

Ввод

A[i]

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 Запишите операторы вывода массива из 17-ти вещественных чисел в пять разных компонентов.

Лабораторное задание

1 Дать ответы на контрольные вопросы.

2 Составить схемы алгоритмов, разработать проект формы и программы в C++ Builder для

выполнения индивидуального задания из таблиц 4.1...4.3 согласно с номером фамилии студента в

списке группы. В проекте предусмотреть ввод элементов массива с клавиатуры через компонент

Memo и вывод полученных результатов на форму в компоненты Edit, Memo, ListBox или Label (по

указанию преподавателя).

3 Оформить протокол лабораторной работы и записать результаты работы программы.

Таблица 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 действ. Вычислить произведение минимального и максимального элементов массива

22

Окончание таблицы 4.1

№ вар.

Размер массива

Тип данных

Индивидуальное задание

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

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 целый Вычислить факториал индекса максимального элемента

23

Окончание таблицы 4.2

№ вар.

Размер массива

Тип данных

Индивидуальное задание

16 12 действ. Вычислить сумму всех элементов от начала до первого отрицательного. Если

среди элементов нет отрицательных, выдать об этом сообщение и вычислить

сумму всех элементов

17 20 целый Вычислить сумму элементов с четными индексами и построить новый мас-

сив разницы элементов исходного массива и вычисленной суммы

18 18 действ. Вычислить сумму элементов массива, значение которых превышает среднее

арифметическое

19 11 целый Вычислить минимальный элемент из четных положительных элементов

20 9 действ. Вычислить максимальный элемент из числа отрицательных элементов

21 16 целый Построить новый массив остатков от деления нацело элементов массива на 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

24

Окончание таблицы 4.3

№ вар.

Размер масси-

вов

Тип данных Индивидуальное задание

12 до 9 действ. Ввести массив и число Р. Определить элемент массива, значение которого

наиболее близко к Р, т. е. значение |xi – Р| минимально

13 до 15 целый Упорядочить массив так, чтобы все положительные числа были располо-

жены сначала по возрастанию, а все отрицательные – в конце по убыванию

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 действ. Ввести два массива, определить минимальные элементы каждого из них

и поменять их местами

25

5 Двумерные массивы

Многомерный массив объявляется в программе следующим образом:

тип имя [ размер 1] [ размер 2] … [ размер n];

Количество элементов массива равно произведению количества элементов по каждому ин-

дексу. Например, int А[4][5];

Объявлен двумерный массив из 4-х строк и 5-ти столбцов (20 элементов) массива целого типа: А[0,0], А[0,1], А[0,2], А[0,3], А[0,4], А[1,0], А[1,1], А[1,2], А[1,3], А[1,4], А[2,0], А[2,1], А[2,2], А[2,3], А[2,4], А[3,0], А[3,1], А[3,2], А[3,3], А[3,4];

Типу массив соответствует память, которая требуется для размещения всех его элементов.

Элементы массива с первого до последнего запоминаются в последовательных возрастающих ад-

ресах памяти. Между элементами массива в памяти разрывы отсутствуют. Элементы массива за-

поминаются друг за другом построчно.

Примеры объявления массивов: float Mas [4][4]; // квадратная матрица 4х4 из 16-ти элементов вещественного типа, char B[5][10]; // двумерный массив из 5х10=50 элементов символьного типа; double W [4][5][4]; // трехмерный массив из 4х5х4=100 вещественных элементов

Задача 5.1 Составить схему алгоритма и разработать проект для ввода

матрицы вещественных чисел размерностью 3х4 и нахождения среднего

арифметического максимального и минимального элементов матрицы.

На форме расположены компоненты StringGrid1, Edit1, Button1, Button2,

Button3, Label1 и Label2, а их новые свойства указаны в таблице 5.1.

Таблица 5.1 – Свойства компонентов

Тексты программ:

void __fastcall TForm1::FormCreate(TObject *Sender) // Создание формы

{ for (int i=1;i<=3;i++)StringGrid1->Cells[0][i]=IntToStr(i)+"-я строка"; for (int j=1;j<=4;j++)StringGrid1->Cells[j][0]=IntToStr(j)+"-й столбец"; } //---------------------------------------------------------------------------

Компоненты Свойства Новые значения

StringGrid1 ColCount 5

StringGrid1 RowCount 4

StringGrid1 Options.goEditing True

StringGrid1 Options.goTabs True

Button1 Caption Решение

Button2 Caption Очистка

Button3 Caption Выход

max=A00, min=A00

12,1 ki

Начало

Вывод sr

Конец

max<Aij

Да

Нет

410a

ki ,1

Ввод Ai,j

9,0i

max=Aij,

11

min>Aij

Да

Нет

min=Aij,

sr=( min+max)/2

26

kol = 0

k = 0

6,1i ,2

Начало

Вывод pk

Конец

Сij ≠ 0

да

Нет

6,0i

3,0j

Ввод Сi,j

2,0i

pk= pk + Cij

kol = kol+1

Да

pk = 0

k=k+1

void __fastcall TForm1::Button1Click(TObject *Sender) { float A[3][4], max, min; int i, j; for (i = 0; i < 3; i++) for (j = 0; j < 4; j++) if(StringGrid1->Cells[j+1][i+1] != "") A[i][j]=StrToFloat(StringGrid1->Cells[j+1][i+1]); else { ShowMessage("Заполните [" + IntToStr(i+1) + "," + IntToStr(j+1) + "] элемент"); break; } min=A[0][0]; max=A[0][0]; for (i = 0; i < 3; i++) for (j = 0; j < 4; j++) { if(max < A[i][j]) max = A[i][j]; if(min > A[i][j]) min = A[i][j]; } float sr = (min + max) / 2.; Edit1->Text = FormatFloat("0.00", sr); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button2Click(TObject *Sender) // Очистка { for (int i = 0; i < 3; i++) for (int j = 0; j < 5; j++) StringGrid1->Cells[j+1][i+1] = ""; Edit1->Clear(); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button3Click(TObject *Sender) // Выход { Close(); }

Задача 5.2 Из элементов матрицы размерностью 4х7 целых чисел

вычислить вектор средних арифметических четных элементов нечетных

(1, 3, 5 и 7) столбцов матрицы.

Поскольку при формировании вектора его индексы не совпадают с

индексами нечетных столбцов матрицы, по которым формируется вектор,

то возникает необходимость в использовании дополнительной перемен-

ной, например k для индексов вектора.

На форме расположены

компоненты StringGrid1,

StringGrid2, BitBtn1, а их новые

свойства указаны в таблице

5.2. Компонент BitBtn пред-

ставляет собой разновид-ность

стандартной кнопки Button, но

с возможностью вывода на

кнопку, кроме надписи, пикто-

графических изображений с

помощью свойств Kind или

Glyph.

Текст программы:

void __fastcall TForm1::BitBtn1Click(TObject *Sender)

{ int i,j; int C[4][7]; float p[3]; for (i=0; i<4; i++) for (j=0; j<7; j++) C[i][j] = StrToInt(SG1->Cells[j][i]); int kol, k=0; for(j=0; j<7; j+=2)

Таблица 5.2 – Свойства компонентов

Компоненты Свойства

Новые

значения StringGrid1 ColCount 7

StringGrid1 RowCount 4

StringGrid1 FixedCols 0

StringGrid1 FixedRows 0

StringGrid1 Options.goEditing True

StringGrid1 Options.goTabs True

StringGrid1 Name SG1

StringGrid2 ColCount 4

StringGrid2 RowCount 1

StringGrid2 FixedCols 0

StringGrid2 FixedRows 0

StringGrid2 Name SG2

BitBtn1 Kind bkOK

BitBtn1 Caption Вектор

27

{ p[k] = 0; kol = 0; for (i = 0; i < 4; i++) if(C[i][j]%2 == 0) { p[k] += C[i][j]; kol++; } if(p[k] != 0) p[k] = (float) p[k] / kol;

SG2->Cells[k][0] = FormatFloat("0.00", p[k]); k++; } }

Задача 5.3 Из элементов матрицы размерностью 4х7 вещественных

чисел вычислить вектор произведений ненулевых элементов четных (2, 4

и 6) столбцов матрицы.

Поскольку при формировании вектора его индексы не совпадают с

индексами четных столбцов матрицы, по которым формируется вектор, то

возникает необходимость в использовании дополнительной переменной,

например k для индексов вектора.

На форме расположены компоненты StringGrid1, StringGrid2, BitBtn1,

а их новые свойства указаны в табл. 5.3. Компонент BitBtn представляет

собой разновидность стандартной кнопки Button, но с возможностью вы-

вода на кнопку, кроме надписи, пиктографических изображений с помо-

щью свойств Kind или Glyph.

Текст программы:

void __fastcall TForm1::BitBtn1Click(TObject * Sender)

{ int i, j; float C[4][7], p[3]; for (i = 0; i < 4; i++) for (j = 0; j < 7; j++) C[i][j] = StrToFloat(SG1->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++; } }

Т а б л и ц а 5.3 – Новые свойства компонентов

Компоненты Свойства Новые значения

StringGrid1 ColCount 7

StringGrid1 RowCount 4

StringGrid1 FixedCols 0

StringGrid1 FixedRows 0

StringGrid1 Options.goEditing True

StringGrid1 Options.goTabs True

StringGrid1 Name SG1

StringGrid2 ColCount 3

StringGrid2 RowCount 1

StringGrid2 FixedCols 0

StringGrid2 FixedRows 0

StringGrid2 Name SG2

BitBtn1 Kind bkOK

BitBtn1 Caption Вектор

Form1 Caption Задача 5.3

k = 0

4,0j

Начало

Вывод pk

Конец

Сij ≠ 0

да

2,0i

6,0j

Ввод Сi,j

3,0i

pk= pk * Cij

нет

четный стол-

бец?

pk = 1

k=k+1

нет

да

28

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

Обработка двумерных массивов

Цель работы: Изучить средства использования многомерных массивов в программах C++.

Контрольные вопросы

1 Как определить размерность массива?

2 Какие из приведенных ниже объявлений двумерных массивов неправильны и почему?

а) int C [1..5, 1..5];

б) float C[5][5];

в) float C [ 1..5][1..5];

г) int C: [5][5];

3 Матрица целых чисел состоит из 3-х строк и 5-ти столбцов. Напишите фрагмент програм-

мы для ввода ее элементов с компонента StringGrid.

4 Матрица целых чисел состоит из 3-х строк и 2-ти столбцов. Присвойте значения элементам

массива при объявлении.

5 Для матрицы вещественных чисел из 3-х строк и 5-ти столбцов напишите фрагмент про-

граммы для вывода на форму ее элементов в компонент StringGrid.

Лабораторное задание

1 Дать ответы на контрольные вопросы.

2 Составить схемы алгоритмов, разработать проект формы и программы алгоритмическим

языком C++ для выполнения индивидуального задания согласно варианту из таблиц 5.4…5.6. В

проекте предусмотреть ввод элементов матрицы с клавиатуры через компонент StringGrid (значе-

ния произвольные) и вывода полученных результатов на форму.

3 Оформить протокол лабораторной работы и записать результаты работы проекта програм-

мы.

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

вар. Индивидуальное задание

1 В матрице вещественных чисел из 5-ти строк и 4-х столбцов определить количество положи-

тельных, отрицательных и нулевых элементов

2 В матрице целых чисел размерностью 45 определить номер строки, которая содержит

наибольший элемент

3 Определить минимальный элемент главной диагонали квадратной матрицы размерностью

55 и номер строки, в котором он находится

4 Поменять местами элементы первой строки матрицы вещественных чисел размерностью 44

и элементы ее неглавной диагонали

5 В матрицы целых чисел размерностью 35 заменить отрицательные элементы нулями

6 Определить максимальный и минимальный элементы матрицы вещественных чисел размер-

ностью 66 и поменять их местами

7 Определить наибольший элемент из числа отрицательных элементов четных столбцов матри-

цы целых чисел размерностью 46

8 Вычислить сумму элементов неглавной диагонали матрицы 55 целых чисел

9 Для матрицы целых чисел размерностью 55 получить транспонированную матрицу

10 Определить номер столбца матрицы вещественных чисел размерностью 36 с наименьшим

элементом

11 Определить минимальный элемент неглавной диагонали матрицы целых чисел размерностью

55 и номер столбца, в котором он находится

12 Вычислить вектор сумм элементов строк матрицы целых чисел размерностью 73

29

Окончание таблицы 5.4

вар. Индивидуальное задание

13 Заменить в нечетных строках матрицы вещественных чисел размерностью 74 отрицательные

элементы нулями, а положительные элементы – единицами

14 Вычислить разницу сумм элементов главной и неглавной диагоналей матрицы вещественных

чисел размерностью 55

15 В матрице вещественных чисел размерностью 75 вычислить сумму всех отрицательных

элементов четырех строк

16 В матрице целых чисел размерностью 45 заменить все отрицательные элементы нулями

17 Вычислить произведение минимального элемента матрицы целых чисел размерностью 45 на

его среднее арифметическое

18 В матрице целых чисел размерностью 64 вычислить среднее арифметическое положитель-

ных элементов

19 В матрице целых чисел размерностью 54 заменить в нечетных строках положительные эле-

менты на 1, а в четных – отрицательные на –1

20 В матрице вещественных чисел размерностью 63 вычислить произведение всех отрицатель-

ных элементов четных строк

21 В матрице целых чисел размерностью 35 определить количество элементов, меньших чем

среднее арифметическое

22 В матрице вещественных чисел размерностью 53 заменить все элементы, превышающие 2.5,

на –1

23 Вычислить вектор модулей сумм элементов строк матрицы вещественных чисел размерно-

стью 45

24 Определить в матрице целых чисел размерностью 74 наименьший элемент из числа положи-

тельных и наибольший из числа отрицательных и поменять их местами

25 Вычислить вектор элементов главной диагонали матрицы вещественных чисел размерностью

55

26 Вычислить вектор сумм квадратов элементов столбцов матрицы вещественных чисел размер-

ностью 35

27 В матрице целых чисел размерностью 55 поменять местами элементы главной и неглавной

диагоналей

28 В матрице целых чисел размерностью 55 заменить все четные элементы на нули

29 Вычислить разницу сумм элементов первой строки и последнего столбца матрицы веще-

ственных чисел размерностью 46

30 Получить вектор сумм элементов главной и неглавной диагонали матрицы вещественных чи-

сел размерностью 66

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

вар. Индивидуальное задание

1 Получить вектор сумм элементов нечетных столбцов матрицы 37 целых чисел

2 Получить вектор скалярных произведений строк матрицы вещественных чисел размерностью

44 на ее последний столбец

3 Получить вектор произведений нечетных элементов четных строк матрицы целых чисел раз-

мерностью 64

4 Получить вектор скалярных произведений элементов первой строки матрицы целых чисел

размерностью 44 на столбцы этой матрицы

5 Определить номер столбца матрицы вещественных чисел размерностью 45 с наименьшей

суммой элементов

6 Получить вектор произведений элементов столбцов матрицы целых чисел размерностью 36

30

Окончание таблицы 5.5

вар. Индивидуальное задание

7 Вычислить вектор произведений четных элементов нечетных столбцов матрицы целых чисел

размерностью 45

8 Определить номер строки матрицы целых чисел размерностью 45 с наибольшей суммой

элементов

9 Получить вектор сумм нечетных элементов четных строк матрицы целых чисел размерно-

стью 66

10 Получить вектор скалярных произведений элементов столбцов матрицы вещественных чисел

размерностью 33 на ее главную диагональ

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

мерностью 46

12 В матрице вещественных чисел размерностью 73 определить номер строки с наименьшей

суммой модулей элементов

13 Заменить элементы главной диагонали матрицы целых чисел размерностью 55 суммами

элементов столбцов

14 Получить вектор среднеарифметических положительных элементов четных строк матрицы

целых чисел размерностью 78

15 Сформировать вектор из наибольших элементов строк матрицы вещественных чисел размер-

ностью 76

16 Заменить элементы неглавной диагонали матрицы целых чисел размерностью 44 суммами

элементов ее строк

17 Получить вектор скалярных произведений строк матрицы целых чисел размерностью 55 на

ее неглавную диагональ

18 Получить вектор из строки матрицы, содержащей наибольший элемент матрицы целых чисел

размерностью 56

19 Заменить элементы главной диагонали матрицы целых чисел размерностью 66 суммой мак-

симального и минимального элементов матрицы

20 Заменить элементы неглавной диагонали матрицы вещественных чисел размерностью 44

значением минимального элемента матрицы

21 Заменить нулевые элементы матрицы вещественных чисел размерностью 55 ее максималь-

ным элементом

22 В матрице вещественных чисел размерностью 73 поменять местами первый и последний от-

рицательные элементы

23 Получить вектор сумм положительных элементов строк матрицы целых чисел размерностью

65. Упорядочить полученный вектор по возрастанию

24 Среди строк матрицы целых чисел размерностью 54 найти ту, для которой сумма нечетных

элементов будет минимальной, и построить из этой строки вектор

25 Если в матрице вещественных чисел 64 сумма положительных чисел больше модуля суммы

отрицательных, то заменить угловые элементы большей из сумм. Иначе выдать сообщение

26 Получить вектор скалярных произведений столбцов матрицы вещественных чисел размерно-

стью 44 на ее неглавную диагональ

27 Сформировать вектор из наибольших элементов строк матрицы вещественных чисел размер-

ностью 56

28 Сформировать вектор из среднеарифметических элементов строк матрицы вещественных чи-

сел размерностью 54

29 Получить вектор среднеарифметических первого и последнего элементов четных строк мат-

рицы целых чисел размерностью 78

30 Получить вектор квадратов элементов минимальных элементов нечетных столбцов матрицы

вещественных чисел размерностью 65

31

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

вар. Индивидуальное задание

1 Из заданной матрицы вещественных чисел размерностью 57 получить новую матрицу, в ко-

торой каждый элемент вычисляется как полусумма среднеарифметических соответствующих

строки и столбца

2 В матрице вещественных чисел размерностью 77 вычислить определитель

3 Получить вектор максимальных элементов строк матрицы вещественных чисел размерностью

55

4 Получить произведение матрицы целых чисел размерностью 55 на ее транспонированную

матрицу

5 В матрице вещественных чисел размерностью 73 определить номер строки, длина которой

(как вектор) максимальна

6 Сформировать вектор из строки матрицы вещественных чисел размерностью 83, наименее

удаленной от второй строки, если расстояние между строками вычисляется по формуле

n

j

jiji aad1

2

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

чисел размерностью 44, а затем по возрастанию (сверху вниз) – элементы всех столбцов

8 Наименьшую по длине строку матрицы вещественных чисел размерностью 54 заменить на

наибольшую по длине

9 Сформировать вектор из строки матрицы вещественных чисел размерностью 55, наиболее

удаленной от первой строки, причем в качестве расстояния от первой строки матрицы до

і-той взять величину 1,1

1

iaad j

n

j

iji

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

шей суммой

n

j

ija1

2

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

наибольшим весом, где вес столбца матрицы вычисляется так

n

i

ijj aW1

12 Сформировать вектор из столбца матрицы вещественных чисел размерностью 86 с

наибольшей суммой ij

n

j

ij aa 1

13 Каждый отрицательный элемент матрицы вещественных чисел размерностью 48 заменить

суммой положительных элементов той строки, в которой расположен этот элемент

14 Сформировать вектор из столбца матрицы вещественных чисел размерностью 68, наименее

удаленного от первого, причем за расстояние между столбцом j и первым считать величину

1,1

1

jaad i

n

i

ijj

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

шим весом, а вес строки матрицы считать равным

n

j

iji aW1

16 Ввести две матрицы вещественных чисел 45. Если максимальный элемент первой матрицы

меньше чем максимальный элемент второй матрицы, то поменять местами строки матриц,

содержащие максимальные элементы. Иначе выдать сообщение

17 Из матрицы целых чисел размерностью 45 сформировать вектор положительных элементов

32

Окончание таблицы 5.6

вар. Индивидуальное задание

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

главной диагональю и минимальный элемент в секторе под главной диагональю. Наиболь-

шим из этих значений заменить элементы главной диагонали

19 Матрица целых чисел размерностью 55 состоит из чисел от 0 до 9. Если количество повто-

рений элемента матрицы совпадает с самим элементом, то заменить его на нуль

20 Сформировать вектор из строки матрицы целых чисел размерностью 75, наиболее удален-

ной от третьей строки, причем в качестве расстояния между строками взять величин

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

личиной

n

i

ijj aW1

2

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

содержание каждого из этих чисел в матрице

23 Матрица целых чисел размерностью 64 состоит из чисел от 0 до 9. Сформировать вектор

длиной 10, элементами которого будут числа повторов этих констант в матрице

24 Сформировать вектор из наиболее удаленного от (n – 1)-го столбца матрицы вещественных

чисел размерностью 65, причем за расстояние считать величину 1,

1

ni

n

i

ijj aad

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

и поменять местами эту строку с первой

26 Ввести матрицу вещественных чисел 55 и вектор из пяти вещественных чисел. Заменить все

строки массива, в которых есть два или больше отрицательных чисел, на элементы вектора

27 Вывести координаты элемента матрицы вещественных чисел размерностью 57 с наимень-

шим весом, а вес рассчитывать по формуле

n

i

m

j

ij

ijji

aW

1 1

28 Если в матрице вещественных чисел 45 сумма положительных чисел больше модуля суммы

отрицательных, то заменить угловые элементы средним арифметическим элементов матри-

цы. Иначе выдать сообщение

29 Если в матрице целых чисел 56 содержится четное количество отрицательных чисел, то за-

менить любую половину из этих чисел на нуль. Иначе заменить все отрицательные элементы

на значение их количества

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

по формуле

n

i

m

j

iijjijij aaad1 1

33

6 Указатели и динамическое управление памятью

Оперативная память ПК представляет собой совокупность ячеек для хранения информации,

каждая из которых имеет собственный номер. Эти номера называются адресами, они позволяют

обращаться к любому байту памяти. Существует два способа закрепления оперативной памяти за

величинами, которые будут использоваться в программах. Обычно применяют так называемый

статический способ закрепления оперативной памяти. При использовании этого способа память

для каждой величины остается занятой ею в течение всего времени работы программы. При таком

способе при объявлении массива надо учитывать максимально возможное количество его элемен-

тов. А это приводит к неэффективному использованию памяти.

При динамическом способе закрепления оперативной памяти сама программа может выде-

лять и освобождать необходимую память для данных, т.е. управлять размещением используемых в

ней данных в оперативной памяти. При этом оперативная память используется более эффективно.

Такая возможность связана с наличием в C++ особенного типа данных – указателей.

Область оперативной памяти, в которой можно выделять отдельные участки для размещения

данных, называется динамической областью памяти, или динамической памятью.

Указатель – переменная, которая указывает на другую переменную (содержит местоположе-

ние другой переменной в форме адреса). В этом смысле имя переменной “отсылает” к ее значению

непосредственно, а указатель – косвенно. Ссылка на значение указателя называется косвенной ад-

ресацией.

Формат объявления указателя:

тип_данных *имя_указателя

* – означает, что следующая за ней переменная является указателем. Переменная, объявлен-

ная как указатель, хранит адрес памяти.

Примеры:

char *mes; // объявляется переменная-указатель mes на величину типа char

int (*p2)[10]; // объявлен указатель p2 на массив из 10 элементов типа int

В С++ Builder указатели используются очень широко. В частности, все компоненты, формы и

т. д. объявляются именно как указатели на соответствующий объект.

Указатели должны инициироваться либо при своем объявлении, либо с помощью оператора

присваивания. Указатель может получить в качестве начального значения 0, NULL или адрес.

Указатель с начальным значением 0 или NULL ни на что не указывает.

Операция адресации "&" (амперсанд) присваивает указателю адрес некоторой переменной.

Операцию "&" также часто используют для передачи в функции параметров по ссылке.

Операция разадресации (или разыменования, или косвенной адресации) (*) применяется

для обращения к переменной по указателю, т. е. для того, чтобы получить значение, на которое

указывает указатель, например:

double y, *py=&y; // объявленному указателю py присваивается адрес y

*py = 7.5; // эквивалентно y = 7.5

С указателями может выполняться ограниченное количество а р и ф м е т и ч е с к и х опера-

ций. Указатель можно увеличивать (++), уменьшать (--), складывать с указателем целые числа (+

или +=), вычитать из него целые числа (– или –=) или вычитать один указатель из другого.

Арифметические операции, применяемые к указателю, имеют осмысленный результат только

когда указатель адресует массив памяти, а целая величина представляет смещение адреса в преде-

лах этого массива. Преобразование целой величины к адресному смещению предполагает, что в

пределах смещения плотно расположены элементы одинакового размера. Это предположение

справедливо для элементов массива. Массив определяется как набор величин одного и того же ти-

па; его элементы расположены в смежных ячейках памяти. Сложение и вычитание адресов, ссы-

лающихся на любые величины, кроме элементов массива, дает непредсказуемый результат, по-

скольку в таком случае не гарантируется плотное заполнение памяти.

34

Пример 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=mass;

Здесь указатель ptr устанавливается на адрес первого элемента массива, причем присваива-

ние ptr=mass можно записать в эквивалентной форме ptr=&mass[0]. Для того чтобы получить зна-

чение 16-го элемента массива mass, можно записать mass[16] или *(mass+16). Результат один и

тот же. При реализации на компьютере первый способ приводится ко второму, т. е. индексное вы-

ражение преобразуется к адресному. Таким образом, операции над указателями обрабатываются

быстрее, поэтому, если элементы массива обрабатываются по порядку, то выгоднее использовать

второй способ. Если же выбор элементов случаен, то, во избежание ошибок, предпочтительнее

первый способ. Кроме того, первый способ более нагляден, что способствует лучшей читаемости

программ.

Для доступа к начальному элементу массива (т. е. к элементу с нулевым индексом) можно

использовать просто значение указателя mass или ptr. Любое из шести присваиваний

* mass = 2; mass [0] = 2; *( mass +0) = 2;

* ptr = 2; ptr[0] = 2; *(ptr+0) = 2;

присваивает начальному элементу массива значение 2, но быстрее всего выполнятся присваивания

*mass=2 и *ptr=2, так как в них не требуется выполнять операции сложения.

Указатели на многомерные массивы в языке С++ – это массивы массивов, т. е. такие масси-

вы, элементами которых являются массивы. При размещении элементы многомерных массивов

располагаются в памяти подряд по строкам, т. е. быстрее всего изменяется последний индекс, а

медленнее – первый. Например, для двумерного массива int matr[4,3]; обращение *(matr) ссылает-

ся на элемент matr[0][0], обращение *(matr+2) – к элементу matr [0][2], обращение *(matr+2*3+1) – к

35

элементу matr [2][1]. Т. е., используя операторы цикла, можно организовать поочередное обраще-

ние к элементам этой матрицы, например для ввода всей матрицы из StringGrid1: for(int i=0;i<3;i++) for(int j=0;j<4;j++) *(matr+i*3+j)=StrToInt(StringGrid1->Cells[j][i]); // *(matr+i*3+j) аналогично matr[i][j]

Задача 6.1 Ввести массив из 7-ми целых чисел определить сумму нечетных элементов.

Текст функции и ее вызова в основной программе:

int fun(int a[7]) { int s=0,*pa=a; for(int i=0; i<7; i++) if (*(pa+i)%2==1) s+=*(pa+i); return s; }

void __fastcall TForm1::Button1Click(TObject *Sender) { int i,a[7]; for(i=0; i<7; i++) *(a+i)=StrToInt(Memo1->Lines->Strings[i]); // обращение *(a+i) эквивалентно a[i] , но не требует последующего // преобразования компилятором, а значит, работает быстрее int sum=fun(a); // вызов функции fun Edit1->Text=IntToStr(sum); }

Задача 6.2 Ввести массив из 8-ми вещественных чисел, вычислить среднее арифметическое

его положительных элементов и построить новый массив как разницу элементов исходного мас-

сива и вычисленного среднего арифметического.

Текст функции и ее вызова в основной программе:

float fun(float * a, int kol) { int k=0; float s=0; for(int i=0; i<kol; i++) if (*(a+i)>0) {s+=*(a+i); k++;} s=s/k; for(int i=0; i<kol; i++) *(a+i) = *(a+i)-s; return s; }

void __fastcall TForm1::Button1Click(TObject *Sender)

{ int i,n=8; float a[8]; for(i=0; i<n; i++)*(a+i)=StrToFloat(Memo1->Lines->Strings[i]); float sr=fun(a,n); Edit1->Text=FormatFloat("0.00",sr); Memo2->Clear(); for(i=0; i<n; i++) Memo2->Lines->Add(FormatFloat("0.00",*(a+i))); }

Задача 6.3 Ввести матрицу целых чисел из 5-ти строк и 4-х

столбцов. Вычислить вектор сумм минимального и максимального

элементов каждого столбца.

Текст функции и ее вызова в основной программе:

void __fastcall TForm1::Button1Click(TObject *Sender) { int i, j, c[5][4], v[4], min, max; for(i=0; i<5; i++) for(j=0; j<4; j++) c[i][j] = StrToInt(SG1->Cells[j][i]); int *pc = &c[0][0]; for(j=0; j<4; j++) { min = *(pc+j); max = *(pc+j); // *(pс+j) аналогично c[0][j] for(i=1; i<5; i++) { if(min > *(pc+i*4+j)) min = *(pc+i*4+j); if(max < *(pc+i*4+j)) max = *(pc+i*4+j); } //*(pс+i*4+j) аналогично c[i][j] *(v+j) = min + max; SG2->Cells[j][0] = IntToStr(*(v+j)); } }

36

Работа с динамической памятью. Динамическое размещение массивов

Некоторые функции для выделения и освобождения памяти: malloc(s);

выделяет блок оперативной памяти длиной s байт и возвращает указатель на этот блок памяти.

При неудачном завершении возвращается значение NULL; calloc(n, m);

выделяет блок оперативной памяти для размещения n элементов по m байт каждый и возвращает

указатель на начало этой области памяти. При неудачном завершении возвращается значение

NULL; free(p);

освобождает ранее выделенный блок оперативной памяти, на который ссылается указатель p. Эта

область становится свободной для дальнейшего использования в других целях, а указатель p – не-

определенным (NULL), т. е. ни на что не ссылается; realloc(bl, ns);

изменить размер ранее выделенной памяти с адресом начала bl на ns байт.

При динамическом распределении памяти для массивов следует описать соответствующий

указатель и присваивать ему значение при помощи функций malloc или calloc. Два аналогичных

примера выделения памяти под одномерный массив a[10] из элементов типа:

float *a; a=(float*) malloc(10);

float *a; a=(float*)(calloc(10,sizeof(float));

Примеры создания двумерного массива a[n][m]:

Аналогичным образом можно распределить память и для трехмерных массивов.

Для иллюстрирования работы функции realloc приведем пример изменения размера ранее

выделенной памяти под одномерный массив из 10-ти вещественных элементов до 20-ти элемен-

тов: a = (float*) realloc(a, 20);

Следует только помнить, что ненужную для дальнейшего выполнения программы память

следует освобождать при помощи функции free, например: free(а);

Использование указателей совместно с вышеназванными функциями дает возможность

управлять распределением динамической памяти.

Задача 6.4 Разработать программу для ввода элементов вектора до 10-ти целых чисел и за-

менить в нем все четные элементы значением максимального элемента.

Текст функции и ее вызова в основной программе:

vect (int *a, int n) { int i, max = *a; for(i=1; i<n; i++) if(max < *(a+i)) max = *(a+i); for(i=0; i<n; i++) if(*(a+i)%2 == 0) *(a+i) = max; }

void __fastcall TForm1::Button3Click(TObject *Sender) { int i, n = Memo1->Lines->Count; int *a = (int*) malloc (n * sizeof(int)); for(i = 0; i < n; i++) a[i] = StrToInt(Memo1->Lines->Strings[i]); vect(a, n); Memo2->Clear(); for(i = 0; i < n; i++) Memo2->Lines->Add(IntToStr(a[i])); free(a); }

Задача 6.5 Разработать программу для ввода элементов матрицы вещественных чисел раз-

мерностью из 5-ти строк и 5-ти столбцов и вычисления вектора скалярных произведений столбцов

матрицы на ее неглавную диагональ.

int *p, n=3, m=5; p=(int*)malloc(n*m*sizeof(int));

int *p, n=3, m=5; p=(int*)calloc(n*m, sizeof(int));

37

Текст функции и ее вызова в основной программе:

fun(float *a, float *x) { for(int j=0;j<5;j++) { *(x+j)=0; for(int i=0;i<5;i++) *(x+j)+=(*(a+i*5+j))* *(a+i*5+4-i); // обращение *(a+i*5+j) эквивалентно a[i][j],

// *(a+i*5+4-i) эквивалентно a[i][4-i] – элементы // неглавной диагонали

} }

void __fastcall TForm1::Button1Click(TObject *Sender) { // выделить память для матрицы и вектора float *a = (float*)malloc(5*5*sizeof(float)); float *v = (float*)malloc(5*sizeof(float)); for(int i=0;i<5;i++) for(int j=0;j<5;j++)*(a+i*5+j)=StrToFloat(SG1->Cells[j][i]); fun(a, v); // вызов функции for(int i=0;i<5;i++) SG2->Cells[i][0]=FloatToStr(v[i]); free(a); free(v); // освободить память }

Задача 6.6 Разработать программу для ввода элементов матрицы вещественных чисел раз-

мерностью из 5-ти строк и 3-х столбцов и вычисления процентного содержания в ней положи-

тельных, отрицательных и нулевых элементов.

Функция может явно возвращать только один результат. В данном случае результатами яв-

ляются три числа, поэтому, чтобы не писать три функции для каждого из результатов, удобно пе-

редавать результаты по ссылке.

Текст функции и ее вызова в основной программе:

dinam(float *a,float &otr, float &pol, float &nul) { int i,j; otr=0;pol=0;nul=0; for(i=0;i<5;i++) for(j=0;j<3;j++) { if(*(a+i*3+j) < 0) otr++; if(*(a+i*3+j) > 0) pol++; if(*(a+i*3+j) == 0) nul++; } otr=otr/15.*100; pol=pol/15.*100; nul=nul/15.*100; }

void __fastcall TForm1::Button1Click(TObject *Sender) { float otr, pol, nul; float *a = (float*)malloc(5*3*sizeof(float)); for(int i=0; i<5; i++) for(int j=0; j<3; j++) *(a+i*3+j) = StrToFloat(SG1->Cells[j][i]); dinam(a, otr, pol, nul); Edit1->Text = FormatFloat("0.00", pol); Edit2->Text = FormatFloat("0.00", otr); Edit3->Text = FormatFloat("0.00", nul); free(a); }

38

Лабораторная работа № 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 Назовите известные Вам функции для работы с динамическим распределением памяти.

Лабораторное задание

1 Дать ответы на контрольные вопросы.

2 Указатели. Составить схемы алгоритмов, разработать проект формы и программы для вы-

полнения индивидуальных заданий, которые выбираются из таблиц предыдущих лабораторных

работ № 2.4 и № 2.5, согласно уровню сложности по указанию преподавателя. В проекте преду-

смотреть ввод исходных данных с клавиатуры и вывод полученных результатов на форму в ком-

поненты в головной программе, а обработку данных, т. е. все вычисления, организовать в функци-

ях с использованием указателей. Т. е. задание состоит в переделке уже существующих проектов

обработки одномерных и двумерных массивов таким образом, чтобы в головной программе оста-

лись операторы ввода/вывода данных, а все вычисления по выполнению индивидуального задания

организовать в функциях с использованием указателей (см. задачи 6.1…6.3).

3 Динамическое распределение памяти. Составить схемы алгоритмов, разработать проект

формы и программы для выполнения индивидуальных заданий, которые выбираются из таблиц

предыдущих лабораторных работ № 2.4 и № 2.5, согласно уровню сложности по указанию препо-

давателя. В проекте предусмотреть ввод исходных данных с клавиатуры и вывод полученных ре-

зультатов на форму в компоненты в головной программе, а обработку данных, т. е. все вычисле-

ния, организовать в функциях с использованием указателей и динамическим распределением па-

мяти под массивы. Т. е. задание состоит в переделке уже существующих проектов обработки од-

номерных и двумерных массивов таким образом, чтобы в головной программе остались операторы

ввода/вывода данных и динамического распределения памяти под массивы, а все вычисления по

выполнению индивидуального задания организовать в функциях с использованием указателей (см.

задачи 6.4…6.6).

Если по указанию преподавателя студентом уже было выполнено задание 2, то оно может

быть использовано для выполнения задания 3, т. е. следует только изменить объявления массивов,

используя функции выделения и освобождения динамической памяти.

4 Оформить протокол лабораторной работы и записать результаты работы проекта програм-

мы.

39

Дополнительная литература

1 Леонов Ю.Г., Силкина Н.В., Шпинова О.Д. Программирование на алгоритмическом

языке С++. Учеб. пособие с лабораторным практикумом. – Одесса: ОНАС, 2002. – 68 с.

2 Леонов Ю.Г., Угрік Л.М., Швайко І.Г. Збірник задач з програмування. – Одеса: УДАЗ,

1997. – 80 с.

3 Архангельский А.Я., Тагин М.А. Программирование в С++ Builder 6 и 2006. – М.: Би-

ном, 2007. – 1184 с.

4 Архангельский А.Я. Программирование в С++ Builder 5. – М.: Бином, 2000. – 1152 с.

5 Березин Б.Н., Березин С.Б. Начальный курс С и С++. – М.: Диалог-МИФИ, 2000. –

288 с.

6 Страуструп Б. Язык программирования С++. – СПб.-М.: Бином, 1999. – 991 с.

40

СОДЕРЖАНИЕ

Введение ................................................................................................................................................. 2

Структура модуля 2 ............................................................................................................................... 4

1 Организация циклических вычислений с помощью оператора цикла FOR................................. 5

Лабораторная работа № 2.1 Оператор цикла с параметром FOR ............................................... 7

2 Организация вычислений с использованием условных операторов цикла ................................ 10

Лабораторная работа № 2.2 Условные операторы цикла ....................................................... 13

3 Функции в С++ ................................................................................................................................. 15

Лабораторная работа № 2.3 Создание функций пользователя для организации

циклических вычислений ................................................................................................................... 18

4 Одномерные массивы ...................................................................................................................... 19

Лабораторная работа № 2.4 Обработка одномерных массивов ................................................. 21

5 Двумерные массивы......................................................................................................................... 25

Лабораторная работа № 2.5 Обработка двумерных массивов ................................................... 28

6 Указатели и динамическое управление памятью ......................................................................... 33

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

Работа с динамической памятью. Динамическое размещение массивов ....................................... 36

Лабораторная работа № 2.6 Указатели и динамическое управление памятью ........................ 38

Дополнительная литература .............................................................................................................. 39

Редактор И.В. Ращупкина