Использование отрицательного числа в качестве индекса массива
Я столкнулся с конкурентным вопросом, который запрашивает вывод следующего:
#include <stdio.h>
int main()
{
int a[] = {0,1,2,3,4};
int i, *ptr;
for(ptr = a+4, i=0; i <=4; i++)
printf("%d", ptr[-i]);
return 0;
}
Я прочитал эту тему: Разрешены ли отрицательные индексы массива в C? Однако мне было непонятно, как символ -ve генерирует массив в обратном порядке, то есть. 4, 3, 2, 1, 0
.
Ответы
Ответ 1
Во-первых, напомним, что в C выражение ptr[index]
означает то же, что и *(ptr+index)
.
Теперь давайте снова посмотрим на ваше выражение: ptr
перед циклом устанавливается a+4
; то вы применяете к нему индекс -i
. Следовательно, эквивалентное выражение для арифметических указателей было бы следующим:
printf("%d", *(a+4-i));
Это выражение повторяет массив назад, создавая результаты, которые вы видите.
Ответ 2
Причина, по которой он работает, заключается в том, что оператор [] выполняет добавление указателя.
Когда вы ссылаетесь на
a[x]
На самом деле происходит его выбор адреса памяти a и добавление sizeof (int) * x
Итак, если вы установите ptr на + 4, вы перейдете к + sizeof (int) * 4
тогда, когда вы положите отрицательное значение, вы перемещаетесь назад по адресу памяти.
Ответ 3
a+4
дает указатель на пятый элемент a
. Таким образом, ptr
ссылается на это местоположение.
Затем цикл подсчитывает i
от 0 до (и включает) 4.
Разница ptr[-i]
эквивалентна *(ptr - i)
(по определению). Итак, поскольку i
равно 0, а ptr
- a+4
, это эквивалентно a+4-0
, затем a+4-1
, затем a+4-2
и т.д. До a+4-4
, что (очевидно, достаточно) a
.
Ответ 4
ptr[-i]
распадается на *(ptr + (-i))
. На первой итерации, когда i = 0
, ptr[-i]
обращается к последнему элементу массива a
, потому что изначально ptr был установлен равным a + 4
, что означает - принять адрес начала a
и добавить 4 * sizeof(int)
(потому что ptr
имел размер int). На каждой следующей итерации, когда я увеличивается, достигается доступ к предыдущему элементу массива.
Ответ 5
В для оператора
for(ptr = a+4, i=0; i <=4; i++)
Указатель ptr
установлен на a+4
Это можно сделать также следующим образом
ptr = &a[4];
Если вы выставляете лоток для вывода значения, на которое указывает указатель, например,
printf( "%d\n", *ptr );
вы получите 4
. То есть указатель указывает на последний элемент массива.
Внутри цикла используется выражение ptr[-i]
. для i, равного 0, он эквивалентен ptr[0]
или просто *ptr
, который будет выводиться последним элементом массива.
Для i, равного 1, выражение ptr[-i]
эквивалентно a[4 - 1]
или просто [3]. Когда iequal до 2, когда выражение ptr [-i] эквивалентно a[4 - i]
, то есть a[4 - 2]
, которое, в свою очередь, a[2]
и так далее.
Итак, вы получите
4321
Ответ 6
Как я упоминал в своем комментарии на C/С++
a[b] == *(a+b) == b[a]
В вашем случае все это прекрасно
printf("%d", *(a + 4 - i));
printf("%d", a[4 - i]);
printf("%d", 4[a - i]);
...