Урок №87. Адресна арифметика і індексація масивів

  Юрій  | 

  Оновл. 12 Січ 2021  | 

 134

Мова С++ дозволяє виконувати цілочисельні операції додавання/віднімання з вказівниками. Якщо ptr вказує на ціле число, то ptr + 1 є адресою наступного цілочисельного значення в пам’яті після ptr. ptr - 1 — це адреса попереднього цілочисельного значення (перед ptr).

Адресна арифметика

Зверніть увагу, ptr + 1 не повертає наступну будь-яку адресу в пам’яті, яка знаходиться відразу після ptr, але повертає адресу наступного об’єкта в пам’яті, тип якого збігається з типом значення, на яке вказує ptr. Якщо ptr вказує на адресу цілочисельного значення в пам’яті (розмір якого складає 4 байта), то ptr + 3 повертатиме адресу третього цілочисельного значення після ptr в пам’яті. Якщо ptr вказує на адресу значення типу char в пам’яті, то ptr + 3 повертатиме адресу третього значення типу char в пам’яті після ptr.

При обчисленні результату виразу адресної арифметики (або “арифметики з вказівниками”) компілятор завжди множить цілочисельний операнд на розмір об’єкта, на який вказує вказівник. Наприклад:

Результат на моєму комп’ютері:

002CF9A4
002CF9A8
002CF9AC
002CF9B0

Як ви можете бачити, кожна наступна адреса збільшується на 4. Це пов’язано з тим, що розмір типу int на моєму комп’ютері становить 4 байти.

Ось та ж програма, але з використанням типу short замість типу int:

Результат:

002BFA20
002BFA22
002BFA24
002BFA26

Оскільки тип short займає 2 байти, то кожна наступна адреса збільшується на 2.

Розташування елементів масиву в пам’яті

Використовуючи оператор адресу &, ми можемо легко визначити, що елементи масиву розташовані в пам’яті послідовно:

Результат на моєму комп’ютері:

Element 0 is at address: 002CF6F4
Element 1 is at address: 002CF6F8
Element 2 is at address: 002CF6FC
Element 3 is at address: 002CF700

Зверніть увагу, кожна з цих адрес окремо займає 4 байти, як і розмір типу int на моєму комп’ютері.

Індексація масивів

Ми вже знаємо, що елементи масиву розташовані в пам’яті послідовно. З попереднього уроку ми знаємо, що фіксований масив може конвертуватися на вказівник, який вказує на перший елемент (елемент під індексом 0) масиву.

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

Отже, можна припустити, що додавання одиниці до ідентифікатора масиву призведе до повернення адреси другого елементу (елементу під індексом 1) масиву в пам’яті. Перевіримо на практиці:

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

Результат виконання програми на моєму комп’ютері:

001AFE74
001AFE74
8
8

Виявляється, коли компілятор бачить оператор індексу []. Він, насправді, конвертує його у вказівник з операцією додавання і розіменування! Тобто, array[n] — це те ж саме, що *(array + n), де n є цілочисельним значенням. Оператор індексу [] використовується в цілях зручності, щоб не потрібно було завжди пам’ятати про дужки.

Використання вказівника для ітерації по масиву

Ми можемо використовувати вказівники і адресну арифметику для виконання ітерацій по масиву. Хоча зазвичай це не робиться (використання оператора індексу, як правило, більш читабельне і менш вразливе до помилок), наступний приклад показує, що це можливо:

Як це працює? Програма використовує вказівник для прогону кожного елемента масиву по черзі. Пам’ятаєте, що масив конвертується у вказівник на перший елемент масиву? Відповідно, присвоївши name для ptr, сам ptr став вказувати на перший елемент масиву. Кожен елемент розіменовується за допомогою кейсу switch, і, якщо поточний елемент масиву є голосною буквою, то numVowels збільшується. Для переміщення вказівника до наступного символу (елементу) масиву в циклі for використовується оператор ++. Цикл завершиться, коли всі символи будуть перевірені.

Результат виконання програми:

Jonathan has 3 vowels.

Оцінити статтю:

1 Зірка2 Зірки3 Зірки4 Зірки5 Зірок (3 оцінок, середня: 5,00 з 5)
Loading...

Залишити відповідь

Ваш E-mail не буде опублікований. Обов'язкові поля відмічені *