Как можно получить доступ к элементам массива, добавив числа к массиву "имя", то есть постоянный указатель, в котором хранится адрес первого элемента?
В Си меня учили, что мы можем получить доступ к элементам массива с помощью указателей, увеличив адрес на размер памяти типа данных массива. Так что для массива А, хранящего целые числа,
int *ptr = &A[0];
for(int i = 0; i<3; i++)
{
printf("%p\n", *ptr)
ptr++ // here it's +4 cause int
}
Напечатал бы все 3 значения массива A. Однако, поскольку имя массива является константным указателем, который имеет адрес первого элемента массива, я также видел этот код:
<information on site>
double *p;
double balance[10];
p = balance;
Допустимо использовать имена массивов в качестве указателей на константы, и наоборот. Следовательно, *(баланс + 4) является законным способом доступа к данным на балансе [4].
</informationonsite>
Но как? Если я добавлю +4 к адресу, хранящемуся в указателе баланса, если баланс [] - это массив типа int, то это эквивалентно увеличению его, тогда это заставит его перейти от наведения баланса [1] на баланс [2], а не к баланс [4]. Таким образом, разыменование (*(баланс +4)) даст значение баланса [1], а не [4], верно? Пожалуйста, объясни.
2 ответа
Компилятор знает, что вы указываете на двойной массив, поэтому: *(x+4)
[где х является двойным] является *(double*)((char*)x + 4*sizeof(double))
объяснение: при использовании указателя типа A, то оператор A* p = SOME_ADDRESS; p++
заставляет р двигаться sizeof(A)
байтов вперед, что означает, что он перешел от адреса X к адресу X+sizeof(A) (в байтах)
Массивы не являются указателями, а имена массивов не более указателями, чем массивы. Массивы могут быть автоматически преобразованы в указатели при использовании в выражениях, за исключением некоторых исключений, таких как операнд унарного &
оператор, sizeof
оператор и т. д. Имена массивов будут пропущены во время выполнения, за исключением информации отладки.
(pointer) + (integer)
определяется указателем, который указывает на (integer)
элементы после того, на что указывает (pointer)
в N1570 6.5.6 Аддитивные операторы. Вам не нужно думать об адресах.
Вы не можете разыменовать (*(balance+4))
, который является типом double
, (*(balance+4))
эквивалентно balance[4]
(см. N1570 6.5.2.1 Подписка на массив).