Здавалка
Главная | Обратная связь

Завдання на лабораторну роботу

Теоретичні основи

Загальні відомості про вказівники

У мові C для виділення динамічної пам’яті та її вивільнення використовуються функції calloc(), malloc(), realloc() і free(), заголовки (прототипи) яких описані в заголовковому файлі alloc.h:

void *calloc(unsigned n, unsigned m) – повертає вказівник на початок ділянки динамічної пам’яті для розміщення n елементів по m байт кожен або NULL при невдалому виділенні;

void *malloc(unsigned s) – повертає вказівник на блок динамічної пам’яті довжиною s байт або NULL;

void *realloc(void *bl, unsigned ns) – змінює розмір виділеної динамічної пам’яті з адресою початку bl до розміру ns байт або NULL. Якщо bl == NULL, то функція працює як malloc();

void free(void *bl) – звільнює раніше виділений блок динамічної пам’яті з адресою першого байта bl.

Треба пам’ятати, що функції динамічного розподілу пам’яті мають тип void *. Це обумовлює необхідність приведення типу при зв’язуванні виділе­ної пам’яті з конкретним вказівником:

#include<alloc.h>
//. . .
char *pchar;
long *plong;
int n=10;
// ...
// Виділення 256 байт під символьний масив
pchar = (char *)malloc(256);
// Виділення пам’яті під масив з n елементів
plong = (long *)calloc(n, sizeof(long)); // типу long
// ...
free(pchar); // Вивільнення пам’яті, що зв’язана з
// вказівником pchar
free(plong); // Вивільнення пам’яті, що зв’язана з
// вказівником plong

На відміну від імені масиву звичайний вказівник може змінювати своє значення. Однак у цьому випадку можна загубити можливість правильного вивільнення пам’яті. Справа в тому, що після розподілу пам’яті вказівник зв’язується з першим байтом виділеної ділянки пам’яті. Якщо ж вказівник змінює своє значення, то вивільнення пам’яті з початку виділеної ділянки стає неможливим. Тому завжди необхідно зберігати адресу початку виділеної ділянки пам’яті.

Важливим моментом є необхідність перевірки правильності виділення пам’яті. Для цього необхідна перевірка значення вказівника після розподілення пам’яті. Наприклад,

if (pchar != NULL) ...

або

if (pchar) ...

У мові C++ існує операція

new ім’я_типу

або

new ім’я_типу ініціалізатор

яка дозволяє виділити ділянку динамічної пам’яті, розмір якої відповідає типу даних, що визначається іменем типу. Ініціалізатор задається виразом у круглих дужках. Якщо пам’ять не може бути виділена, то операція new повертає значення NULL.

Вивільнення пам’яті в мові C++ здійснюється операцією

delete вказівник;

Якщо вивільнюється пам’ять, що виділялася під масив, то операція delete має такий формат:

delete [] вказівник;

У програмі може бути визначений як звичайний вказівник, так і вказівник на масив.

Наприклад,

long *plong; // Вказівник на тип long

long (*plarray)[3][2]; // Вказівник на масив 3х2

Ці вказівники можуть бути зв’язані як з об’єктами статичної пам’яті, так і з об’єктами динамічної пам’яті.

Приклади програм

Приклад 1. Дано натуральне число n і масив з n цілих чисел ( ). Чи правда, що вміст масиву однаково читається в прямому і зворотному напрям­ках?

Розв’язок.

#include <iostream>
}

Приклад 2. Дано натуральне число ( ) і дійсні числа , , …, , , , …, . Обчислити .

Розв’язок.

#include <iostream>
}

Приклад 3. Дано натуральне число n ( ) і масив з n дійсних чисел. Вивести його вміст, починаючи з першого додатного елемента і закінчуючи останнім від’ємним (з урахуванням напряму перегляду при виведенні).

Розв’язок.

#include <iostream>
}

Приклад 4. Дано натуральне число n ( ) і послідовність дійсних чисел , , …, . Упорядкувати члени послідовності за незростанням мето­дом «занурення» («камінчика»). Сутність методу полягає в наступному: для будь-якого значення k з ряду 1, 2, ..., n – 1 послідовно розглядаються всі члени , j = 1, 2, ..., k, і при виконанні умови члени і міняються міс­цями з переходом до нового значення j незалежно від того, переставлялися числа чи ні.

Розв’язок.

#include <iostream>
}

Приклад 5. Дано натуральні числа m, n ( ) і два впорядкованих за неубуванням дійсних масиви, які містять відповідно m і n елементів. Пере­писати вміст цих масивів у третій масив, забезпечивши неубування вмісту ре­зультуючого масиву.

Розв’язок.

#include <iostream>
}

Приклад 6. Дано натуральне число ( ) і послідовність з n дійс­них чисел. Знайти в ній найдовшу підпослідовність, що містить тільки додатні числа.

Розв’язок.

#include <iostream>
}

Приклад 7. Дано натуральне число n ( ), дійсне число w і масив з n дійсних чисел. Видалити з масиву елемент, що є найближчим до числа w.

#include <iostream>
}

Завдання на лабораторну роботу

За час, відведений для виконання лабораторної роботи (2 академічні години), студент повинен:

1. Розробити алгоритм розв’язання задачі, запропонованої для програ­мування.

2. Здійснити програмну реалізацію розробленого алгоритму.

3. Здійснити налаштування програми, виправивши синтаксичні та ло­гічні помилки.

4. Підібрати тестові дані для перевірки програми, включаючи ви­нят­кові випадки.

5. Оформити звіт до лабораторної роботи.

6. Відповісти на контрольні запитання.

7. Здати викладачу працездатну програму з демонстрацією її робо­ти на декількох варіантах вихідних даних.

Варіанти задач

1. Дано натуральне число ( ) і послідовність дійсних чисел , , …, . Отримати нову послідовність, вилучивши з первинної всі члени зі значеннями, що відрізняються від середнього арифметичного не більш ніж на 10%. Для доступу до елементів масиву скористатися вказівниками.

2. Дано натуральне число ( ) і цілі числа , , …, . Якщо в по­слідовності прості й непрості числа чергуються між собою, то результатом повинна бути сама послідовність. У противному випадку видалити з послі­довності прості числа, розмістивши елементи, що залишаться, в порядку, протилежному початковому. Для доступу до елементів масиву скористатися вказівниками.

3. Дано натуральне число ( ) і послідовність дійсних чисел , , …, . Якщо в результаті заміни від’ємних членів послідовності , , …, їхніми квадратами члени нової послідовності будуть утворювати незрос­тальну послідовність, то одержати добуток членів первинної послі­довності; у противному випадку одержати їхню суму. Для доступу до елементів масиву скористатися вказівниками.

4. Дано натуральне число ( ) і послідовність дійсних чисел , , …, . Розвернути найкоротшу підпослідовність, яка містить тільки додатні числа. Для доступу до елементів масиву скористатися вказівниками.

5. Дано натуральне число ( ) і масив з дійсних чисел. Визначити в цьому масиві кількість ділянок, на яких його елементи убувають. Для доступу до елементів масиву скористатися вказівниками.

6. Дано натуральне число ( ) і послідовність дійсних чисел , , …, , серед яких обов’язково є як від’ємні, так і невід’ємні. Отримати де , , …, - від’ємні члени послідовності , , …, , розгля­нуті в порядку їх проходження, , , …, - невід’ємні члени, взяті в зворот­ному порядку, Для доступу до елементів масиву скористатися вказівниками.

7. Дано натуральне парне число ( ) і послідовність цілих чисел , , …, . Отримати нову послідовність, вставивши в первинну після кож­ного парного числа його квадрат. Для доступу до елементів масиву скорис­татися вказівниками.

8. Дано натуральне число ( ). Одержати всі прос­ті числа, що не пере­вищують це значення. Для прискорення обчислень при перевірці поточного числа на його простоту можна використати раніше знайдені прості числа. Для доступу до елементів масиву скористатися вказівниками.

9. Дано натуральне число ( ) і дійсні числа , , …, . Знай­ти номер найменшого додатного числа в заданій послідовності. Якщо в по­слідовності , , …, відсутні додатні числа, результатом повинен бути вказівник зі значенням NULL. Для доступу до елементів масиву скориста­тися вказівниками.

10. Дано натуральне числа ( ) і послідовність цілих чисел , , …, . Поміняти місцями в цій послідовності найбільший і найменший чле­ни. Якщо в послідовності декілька найбільших або найменших елементів, то розглядати останні з таких. Для доступу до елементів масиву скористатися вказівниками.

11. Дано натуральне число ( ) і масив з дійсних чисел. Кожен еле­мент цього масиву замінити середнім арифметичним всіх передуючих йому елементів, включаючи його самого. Для доступу до елементів масиву ско­ристатися вказівниками.

12. Дано натуральне число ( ) і послідовність з дійсних чисел. Ви­вести всі члени послідовності, починаючи з максимального члена і за­кін­чуючи мінімальним, поза залежністю від їх взаємного розташування (завжди першим повинен виводитись максимальний член, а останнім – мі­німальний). Для доступу до елементів масиву скористатися вказівниками.

13. Дано натуральне число ( ) і цілі числа , , …, . З’ясу­вати, чи є серед чисел , , …, співпадаючі. Для доступу до елементів масиву скористатися вказівниками.

14. Дано масив з n цілих чисел, де n – задане натуральне число ( ). Сформувати новий масив, що містить тільки ті елементи первинного ма­си­ву, які є простими числами. Для доступу до елементів масиву скористатися вказівниками

15. Дано натуральне число ( ) і цілі числа , , …, . З’ясу­вати, чи правда, що для всіх , , …, є рівні серед , , …, . Для досту­пу до елементів масиву скористатися вказівниками.

16. Дано натуральне число ( ) і послідовність відмінних від нуля ці­лих чисел , , …, . Якщо в послідовності числа з різними знаками чер­гуються, вивести початкову послідовність. У противно­му ви­­падку виклю­чити з послідовності всі додатні члени. Для доступу до еле­ментів масиву скористатися вказівниками.

17. Дано натуральне число ( ) і послідовність цілих чи­сел , , …, . Одержати нову послідовність, вилучивши з первинної послідов­но­сті всі члени зі значенням . Для доступу до елементів масиву ско­ристатися вказівниками.

18. Дано натуральне число ( ) і масив з цілих чисел. Знайти най­менше натуральне число, відсутнє в масиві. Для доступу до елементів масиву скористатися вказівниками.

19. Дано натуральне число ( ) і послідовність дійсних чисел , , …, . Залишити без зміни послідовність , , …, , якщо вона впо­­рядко­вана за неубуванням або незростанням; у противному випадку ви­­да­лити з неї ті члени, порядкові номери яких кратні шести, зберігши поря­­док членів, що залишилися. Для доступу до елементів масиву скористатися вказів­ни­ками.

20. Дано натуральне число ( ) і масив дійсних чисел , , …, . Упорядкувати цей масив за неубуванням. Скористатися таким ме­то­дом. Знайти найменший елемент масиву і переставити його місцями з першим еле­ментом, потім серед елементів масиву, починаючи з другого, знайти най­­менший і переставити його з другим і т. д. Для доступу до елементів масиву скорис­татися вказівниками.

21. Дано натуральне число ( ) і цілі числа , , …, . Якщо в по­слі­довності , , …, жодне парне число не розташоване після непар­­ного, то одержати нову послідовність з усіх від’ємних членів вихідної по­слі­довності. У противному випадку в нову послідовність вмістити всі дода­тні числа з послідовності , , …, . В обох ви­пад­ках порядок проход­ження чисел замінити на зворотний. Для доступу до елементів ма­сиву ско­ристатися вказівниками.

22. Дано натуральне число ( ), ціле число і масив з цілих чи­сел. Чи міститься число у масиві? Відповіддю повинен бути вказівник на знайдений елемент при позитивній відповіді і значення NULL – при нега­тивній. Для доступу до елементів масиву скористатися вказівниками. Для доступу до елементів масиву ско­ристатися вказівниками.

23. Дано натуральне число ( ), ціле число k і послідовність ці­лих чи­сел , , …, . ціле число k ( ) і послідовність ці­лих чи­сел , , …, . Здійснити циклічний зсув елементів послідов­ності на 1 позицію вправо (при ) або вліво (при ). Для доступу до елементів масиву ско­рис­татися вказів­ни­ками.

24. Дано натуральне число ( ) і дійсні числа , , …, . Пере­­ста­вити члени послідовності , , …, так, щоб спочатку розташу­­валися всі її невід’ємні члени, а потім всі від’ємні. Зберегти початковий порядок, як серед всіх невід’ємних членів, так і се­ред від’ємних. Для доступу до еле­ментів масиву скористатися вказівниками.

25. Дано натуральне число ( ) і послідовність дійсних чисел , , …, . Якщо послідовність не впорядкована ні за зростанням, ні за убуванням, то впорядкувати її так, щоб спочатку йшли за неубуванням всі додатні еле­менти, потім також за неубуванням все від’ємні елементи, а наприкінці – усі нулі. Для доступу до елементів масиву скористатися вказівниками.

5. Контрольні запитання

26. Яка операція використовується для отримання адреси змінної?

27. Що таке вказівник?

28. Поясніть концепцію вказівників у C++. Урахуйте той факт, що об’єкти різ­них типів займають різний обсяг пам’яті.

29. Яка операція дозволяє отримати значення, записане за адресою, що міс­титься у вказівнику?

30. У чому відмінність між адресою, яка зберігається у вказівнику, і значенням, записаним за цією адресою?

31. У чому різниця між операцією розіменування і операцією отримання ад­реси?

32. У чому різниця між такими оголошеннями: const int *ptrOne й int * const ptrTwo?

33. Поясніть сенс таких оголошень змінних:

int * pOne;
int vTwo;
int * pThree = &vTwo;

34. Вказівники pt1 і pt2 мають той самий базовий тип. Що можна сказати стосовно виразу pt1 + pt2?

35. Опишіть особливості операції віднімання для двох вказівників.

36. Як виконуються операція віднімання числа з вказівника?

37. Що є результатом при виконанні підсумовування вказівника і числа?

38. Як виконуються операції ++ і --, застосовані до вказівників?

39. Опишіть особливості вказівника на тип void.

40. Як виконується операція індексування вказівника?

41. Опишіть особливості вказівників, що описуються з модифікатором const.

42. Опишіть особливості імені масиву як вказівника.

43. Нехай у програмі оголошена змінна yourAge типу unsigned int. Як описати вказівник, який дозволить маніпулювати цією змінною?

44. Поясніть, яка помилка може приховуватися в наведеному нижче оголо­шенні змінних:

int * int_ptr1, int_ptr2;

45. За допомогою вказівника здійсніть присвоювання змінній yourAge зна­чення 17.

46. Напишіть невеличку програму і опишіть у ній змінну типу int і вказівник на цей тип. Збережіть адресу цієї змінної у вказівнику. Використовуючи вказівник, здійсніть присвоювання цій змінній деякого значення.

47. Яким буде виведення при виконанні наведеного нижче фрагменту коду?

int *p1, *p2;
*pInt = 7;
cout << "The value at pInt: " << pInt;

48. Маємо таку програму:

#include <iostream>
using namespace std;
int main()
{
int pInt;
*pInt = 7;
cout << "The value at pInt: " << *pInt << '\n';
system("pause");
return 0;
}

Чи є помилки в цій програмі? У разі позитивної від­повіді зробіть пояснення.

49. Маємо таку програму:

#include <iostream>
using namespace std;
int main()
{
int SomeVariable = 9;
cout << "SomeVariable: " << SomeVariable << '\n';
int *pVar = &SomeVariable;
*pVar = 7;
cout << "SomeVariable: " << *pVar << '\n';
system("pause");
return 0;
}

Чи є помилки в цій програмі? У разі позитивної від­повіді зробіть пояснення.

50. У програмі зустрілась така послідовність операторів:

double a[100];
double i;
for (i = 0; i < 100; i++)
a[i] = i;

Чи є помилки в наведеному вище фрагменті програмного коду? У разі позитивної від­повіді зробіть пояснення.

51. У програмі зустрілась така послідовність операторів:

double a[100];
char i;
for (i = 0; i < 100; i++)
a[i] = i;

Чи є помилки в наведеному вище фрагменті програмного коду? Зро­біть пояснення.

52. У програмі зустрілась така послідовність операторів:

double a[100], *pt = a;
pt = -1.221;

Чи є помилки в наведеному вище фрагменті програмного коду? Зро­біть пояснення.

53. У програмі зустрілась така послідовність операторів:

double a[10], *pt;
for (int i = 9; i > 0; i--)
*(pt + i) = i;

Чи є помилки в цьому коді? Зробіть пояснення.

54. У програмі зустрілась така послідовність операторів:

double a[100], *pt = a;
*pt = true;

Чи є помилки в наведеному вище фрагменті програмного коду? Зро­біть пояснення.

55. У програмі зустрілась така послідовність операторів:

bool a[10], *p_a = a, b[10], *p_b = b;

Для переписування вмісту масиву a в масив b використаний такий оператор:

for (int i = 0; i < 10; i++)
for (int j = i; j < i + 1; j++)
*(p_b + i) = *p_a + j;

Чи є помилки в наведених вище фрагментах програмного коду? Зро­біть пояснення.

56. Маємо ті ж визначення, що й у попередньому запитанні. Нижче наведений оператор подвійного циклу. Що можна сказати про нього?

for (int i = 0; i < 10; i++)
for (int j = 0; j <= i; j++)
*(p_b + i) = *(a + j);

Список літератури

57. Страуструп, Б. Язык программирования Си++ : Второе издание / Б. Страуструп. – К. : ДиаСофт, 1993. – Ч. 1. – 264 с. ; Ч. 2. – 296 с.

58. Керниган, Б. Язык программирования Си / Б. Керниган, Д. Ритчи. – М. : Финансы и статистика, 1992. – 272 с.

59. Либерти, Джесс. Освой самостоятельно С++ за 21 день : учеб. пособ. / Джесс Либерти. – М. : Вильямс, 2001. – 816 с.

60. Подбельский, В. В. Программирование на языке Си / В. В. Подбельский, С. С. Фомин. – М. : Финансы и статистика, 1999. – 600 с.

61. Подбельский, В. В. Язык Си++ / В. В. Подбельский. – М. : Финансы и ста­тистика, 1999. – 560 с.

62. Савитч, Уолтер. Язык C++. Курс объектно-ориентиро­ван­ного програм­мирования / Уолтер Савитч. – М. : Вильямс, 2001. – 704 с.


 

 

Навчальне видання

 

Методичні вказівки

до лабораторної роботи
«Використання вказівників у програмах мовою C++»

з курсу «Програмування» для студентів напряму 6.040302 – Інформатика
і курсу «Програмування та алгоритмічні мови» для студентів напряму
6.040303 – Системний аналіз

 

 

Укладачі: БЕЗМЕНОВ Микола Іванович,

БЕЗМЕНОВА Ольга Миколаївна

 

 

Відповідальний за випуск О. С. Куценко

Роботу до видання рекомендував О. В. Горелий

 

 

За авторською редакцією

 

План 2013 р., поз. 11/41–13

 

Підписано до друку __.__.2013 р. Формат 60´84 1/16. Папір офсетний.

Друк – ризографія. Гарнітура Таймс. Ум. друк. арк. _______.

Обл.-вид. арк. 1,0. Тираж 50 прим. Зам. №___ . Ціна договірна.

________________________________________________________________________________________________________________________

Видавничий центр НТУ «ХПІ».

Свідоцтво про державну реєстрацію ДК№ 116 від 10.07.2000 р.

61002, Харків, вул. Фрунзе, 21.

________________________________________________________________________________________________________________________

Друкарня НТУ «ХПІ»

61002, Харків, вул. Фрунзе, 21.





©2015 arhivinfo.ru Все права принадлежат авторам размещенных материалов.