Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Консп_лекцій_Частина_1. Основи представлення с.doc
Скачиваний:
9
Добавлен:
06.11.2018
Размер:
839.68 Кб
Скачать

5.3. Посилання

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

Формат оголошення посилання:

тип & ім'я;

де тип - це тип величини, на яку вказує посилання, & - оператор посилання, що означає, що наступне за ним ім'я є ім'ям змінної типу посилання, наприклад:

іnt kol;

int & pal = kol; // посилання pal - альтернативне ім'я для kol

const char & CR = ' \ n ' : // посилання на константу

Для посилання діють наступні правила:

  • Змінна-посилання повинна явно ініціалізуватися при її описі, крім випадків, коли вона є параметром функції, описана як extern або посилається на поле даних класу.

  • Після ініціалізації посиланню не може бути присвоєна інша змінна.

  • Тип посилання повинен збігатися з типом величини, на яку воно посилається.

  • Не дозволяється визначати вказівники на посилання, створювати масиви посилань і посилання на посилання.

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

Посилання, на відміну від вказівника, не займає додаткового простору в пам'яті і є просто іншим ім'ям величини. Операція над посиланням приводить до зміни величини, на яку вона посилається.

5.4. Масиви

Масив - це впорядкований скінченний набір даних одного типу, які зберігаються в послідовно розташованих комірках оперативної пам'яті і мають спільну назву. З оголошення масиву компілятор одержує інформацію про тип елементів масиву та їх кількість.

Для роботи з масивом його елементи індексуються (нумеруються), а доступ до них здійснюється за допомогою операції взяття індексу. В мові С++ індексація масивів починається з 0, тому елемент із індексом 1 насправді є другим елементом масиву, а індекс першого дорівнює 0. Індекс може бути цілим числом або цілим виразом. Якщо в якості індекса використовується вираз, то спочатку обчислюється вираз, щоб визначити конкретний елемент масиву з яким буде виконуватись робота.

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

int b[3] = {3, 2, 1}; // аналогічно присвоєнням : b[0]=3; b[l]=2; b[2]=l;

Якщо початкових значень меньше, ніж елементів в масиві, то елементам, що залишились автоматично надаються нульові початкові значення. Наприклад, елементам масиву b можна присвоїти нульові початкові значення за допомогою оголошення

int b[12] = {3, 2, 1};

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

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

int b[5] = {0}; // аналогічно присвоєнням : b[0]=0; b[l]=0; b[2]=0; b[3]=0; b[4]=0;

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

int b[5] = {5, 4, 3, 2, 1, 0};

призведе до синтаксичної помилки, оскільки список ініціалізації містить 6 початкових значень, а масив має тільки 5 елементів.

Використання ідентифікатора масива в програмі еквівалентно використанню адреси його першого елемента. Прохід по масиву можна здійснювати за допомогою індексів або за допомогою вказівників.

Незважаючи на те, що в мові С++ вбудована підтримка для типу даних "масив", вона досить обмежена. Фактично є можливість доступу тільки до окремих елементів масиву. Мова С++ не підтримує абстракцію масиву, не існує операцій над масивами в цілому, таких, наприклад, як присвоєння значень одного масива іншому або порівняння двох масивів на рівність. Замість цього потрібно програмувати такі операції за допомогою циклів поелементно.

В мові С++ також використовуються багатовимірні масиви, при оголошенні яких необхідно вказувати праву границю кожного виміру в окремих квадратних дужках. При звертанні до елементів багатовимірного масиву необхідно вказувати індекси для кожного виміру.

Багатовимірні масиви можуть отримувати початкові значення в своїх оголошеннях так само, як і одновимірні масиви. При ініціалізації багатомірного масиву він представляється як масив масивів, при цьому кожен масив знаходиться у своїх фігурних дужках (у цьому випадку ліву розмірність при описі можна не вказувати). Наприклад, двовимірний масив b[2][2] можна оголосити і надати йому початкові значення наступним чином:

int b[][2]={{1, 2},{3, 4}}; //аналогічно присвоєнням: b[0][0]=1; b[0][l]=2; b[1][0]=3; b[1][1]=4;

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

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

буде означати, що b[0][0] отримує початкове значення 1, b[0][1] отримує початкове значення 0, b[1][0] отримує початкове значення 3 і b[1][1] отримує початкове значення 4.

Якщо зі списку початкових значень забрати всі фігурні дужки навколо кожного підрядка, то компілятор автоматичнонадасть перші початкові значення елементам першого рядка масиву, а наступні – елементам другого рядка масиву. Наприклад, оголошення

int b[2][3] = {1, 2, 3, 4, 5};

містить 5 початкових значень. Початкові значення присвоюються першому рядку матриці:

b[0][0] = 1; b[0][1] = 2; b[0][2] = 3;

решта – другому рядку. Довільні елементи, що не мають явно заданих початкових значень, автоматично отримують нульові початкові значення. Отже:

b[1][0] = 4; b[1][1] = 5; b[1][2] = 0;

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

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

В пам'яті комп'ютера елементи масиву з першого до останнього запам'ятовуються в послідовних зростаючих комірках пам'яті. Між елементами масиву в пам'яті розриви відсутні. Елементи масиву з найменшим індексом зберігаються по найменшій адресі пам’яті. Розмір пам’яті, що відводиться для зберігання масиву, обчислюється за формулою:

Memory = кількість елементів масиву * розмір одного елемента

Багатовимірні масиви в пам'яті комп'ютера зберігаються так, що найбільш правий індекс збільшується першим.

Приклад 8.

Розглянемо двовимірний масив цілих чисел:

іnt mass [3][2]= { {1, 1}, {0, 2}, {1, 3} };

В пам’яті комп’ютера він зберігається у такому виді:

00000001 00000000 00000000 00000000 00000001 00000000 00000000 00000000 00000000

mass [0][0] mass [0][1]

00000000 00000000 00000000 00000010 00000000 00000000 00000000 00000001 00000000

mass [1][0] mass [1][1]

00000000 00000000 00000011 00000000 00000000 00000000

mass [2][0] mass [2][1]

Масив може бути ініціалізований рядковим літералом. Рядковий літерал - рядок символів, що знаходиться у подвійних лапках. От приклади рядкових літералів:

"Program"

"5"

"" // порожній рядок

Такий літерал може займати і кілька рядків, наприклад, щоб зробити код більш читабельним. У цьому випадку наприкінці рядка ставиться зворотна коса риса, наприклад:

"a multі-lіne \

strіng lіteral sіgnals іts \

contіnuatіon wіth a backslash"

Спеціальні символи можуть бути представлені своїми escape-послідовностями, наприклад:

"\nCC\toptіons\tfіle.[c]\a\n"

Якщо в тесті програми йдуть підряд два або декілька рядкових літералів, то компілятор з'єднує їх в один рядок. Наприклад, текст "two" "some" породить рядок символів "twosome".

Фактично рядковий літерал являє собою масив символьних констант, в якому останнім елементом завжди є спеціальний символ з кодом 0 (\0). Наприклад, символьний літерал 'A' задає єдиний символ А, а рядковий літерал "А" - масив із двох елементів: 'А' і \0 (порожній символ).

Символи рядка запам'ятовуються в окремих байтах пам'яті. Символ нуль є відміткою кінця рядка. Він невидимий у рядковому виразі, але він додається як останній елемент, коли рядок запам'ятовується.

Якщо спеціфікується розмір масиву, а рядок містить більше символів ніж специфікований розмір, то зайві символи відкидаються. Наприклад, у прикладі char code[3] = "abcd" тільки три перші символи будуть належати масиву code. Символ d і символ з кодом 0 будуть відкинуті.

Якщо рядок коротший, ніж специфікований розмір масиву, то елементи масиву, що залишилися, ініціалізуються нулем (символом \0).

Приклад 9.

Розглянемо символьний рядок:

char my[] = "Lab-1";

В пам’яті комп’ютера він зберігається в 6 байтах у такому вигляді:

0100 1100 0110 0001 0110 0010 0010 1101 0011 0001 0000 0000

my[0] = 'L' my[1] = 'a' my[2] = 'b' my[3] = '-' my[4] = '1' признак кінця рядка