Подтвердить что ты не робот

Использование отрицательного числа в качестве индекса массива

Я столкнулся с конкурентным вопросом, который запрашивает вывод следующего:

#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.

4b9b3361

Ответ 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]);
...