Смекни!
smekni.com

Мова програмування С++ (стр. 4 из 7)

while (умова)

{< оператори>

if (<вираз-умова>) break;

<оператори>}.

Тобто оператор break доцільно використовувати, коли умову продовження ітерації потрібно перевіряти в тілі циклу.

2) continue – припинення поточної і перехід до наступної ітерації циклу. Використовується, коли тіло циклу містить розгалуження.

3) return – здійснює повернення результату з тіла функції.


5. Вказівники та операції над ними

5.1 ПОНЯТТЯ ВКАЗІВНИКА

Кожна змінна у програмі - це об’єкт, який володіє ім’ям і значенням. Після визначення змінної з ініціалізацією всі звернення у програмі до неї за іменем замінюються компілятором на адресу іменованої області оперативної пам’яті, в якій зберігається значення змінної (Рис. 5.1). Програміст може визначити власні змінні для збереження адрес областей пам’яті. Такі змінні називають вказівниками.

int a=10;


Рис. 5.1.

Вказівник визначається наступним чином:

<тип>*<ідентифікатор><ініціалі затор>;

Приклад 1.Визначення вказівників

int* pa=&a;// вказівник ра містить значення адреси змінної а

float *ptr (NULL); // Нульовий вказівник на об’єкт типу float

char*p; // Неініціалізований вказівник на об’єкт типу char

Значення адреси змінної одержується за допомогою унарної операції ”&”.

Для доступу до комірки пам’яті, виділеної під змінну через вказівник до останнього, слід застосувати унарну операцію розіменування ”*”.

Приклад 2. Непряма адресація через вказівник

int x=2; //змінна типу int

int *y =&x;// вказівник на елемент даних типу int

*y=1; // через вказівник до поля x вноситься значення 1,

//тобто x=1

p=new char(12);

В останньому операторі прикладу 2 неініціалізований вказівник р, описаний у прикладі 1, асоціюється з ділянкою у динамічній пам’яті під змінну типу char, до якої заноситься значення 12.

5.2 ДІЇ НАД ВКАЗІВНИКАМИ

Приклад 3: Дії над вказівниками

int a=5;

int *p=&a, *p2, *p2; p2=p1=p;

++p1; p2+=2;

cout<<“a=”<<a;

cout<<” p=”<<*p<<” p=”<<p<<” p1=”<<p1<<” p2=”<<p2;

Результат виконання:

a=5, *p=5, p=FFC8, p1=FFCC, p2=FFD0.

Конкретні значення адрес залежать від низки причин: архітектури комп’ютера, типу і розміру оперативної пам’яті тощо.

З арифметичних операцій між вказівниками дозволена лише операція віднімання.

Різницею двох вказівників одного типу є відстань між двома областями пам’яті, кратна довжині (в байтах) об’єкта того типу, якому відповідає вказівник. Різниця однотипних вказівників, що адресують суміжні об’єкти, за абсолютною величиною рівна одиниці. Адреси змінних позначаються цілочисельними 16-ковими константами.

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

До вказівника дозволено додавати і віднімати цілочисельну константу (k). При цьому він пересувається між ділянками пам’яті на величину k*(sizeof(type)).

6. Робота з одновимірними масивами

6.1 СТАТИЧНІ ТА ДИНАМІЧНІ МАСИВИ

Масив – це кінцева послідовність даних одного типу. Кожен елемент масиву має однакове ім’я – ім’я масиву, і відрізняється індексом (ціле число), за яким здійснюється доступ до елемента масиву. Індекси масивів у С/С++ починаються з 0. У програмі одновимірний масив оголошується наступним чином:

<тип> <ім’я масиву> [розмір] <ініціалізація>; ,

де розмір – кількість елементів одновимірного масиву.

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

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

Наприклад:

- оголошення одновимірного масиву з п’яти елементів цілого типу:

int a[5];

- динамічне виділення пам’яті під 10 цілочисельних елементів:

int*m=new int [10];

Враховуючи те, що ім¢я масиву є вказівником, зрозумілим стає зміст останньої операції: вказівникові на int m присвоюється початкова адреса ділянки пам¢яті, виділеної у динамічній області під 10 цілочисельних елементів.

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

Натомість ініціалізацію статичних масивів можна здійснювати при їх визначенні. При цьому слід зауважити, що у С/С++ не перевіряється вихід індексу за межі масиву.

Наприклад:

double d[] = {1, 2, 3, 4, 5};

float f[10]={1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.0};

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

Для звернення до елементів масивів використовуються два способи, наприклад до 4-го (по порядку) елемента масиву a можна звернутися як a[3] або *(a+3). Останнє звернення базується на факті, що ім’я масиву є одночасно вказівником на його нульовий елемент, а зміщення вказівника у пам’яті відбувається на величину індексу помножену на розмір типу елементів масиву у байтах.

Пам’ять, зарезервовану під динамічний масив за допомогою new[ ], потрібно звільняти оператором delete [] <ім¢я массиву>.

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

6.2 РЯДКИ, ЯК ОДНОВИМІРНІ МАСИВИ СИМВОЛІВ

У мовах С/С++ немає окремого типу даних “рядок символів”, подібно до типу string у алгоритмічній мові PASCAL. Тому робота з рядками реалізована шляхом використання одновимірних масивів типу char. Рядок символів – це одновимірний масив типу char, останнім елементом якого є нульовий байт. Нульовий байт – це байт, кожен біт якого рівний нулю, при цьому для нульового байта визначена символьная константа ¢&bsol;0¢ (ознака закінчення рядка або нуль-термінатор). Тому, якщо рядок містить k символів, в описі масиву потрібно вказати розмірність k+1.

Так, для збереження у масиві рядкової константи “Лабораторна робота з рядками”, необхідно описати масив char s[29]. В кінці рядкової константи символ ´ &bsol;0¢ вказувати не потрібно, оскільки це зробить компілятор мови С.

Рядки можна

а) ініціалізувати при декларуванні.

Наприклад:

charS1[10]=”123456789”,S2[]=”abcdefg”,S3[]={‘1’,‘2’,‘3’,‘&bsol;0’};,

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

б) вводити з клавіатури, не використовуючи при цьому оператора циклу, подібно звичайним масивам.

Наприклад:

char Tоріс[20];

cout<<”Введіть тему лабораторної роботи:&bsol;n”; cin>>Tоріс;

7. Двовимірні масиви

Крім одновимірних масивів у С/С++ можливо працювати з багатовимірними масивами, а найчастіше з двовимірними матрицями. Двовимірний масив – це масив, що складається з окремих одновимірних масивів у вигляді рядків, розмірність яких рівна кількості стовпців матриці. Для цього при визначенні двовимірного масиву у квадратних дужках вказується дві розмірності. Оператор опису двовимірного масиву має вигляд:

<тип> <ім’я> [<розмір1>][<розмір2>];

Наприклад:

int a[3][5]; // Цілочисельна матриця з 3 рядків і 5 стовпців

Масив зберігається у неперервній області пам’яті по рядках, які зберігаються послідовно один за одним, а не у вигляді звичної з матики матриці:

a00 a01 a02 a03 a04 a10 a11 a12 a13 a14 a20 a21 a22 a23 a24

| -0-ий рядок- - |-- 1-ий рядок - |- - 2-ий рядок- - |

Для доступу до окремого елемента двовимірного масиву використовується конструкція, яка має вигляд a[i][j], де i – номер рядка, j – номер стовпчика. Кожен індекс може змінюватися від 0 до значення, яке на одиницю менше за значення відповідної розмірності.

Як і для одновимірного масиву, при описі двовимірного масиву можна задавати початкові значення його елементів. Їх записують у фігурних дужках. Елементи масиву ініціалізуються в порядку їх розміщення у пам’яті.

Наприклад: оператор

int с[3][4] = {1,2,34,2,3,4,1,3,4,1,2};

визначає матрицю з наступними значеннями елементів: 1 2 3 4

2 3 4 1

3 4 1 2

Можна задавати початкові значення не для всіх елементів масиву. Для цього список значень для кожного рядка береться додатково у фігурні дужки. Наприклад:

int d[3][4] = {{0,1,2},{9,-2},{-7,1,6,8}};

В даному випадку розмірність, що позначає кількість рядків, можна не вказувати.

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

int nriad=5;

int **m=(int**) new int[nriad][10];

Більш ефективний і безпечний спосіб виділення пам’яті під двовимірний масив, коли обидві його розмірності вказуються на етапі виконання програми, тобто є змінними, наведено нижче:

int nriad, nstp;

cout <<”Введіть кількість рядків та стовпців:”;