Почему при выводе динамического массива в консоль не нужен оператор разыменования?
Прохожу тему динамических массивов и при написании кода стало интересно, почему при выводе динамического массива не нужен оператор разыменования? Почему нужен в арифметике указателей я понял.
#include<iostream>
using namespace std;
/*
* динамический массив
*/
void main()
{
int size = 0;
cout << "enter value " << endl;
cin >> size;
int* arr = new int[size];//выделение динамической памяти для массива
for (int i = 0; i < size; i++)//Заполнение динамического массива
{
arr[i] = rand();
}
for (int i = 0; i < size; i++)//Вывод динамического массива
{
cout << arr[i] << "\t";
cout << *(arr + i) << endl; //арифметика указателей
}
delete [] arr;
}
Ответы (2 шт):
По сути выражение arr[i] — это и есть *(arr + i).
Разыменовывать можно указатель, но arr[i] таковым не является.
arr[i] — это i-ый элемент массива, начинающегося по адресу arr. Т.е. элемент, находящийся по адресу arr + i. А чтобы получить значение по этому адресу, нужно разыменование — *(arr + i).
Столкнулся с таким же вопросом, провел небольшое исследование на основе ответа на аналогичный вопрос на en stackoverflow
int main()
{
int* a = new int[5];
for (int i = 0; i < 4; ++i) {
a[i] = i + 1;
}
int x = 10;
int *p1 = &x;
int *p2 = &x;
// Эти выражения эквивалентны
*p1 = 20;
p2[0] = 20;
// Выводы тоже эквивалентны
cout << *(p1) << endl;
cout << p2[0] << endl;
// Попробуем с массивом
cout << *(a) << endl;
cout << a[0]<<endl;
// Если не первый элемент
cout << *(a + 3) << endl;
cout << a[3]<<endl;
return 0;
}
В стандарте C++ ISO/IEC 14882:2014 п 5.2.1 написано:
The expression E1[E2] is identical (by definition) to *((E1)+(E2))
Выражение E1[E2] идентично (по определению) *((E1)+(E2))
Таким образом можно утверждать, что записи
cout << *(a + 3) << endl;
cout << a[3]<<endl;
аналогичны, и разыменование не нужно