Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву
Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Оголошення вказівника, операції, пов’язані з вказівникамиСодержание книги
Поиск на нашем сайте Вказівник (покажчик, англ. pointer) – це особливий тип даних, значенням якого є адреса певного байта оперативної пам'яті. Найчастіше вказівник зберігає адресу першого байта одного з об’єктів програми. Це називається посиланням на вказаний об’єкт. Вказівники можуть бути константними і змінними: константні вказівники зберігають незмінну адресу оперативної пам'яті, зокрема константними вказівниками є імена масивів і символьних рядків; вказівники – змінні є змінними програми, їм можна надавати значення адрес різних ділянок оперативної пам'яті. Як і для змінних, вказівники необхідно оголошувати. Синтаксис оголошення змінних такий:
базовий_тип * ім’я_вказівника;
тут базовий тип – тип об’єктів програми, адреси яких може зберігати даний вказівник; це може бути довільний стандартний тип або тип користувача; * - ознака того, що наступна змінна є вказівником; ім’я вказівника – ідентифікатор. З вказівниками пов’язані дві унарні операції: & - визначення адреси, * - звертання до об’єкта за адресою. Значенням операції визначення адреси змінної є адреса операнда (тобто змінної), перед яким стоїть знак &. Розглянемо фрагмент програми:
#include <iostream> using namespace std; int main() { int a = 5, *pa; pa = &a; cout << pa << endl; }
тут змінна а – звичайна змінна цілого типу, ра – вказівник на ціле. В результаті виконання рядка pa = &a; змінна ра буде містити адресу першого байти пам'яті, яку займає змінна а. Значення адреси змінної можна присвоїти тим вказівникам, базовий тип яких збігається з типом змінної. Тобто, спроба компіляції наступної програми буде призводити до помилки:
#include <iostream> using namespace std; int main() { int a = 5, *pa; char c = 'z'; pa = &c; // Помилка, базовий тип вказівника і // тип змінної не співпадають }
Існують такі обмеження щодо застосування операції визначення адреси: не можна визначати адресу константи; не можна визначати адресу виразу; не можна визначати адресу змінної з класом пам'яті register. В оголошенні вказівника можна виконувати ініціалізацію значенням адреси об’єкта, що має відповідний до вказівника тип і був оголошений раніше. Наприклад:
int a = 5, *pa = &a;
Вказівники можна також ініціалізувати значеннями адрес – констант:
char *pc = (char *) 0x04cd;
Існує константа NULL, яку можна присвоювати вказівникам всіх типів. Вважається що вказівник, значенням якого є NULL, не посилається на жоден об’єкт програми. Такий вказівник називають порожнім вказівником. Операндом операції звертання за адресою є вказівник або адреса ділянки пам'яті, а результатом – значення об’єкта, який зберігається в цій ділянці. Цю операцію також називають розадресацією, вона є зворотною до операції взяття адреси. Результат цієї операції має тип, що був заданий як базовий в оголошенні вказівника. Звертання через вказівник можна використовувати всюди, де синтаксично може бути записаний об’єкт даного типу. Наприклад:
#include <iostream> using namespace std; int main() { int a = 5, *pa; pa = &a; // Отримали адресу змінної а *pa = 12; // Змінили значення змінної а cout << *pa << endl; cout << a << endl; }
В оголошеннях вказівників можна вказувати кваліфікатор const. Роль цього кваліфікатора визначається місцем його запису. Якщо кваліфікатор const в оголошенні передує базовому типу вказівника, то він означає, що за допомогою такого вказівника заборонено змінювати значення об’єкта, на який він посилається.
#include <iostream> using namespace std; int main() { int a = 5; const int b = 123; const int * cp; cp = &a; // Можна змінювати значення вказівника *cp = 12; // Помилка, не можна змінювати значення // об’єкта, на який посилається вказ-к cp = &b; cout << *cp << endl; // Можна читати значення об’єкта, на // який посилається вказівник }
Якщо кваліфікатор const в оголошенні передує імені вказівника, то такий вказівник буде константним. В оголошенні константний вказівник обов’язково необхідно проініціалізувати, змінювати це значення не можна.
#include <iostream> using namespace std; int main() { int a = 5, b = 12; int * const cp = &a; cp = &b; // Помилка, не можна змінювати значення // константного вказівника *cp = 12; // Можна змінювати значення об’єкта, на // який посилається вказівник cout << *cp << endl; // Можна читати значення об’єкта, на // який посилається вказівник } Адресна арифметика Зручність використання вказівників пов’язана з можливістю виконання над ними таких операцій: присвоєння, порівняння, збільшення і зменшення, віднімання. Операції над вказівниками називають адресною арифметикою. Операції присвоєння, порівняння та віднімання бінарні, обидва операнди цих операцій обов’язково повинні бути вказівниками або адресними виразами з однаковим базовим типом. Операції збільшення чи зменшення значень вказівників можуть бути як унарними (постфіксний або префіксний інкремент або декремент вказівника) і бінарними – збільшення (зменшення) значення вказівника на задану цілочислову величину. Приклад використання операції присвоєння значень вказівників:
#include <iostream> using namespace std; int main() { int a = 5; int * p1, * p2; p1 = &a; p2 = p1; *p2 = 123; cout << a << endl; }
Над вказівниками (або адресними виразами) можна виконувати всі операції порівняння мови С++. Результатом виконання операції є величина логічного типу. Наприклад:
#include <iostream> using namespace std; int main() { int a = 5, b = 5; int * p1, * p2; p1 = &a; p2 = &b; if (p1 == p2) // Порівнюємо значення вказівників cout << "p1 == p2" << endl; else cout << "p1!= p2" << endl; if (*p1 > *p2) // Порівнюємо значення, на які // посилаються вказівники, тобто а і b cout << "a > b" << endl; else cout << "a <= b" << endl; }
До значення вказівника можна додавати (чи віднімати від нього) довільне ціле число. Результатом операції збільшення (зменшення) вказівника є нова адреса. Наприклад
#include <iostream> using namespace std; int main() { int a[ 5 ] = { 1, 2, 3, 4, 5 }; int * p; p = &a[ 0 ]; // Адреса першого елемента масиву cout << *p << endl; // Виводимо перший елемент масиву p++; // Адреса другого елемента масиву cout << *p << endl; // Виводимо другий елемент масиву }
У попередньому прикладі при виконанні операції p++ значення вказівника буде збільшуватися на sizeof(базовий_тип), тобто sizeof(int). Після виконання операції інкремента вказівник буде посилатися на наступне ціле значення в пам'яті, тобто на наступний елемент масиву. У загальному випадку, при збільшенні (зменшенні) значення вказівника на ціле число k фактично він буде змінюватися на k * sizeof(базовий_тип) і буде вказувати на інше значення базового типу в пам'яті. Таким чином, величина, яка додається до вказівника або віднімається нього завжди кратна розміру базового типу цього вказівника.
#include <iostream> using namespace std; int main() { int a[ 5 ] = { 1, 2, 3, 4, 5 }; int * p; p = &a[ 0 ]; // Адреса першого елемента масиву cout << *p << endl; // Виводимо перший елемент масиву p += 2; // Адреса третього елемента масиву cout << *p << endl; // Виводимо третій елемент масиву }
Операція віднімання виконується над двома вказівниками (або адресами), її результатом є кількість елементів базового типу, які можна розташувати в ділянці оперативної пам'яті, адреси початку і кінця якої задають вказівники. Наприклад
#include <iostream> using namespace std; int main() { int a[ 5 ] = { 1, 2, 3, 4, 5 }; int * p1, * p2; p1 = & a[ 0 ]; // Адреса першого елемента масиву p2 = & a[ 4 ]; // Адреса останнього елемента масиву cout << p2 - p1; // 4 елемента: 0-й, 1-й, 2-й, 3-й }
Операндом операції звертання за адресою може бути адреса ділянки пам'яті, в якій зберігається значення певного типу. Тип значення в пам'яті буде визначатися базовим типом вказівника. В наступній програмі спочатку обчислюється вираз в дужках, тобто знаходимо адресу четвертого елемента масиву, після цього звертаємося за цією адресою.
#include <iostream> using namespace std; int main() { int a[ 5 ] = { 1, 2, 3, 4, 5 }; int * p; p = & a[ 0 ]; // Адреса першого елемента масиву cout << *(p + 3); // Виводимо 4-й елемент масиву }
Всі інші операції, крім перелічених, виконувати над вказівниками не можна: не можна додавати чи множити вказівники, виконувати над ними побітові операції тощо.
|
||
|
Последнее изменение этой страницы: 2021-12-15; просмотров: 118; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 216.73.216.147 (0.008 с.) |