Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Industrial programming >> Язык C

Указатели и массивы в C++: мастерство взаимодействия

Указатели и массивы в C++

В этом руководстве мы изучим связь между массивами и указателями с практическими примерами.

В C++ указатели — это переменные, хранящие адреса других переменных. Указатель может хранить не только адрес одной переменной, но и адреса элементов массива.

Рассмотрим пример:

int *ptr;
int arr[5];
// Сохранить адрес первого элемента arr в ptr
ptr = arr;

Здесь ptr — указатель, а arr — массив int. Код ptr = arr; сохраняет адрес первого элемента массива в переменной ptr.

Обратите внимание: мы использовали arr вместо &arr[0]. Это эквивалентно, так как оба выражения дают один и тот же адрес. Следующий код идентичен приведённому выше:

int *ptr;
int arr[5];
ptr = &arr[0];

Адреса остальных элементов задаются &arr[1], &arr[2], &arr[3] и &arr[4].


Указание на каждый элемент массива

Допустим, нужно указать на четвёртый элемент массива тем же указателем ptr.

Если ptr указывает на первый элемент, то ptr + 3 будет указывать на четвёртый. Например:

int *ptr;
int arr[5];
ptr = arr;
ptr + 1 эквивалентно &arr[1];
ptr + 2 эквивалентно &arr[2];
ptr + 3 эквивалентно &arr[3];
ptr + 4 эквивалентно &arr[4];

Аналогично можно обращаться к элементам через один указатель:

// Использование оператора разыменования
*ptr == arr[0];
*(ptr + 1) эквивалентно arr[1];
*(ptr + 2) эквивалентно arr[2];
*(ptr + 3) эквивалентно arr[3];
*(ptr + 4) эквивалентно arr[4];

Если мы инициализировали ptr = &arr[2];, то:

ptr - 2 эквивалентно &arr[0];
ptr - 1 эквивалентно &arr[1];
ptr + 1 эквивалентно &arr[3];
ptr + 2 эквивалентно &arr[4];
Указатели и массивы в C++: мастерство взаимодействия

Примечание: Адрес между ptr и ptr + 1 отличается на 4 байта, так как ptr — указатель на int (размер 4 байта в 64-битной ОС). Для char разница была бы 1 байт.


Пример 1: Указатели и массивы в C++

// C++ программа для вывода адреса каждого элемента массива
#include <iostream>
using namespace std;

int main() {
    float arr[3];
    // Объявление указателя
    float *ptr;
    
    cout << "Displaying address using arrays: " << endl;
    // Цикл для вывода адресов всех элементов массива
    for (int i = 0; i < 3; ++i) {
        cout << "&arr[" << i << "] = " << &arr[i] << endl;
    }
    
    // ptr = &arr[0]
    ptr = arr;
    cout << "\nDisplaying address using pointers: " << endl;
    // Цикл для вывода адресов с использованием указательной нотации
    for (int i = 0; i < 3; ++i) {
        cout << "ptr + " << i << " = " << ptr + i << endl;
    }
    return 0;
}

Вывод

Displaying address using arrays:
&arr[0] = 0x61fef0
&arr[1] = 0x61fef4
&arr[2] = 0x61fef8
Displaying address using pointers:
ptr + 0 = 0x61fef0
ptr + 1 = 0x61fef4
ptr + 2 = 0x61fef8

В программе сначала выводятся адреса элементов массива без указателя. Затем указатель ptr используется для обращения к адресам: ptr указывает на a[0], ptr + 1 — на a[1] и так далее.


В большинстве контекстов имена массивов преобразуются в указатели. Простыми словами, имя массива конвертируется в указатель. Поэтому мы можем использовать указатели для доступа к элементам массива.

Однако важно помнить: указатели и массивы — это не одно и то же.

Существуют случаи, когда имя массива не преобразуется в указатель. Подробнее: когда имя массива не распадается в указатель?


Пример 2: Использование имени массива как указателя

// C++ программа для ввода и вывода данных с использованием указательной нотации
#include <iostream>
using namespace std;

int main() {
    float arr[5];
    // Ввод данных с использованием указательной нотации
    cout << "Enter 5 numbers: ";
    for (int i = 0; i < 5; ++i) {
        // Сохранение введённого числа в arr[i]
        cin >> *(arr + i);
    }
    
    // Вывод данных с использованием указательной нотации
    cout << "Displaying data: " << endl;
    for (int i = 0; i < 5; ++i) {
        // Вывод значения arr[i]
        cout << *(arr + i) << endl;
    }
    return 0;
}

Вывод

Enter 5 numbers: 2.5 3.5 4.5 5 2
Displaying data:
2.5
3.5
4.5
5
2

Здесь:

  1. Мы использовали указательную нотацию для сохранения введённых пользователем чисел в массив arr:
    cin >> *(arr + i);
    Это эквивалентно cin >> arr[i];. Отдельный указатель не объявлялся — имя массива arr само выступает в роли указателя на первый элемент.
  2. Аналогично, для вывода значений использовался цикл for с указательной нотацией:
    cout << *(arr + i) << endl;
    Это эквивалентно cout << arr[i] << endl;.

Язык C

  1. Освоение переменных, литералов и констант в C++: подробное руководство
  2. Классы и объекты в C++: практическое руководство по объектно-ориентированному программированию
  3. Управление памятью в C++: экспертное использование new и delete
  4. Публичное, защищённое и приватное наследование в C++: подробный разбор
  5. Дружественные функции и классы в C++: мастерство контроля доступа
  6. Освоение указателей в C: практическое руководство от экспертов
  7. Понимание взаимосвязи между массивами и указателями в C
  8. Передача адресов и указателей в функции в C: практическое руководство
  9. Освоение структур и указателей в C: практическое руководство
  10. Структуры C++ против классов: практическое руководство для разработчиков встроенных систем