10 Указатели
.pdfint n; |
|
// Кількість елементів кожного з масивів |
|
double v[100], w[100]; |
// Масиви |
||
cout << "n = "; |
|
|
|
cin >> n; |
|
|
|
for (double *pt |
= v; pt < v + n; pt++) |
// Цикл зсуву |
|
{ |
// вказівника pt від першого елементу масиву v |
||
cout << "v[" |
<< pt - v << "] = "; |
// до останнього |
|
cin >> *pt; // з доступом до окремих елементів масиву |
|||
} |
|
// розіменуванням вказівника pt |
|
for (double *pt |
= w; pt < w + n; pt++) |
// Аналогічний |
|
{ |
|
|
// цикл для масиву w |
cout << "w[" |
<< pt - w << "] = "; |
|
|
cin >> *pt;
}
double d = 1;
//Вказівник ptv - на перший елемент масиву v,
//а вказівник ptw - на останній елемент масиву w for (double *ptv = v, *ptw = w + n - 1;
ptv < v + n; ptv++, ptw--)
d *= *ptv + *ptw; cout << "Result = " << d; cout << "\nPress any key"; _getch();
return 0;
}
//Поки ptv усередині масиву v
//Зсуваємо вказівники
//Доступ за адресами
Приклад 3. Дано натуральне число n ( n 20 ) і масив з n дійсних чисел. Вивести його вміст, починаючи з першого додатного елементу і закінчуючи останнім від’ємним (з урахуванням напряму перегляду при виведенні).
Розв’язок.
#include <iostream> using namespace std; int main()
{
int n;
double a[20], *Pt1 = NULL, *Pt2 = NULL;
cout << "n = "; |
|
cin >> n; |
|
for (int i = 0; i < n; i++) |
// Звичайне введення масиву |
{
cout << "a[" << i << "] = "; cin >> a[i];
}
11
for (int i = 0; i < n; i++) if (a[i] > 0)
{
Pt1 = &a[i]; // Pt1 отримує адресу першого break; // додатного елементу; завершуємо цикл
}
if (Pt1) // Перевірка умови Pt1 != NULL { // Якщо додатні елементи є, шукаємо останній з них
for (int i = n - 1; i >= 0; i--) if (a[i] > 0)
{
Pt2 = &a[i]; // Pt2 отримує адресу останнього break; // додатного елементу; завершуємо цикл
} |
|
if (Pt2) |
|
{ |
|
cout << |
"Result\n"; |
if (Pt2 |
> Pt1) |
|
// Нижче Pt1 сприймається як ім'я масиву, |
|
// що містить Pt2 - Pt1 + 1 елементів |
|
// зі звичайним індексуванням (від 0), |
|
// тобто ілюструється операція |
|
// індексування вказівника |
for |
(int i = 0; i < Pt2 - Pt1 + 1; i++) |
|
cout << Pt1[i] << '\t'; |
else |
// Тут вже Pt2 сприймається як ім'я |
// |
масиву, що містить Pt1 – Pt2 + 1 елементів |
for |
(int i = Pt1 - Pt2; i >= 0; i--) |
|
cout << Pt2[i] << '\t'; |
cout << |
endl; |
} |
|
else |
|
cout << |
"There are no negative numbers \n"; |
}
else
cout << "There are no positive numbers\n"; system("pause");
return 0;
}
Приклад 4. Дано натуральне число n ( n 100 ) і послідовність дійсних чисел a1 , a2 , …, an . Упорядкувати члени послідовності за незростанням методом «занурення» («камінчика»). Сутність методу полягає в наступному: для будь-якого значення k з ряду 1, 2, ..., n – 1 послідовно розглядаються всі члени
12
a j , j = 1, 2, ..., k, і при виконанні умови a j a j 1 члени a j |
і a j 1 міняються міс- |
цями з переходом до нового значення j незалежно від того, переставлялися числа чи ні.
Розв’язок.
#include <iostream>
using namespace std; int main()
{
int n;
double a[100], *Pt; cout << "n = ";
cin >> n;
for (int j = 0; j < n; j++) // Звичайне введення масиву
{
cout << "a[" << j + 1 << "] = "; cin >> a[j];
}
for (int k = 0; k < n - 1; k++)
{ |
|
// На кожному кроці вказівник |
Pt = a; |
// |
встановлюємо на початок масиву |
for (int j = 0; j < n - |
1 - k; j++) |
|
{ |
|
|
if (*Pt > *(Pt + 1))
{
double d = *(Pt + 1); *(Pt + 1) = *Pt;
*Pt = d;
} |
|
|
Pt++; |
// Зсув вказівника на один елемент |
|
} |
|
|
} |
|
|
cout << "Result\n"; |
|
|
for (int j = 0; j < n; j++) |
// Виведення масиву |
|
cout << "a[" << j + 1 << "] = " << a[j] << '\n'; system("pause");
return 0;
}
Приклад 5. Дано натуральні числа m, n ( m, n 100 ) і два впорядкованих за неубуванням дійсних масиви, які містять відповідно m і n елементів. Переписати вміст цих масивів у третій масив, забезпечивши неубування вмісту результуючого масиву.
13
Розв’язок.
#include <iostream>
using namespace std; int main()
{
int m, n;
double a[100], b[100], c[200]; cout << "Count of array a: "; cin >> m;
for (int j = 0; j < m; j++) // Звичайне введення масиву a
{
cout << "a[" << j << "] = "; cin >> a[j];
}
cout << "Count of array b: "; cin >> n;
for (int j = 0; j < n; j++) // Звичайне введення масиву b
{
cout << "b[" << j << "] = "; cin >> b[j];
}
double *p_a = a, *p_b = b, *p_c = c; for (int j = 0; j < m + n; j++)
{
if (p_a == a + m) // Чи досягнутий кінець масиву a?
{
*p_c = *p_b; |
|
// Нижче тричі замість трьох опе- |
p_b++; // раторів, подібних тим, що записані тут, |
||
p_c++; |
|
// використовується один оператор |
} |
|
|
else |
|
|
if (p_b == b |
+ n) |
// Чи вичерпався масив b? |
*p_c++ = |
*p_a++; |
|
else |
// Обидва масиви ще не вичерпалися |
|
if (*p_a |
< *p_b) |
|
*p_c++ = *p_a++;
else
*p_c++ = *p_b++;
}
cout << "Result\n";
for (int j = 0; j < m + n; j++) // Виведення масиву c cout << "c[" << j << "] = " << c[j] << '\n';
14
system("pause"); return 0;
}
Приклад 6. Дано натуральне число n ( n 100 ) і послідовність з n дійсних чисел. Знайти в ній найдовшу підпослідовність, що містить тільки додатні числа.
Розв’язок.
#include <iostream> using namespace std; int main()
{
int n;
double a[100];
cout << "Count of array a: "; cin >> n;
for (int j = 0; j < n; j++) // Звичайне введення масиву a
{
cout << "a[" << j << "] = "; cin >> a[j];
}
double *p_max = NULL, *p = a, *p1;
int Len = 0; // Початкова довжина підпослідовності while (true)
{
while (p |
< a + n && *p <= 0) |
// Пропускаємо недодатні |
|
p++; |
|
|
// числа |
p1 = p; |
// Запам’ятовуємо адресу першого додатного |
||
while (p |
< a + n && *p > 0) |
// Йдемо по додатним |
|
p++; |
|
|
|
if (p - p1 > Len) |
|
|
|
{ |
|
|
|
Len = p - p1; |
|
|
|
p_max = p1; |
|
|
|
} |
|
|
|
if (p == |
a + n) |
// Якщо вказівник вийшов за масив, |
|
break; |
// закінчуємо обробку масиву |
||
} |
|
|
|
cout << "Result:\n"; |
|
|
|
if (p_max) |
|
|
|
for (int |
j = 0; j < Len; j++) |
|
|
cout |
<< p_max[j] << '\t'; |
// Індексування від 0 |
|
else
cout << "There are no positive numbers";
15
cout << '\n'; system("pause"); return 0;
}
Приклад 7. Дано натуральне число n ( n 20 ), дійсне число w і масив з n дійсних чисел. Видалити з масиву елемент, що є найближчим до числа w.
#include <iostream>
using namespace std; int main()
{
int n;
double a[100], w;
cout << "Count of array a: "; cin >> n;
for (int j = 0; j < n; j++) // Звичайне введення масиву a
{
cout << "a[" << j << "] = "; cin >> a[j];
}
cout << "w = "; cin >> w;
double *p_res = &a[0];
double Len = fabs(w - *p_res);
for (double *p = a + 1; p < a + n; p++) if (fabs(w - *p) < Len)
{
Len = fabs(w - *p); p_res = p;
}
for (double *p = p_res + 1; p < a + n; p++) *(p - 1) = *p;
n--;
cout << "Result:\n"; if (n != 0)
for (double *p = a; p < a + n; p++) cout << *p << '\t';
else // У масиві був всього один елемент. Він видалений cout << "Empty";
cout << '\n'; system("pause");
}
16
3. ЗАВДАННЯ НА ЛАБОРАТОРНУ РОБОТУ
За час, відведений для виконання лабораторної роботи (2 академічні години), студент повинен:
1.Розробити алгоритм розв’язання задачі, запропонованої для програмування.
2.Здійснити програмну реалізацію розробленого алгоритму.
3.Здійснити налаштування програми, виправивши синтаксичні та логічні помилки.
4.Підібрати тестові дані для перевірки програми, включаючи виняткові випадки.
5.Оформити звіт до лабораторної роботи.
6.Відповісти на контрольні запитання.
7.Здати викладачу працездатну програму з демонстрацією її роботи на декількох варіантах вихідних даних.
4.ВАРІАНТИ ЗАДАЧ
1.Дано натуральне число n ( n 100 ) і послідовність дійсних чисел a1 , a2 , …, an . Отримати нову послідовність, вилучивши з первинної всі члени зі
значеннями, що відрізняються від середнього арифметичного не більш ніж на 10%. Для доступу до елементів масиву скористатися вказівниками.
2.Дано натуральне число n ( n 100 ) і цілі числа a1 , a2 , …, an . Якщо в послідовності прості й непрості числа чергуються між собою, то результатом повинна бути сама послідовність. У противному випадку видалити з послідовності прості числа, розмістивши елементи, що залишаться, в порядку, протилежному початковому. Для доступу до елементів масиву скористатися вказівниками.
3.Дано натуральне число n ( n 100 ) і послідовність дійсних чисел x1 , x2 , …,
xn . Якщо в результаті заміни від’ємних членів послідовності x1 , x2 , …, xn їхніми квадратами члени нової послідовності будуть утворювати незростальну послідовність, то одержати добуток членів первинної послідовності; у противному випадку одержати їхню суму. Для доступу до елементів масиву скористатися вказівниками.
4. Дано натуральне число n ( n 100 ) і послідовність дійсних чисел r1 , r2 , …, rn . Розвернути найкоротшу підпослідовність, яка містить тільки додатні числа. Для доступу до елементів масиву скористатися вказівниками.
5.Дано натуральне число n ( n 100 ) і масив з n дійсних чисел. Визначити в цьому масиві кількість ділянок, на яких його елементи убувають. Для доступу до елементів масиву скористатися вказівниками.
17
6. Дано натуральне число n ( n 100 ) і послідовність дійсних чисел r1 , |
r2 , …, |
||
rn , серед яких обов’язково є як від’ємні, так і невід’ємні. Отримати |
x1 |
y1 |
|
x2 y2 |
xs ys , де x1 , x2 , …, x p від’ємні члени послідовності r1 |
, r2 , |
|
…, rn , |
розглянуті в порядку їх проходження, y1 , y2 , …, yq невід’ємні |
||
члени, узяті в зворотному порядку, s min ( p, q). Для доступу до елементів масиву скористатися вказівниками.
7.Дано натуральне парне число n ( n 100 ) і послідовність цілих чисел a1 , a2 , …, an / 2 . Отримати нову послідовність, вставивши в первинну після кожного парного числа його квадрат. Для доступу до елементів масиву скористатися вказівниками.
8.Дано натуральне число n ( n 100 ). Одержати всі прості числа, що не перевищують це значення. Для прискорення обчислень при перевірці поточного числа на його простоту можна використати раніше знайдені прості числа. Для доступу до елементів масиву скористатися вказівниками.
9.Дано натуральне число n ( n 100 ) і дійсні числа x1 , x2 , …, xn . Знайти номер найменшого додатного числа в заданій послідовності. Якщо в послідовності x1 , x2 , …, xn відсутні додатні числа, результатом повинен бути
вказівник зі значенням NULL. Для доступу до елементів масиву скористатися вказівниками.
10. Дано натуральне числа n ( n 100 ) і послідовність цілих чисел a1 , a2 , …, an . Поміняти місцями в цій послідовності найбільший і найменший члени. Якщо в послідовності декілька найбільших або найменших елементів, то розглядати останні з таких. Для доступу до елементів масиву скористатися вказівниками.
11.Дано натуральне число n ( n 100 ) і масив з n дійсних чисел. Кожен елемент цього масиву замінити середнім арифметичним всіх передуючих йому елементів, включаючи його самого. Для доступу до елементів масиву скористатися вказівниками.
12.Дано натуральне число n ( n 100 ) і послідовність з n дійсних чисел. Вивести всі члени послідовності, починаючи з максимального члена і закінчуючи мінімальним, поза залежністю від їх взаємного розташування (завжди першим повинен виводитись максимальний член, а останнім – мінімальний). Для доступу до елементів масиву скористатися вказівниками.
13. Дано натуральне число n ( n 100 ) і цілі числа a1 , a2 , …, an . З’ясувати, чи є серед чисел a1 , a2 , …, an співпадаючі. Для доступу до елементів масиву скористатися вказівниками.
14.Дано масив з n цілих чисел, де n – задане натуральне число ( n 100 ). Сформувати новий масив, що містить тільки ті елементи первинного маси-
18
ву, які є простими числами. Для доступу до елементів масиву скористатися вказівниками.
15.Дано натуральне число n ( n 10 ) і цілі числа a1 , a2 , …, a3n . З’ясувати, чи правда, що для всіх an 1 , an 2 , …, a3n є рівні серед a1 , a2 , …, an . Для доступу до елементів масиву скористатися вказівниками.
16.Дано натуральне число n ( n 100 ) і послідовність відмінних від нуля цілих чисел a1 , a2 , …, an . Якщо в послідовності числа з різними знаками чер-
гуються, вивести початкову послідовність. У противному випадку видалити з послідовності всі додатні члени. Для доступу до елементів масиву скористатися вказівниками.
17. Дано натуральне число n ( n 100 ) і послідовність цілих чисел a1 , a2 , …, an . Одержати нову послідовність, вилучивши з первинної послідовності всі члени зі значенням min(a1 , a2 , , an ) . Для доступу до елементів масиву скористатися вказівниками.
18.Дано натуральне число n ( n 100 ) і масив з n цілих чисел. Знайти найменше натуральне число, відсутнє в масиві. Для доступу до елементів масиву скористатися вказівниками.
19.Дано натуральне число n ( n 100 ) і послідовність дійсних чисел a1 , a2 , …,
an . Залишити без зміни послідовність a1 , a2 , …, an , якщо вона впорядкована за неубуванням або незростанням; у противному випадку видалити з неї ті члени, порядкові номери яких кратні шести, зберігши порядок членів, що залишилися. Для доступу до елементів масиву скористатися покажчиками.
20.Дано натуральне число n ( n 100 ) і масив дійсних чисел a1 , a2 , …, an . Упорядкувати цей масив за неубуванням. Скористатися таким методом. Знайти найменший елемент масиву і переставити його місцями з першим елементом, потім серед елементів масиву, починаючи з другого, знайти найменший і переставити його з другим і т. д. Для доступу до елементів масиву скористатися вказівниками.
21.Дано натуральне число n ( n 100 ) і цілі числа a1 , a2 , …, an . Якщо в послідовності a1 , a2 , …, an жодне парне число не розташоване після непарного, то одержати нову послідовність з усіх від’ємних членів вихідної послідовності. У противному випадку в нову послідовність вмістити всі додатні числа з послідовності a1 , a2 , …, an . В обох випадках порядок проходження чисел замінити на зворотний. Для доступу до елементів масиву ско-
ристатися вказівниками.
22. Дано натуральне число n ( n 100 ), ціле число m і масив з n цілих чисел. Чи міститься число m у масиві? Відповіддю повинен бути вказівник на
19
знайдений елемент при позитивній відповіді і значення NULL – при негативній. Для доступу до елементів масиву скористатися вказівниками. Для доступу до елементів масиву скористатися вказівниками.
23.Дано натуральне число n ( n 100 ), ціле число k ( k 1) і послідовність ці-
лих чисел a1 , a2 , …, an . Здійснити циклічний зсув елементів послідовності на 1 позицію вправо (при k 1) або вліво (при k 1). Для доступу до елементів масиву скористатися вказівниками.
24.Дано натуральне число n ( n 100 ) і дійсні числа a1 , a2 , …, an . Переста-
вити члени послідовності a1 , a2 , …, an так, щоб спочатку розташувалися всі її невід’ємні члени, а потім всі від’ємні. Зберегти початковий порядок, як серед всіх невід’ємних членів, так і серед від’ємних. Для доступу до елементів масиву скористатися вказівниками.
25.Дано натуральне число n ( n 100 ) і послідовність дійсних чисел a1 , a2 , …, an . Якщо послідовність не впорядкована ні за зростанням, ні за убуванням,
то впорядкувати її так, щоб спочатку йшли за неубуванням усі додатні елементи, потім також за неубуванням усі від’ємні елементи, а наприкінці – усі нулі. Для доступу до елементів масиву скористатися вказівниками.
5.КОНТРОЛЬНІ ЗАПИТАННЯ
1.Яка операція використовується для отримання адреси змінної?
2.Що таке вказівник?
3.Поясніть концепцію вказівників у C++. Урахуйте той факт, що об’єкти різних типів займають різний обсяг пам’яті.
4.Яка операція дозволяє отримати значення, записане за адресою, що міститься у вказівнику?
5.У чому відмінність між адресою, яка зберігається у вказівнику, і значенням, записаним за цією адресою?
6.У чому різниця між операцією розіменування і операцією отримання адреси?
7.У чому різниця між такими оголошеннями: const int *ptrOne й int * const ptrTwo?
8.Поясніть сенс таких оголошень змінних:
int * pOne; int vTwo;
int * pThree = &vTwo;
9.Вказівники pt1 і pt2 мають той самий базовий тип. Що можна сказати стосовно виразу pt1 + pt2?
10.Опишіть особливості операції віднімання для двох вказівників.
20
