Я просто читал код и обнаружил, что человек использовал arr[-2]
для доступа ко второму элементу до arr
, например:
|a|b|c|d|e|f|g|
^------------ arr[0]
^---------- arr[1]
^---------------- arr[-2]
Это разрешено?
Я знаю, что arr[x]
это то же самое, что и *(arr + x)
. Так arr[-2]
это *(arr - 2)
, что , кажется , в порядке. Что вы думаете?
somearray-2
не определены, если результат не находится в диапазоне от началаsomearray
до 1 после его конца.[]
них ссылались как на синтаксический сахар для арифметики указателей. Любимый способ запутать новичков - писать1[arr]
вместо того, чтобыarr[1]
смотреть, как они догадываются, что это означает.((E1)+(E2))
будет (64-битным) указателем с ожидаемым значением.Это допустимо, только если
arr
указатель указывает на второй элемент в массиве или более поздний элемент. В противном случае это недопустимо, потому что вы будете обращаться к памяти за пределами массива. Так, например, это было бы неправильно:Но это было бы нормально:
Однако использование отрицательного индекса является необычным.
источник
int arr[10];
были частью структуры с другими элементами до нее,arr[-2]
потенциально могли бы быть четко определены, и вы могли бы определить, основана ли она наoffsetof
и т. Д.If one is sure that the elements exist, it is also possible to index backwards in an array; p[-1], p[-2], and so on are syntactically legal, and refer to the elements that immediately precede p[0]. Of course, it is illegal to refer to objects that are not within the array bounds.
Тем не менее, ваш пример лучше помогает мне понять его. Спасибо!Звучит нормально. Однако это будет редкий случай, когда вам это понадобится на законных основаниях.
источник
Вероятно, это
arr
указывало на середину массива, следовательно,arr[-2]
указывало на что-то в исходном массиве без выхода за пределы.источник
Я не уверен, насколько это надежно, но я только что прочитал следующее предостережение об отрицательных индексах массива в 64-битных системах (предположительно LP64): http://www.devx.com/tips/Tip/41349
Похоже, что автор говорит, что 32-битные индексы массива int с 64-битной адресацией могут привести к вычислению неверных адресов, если только индекс массива явно не повышен до 64-битного (например, через приведение ptrdiff_t). Я действительно видел ошибку его характера в версии gcc 4.1.0 для PowerPC, но я не знаю, является ли это ошибкой компилятора (т.е. должен работать в соответствии со стандартом C99) или правильным поведением (например, для индекса требуется приведение к 64 бит для правильного поведения)?
источник
Я знаю, что на вопрос дан ответ, но я не мог удержаться от этого объяснения.
Я помню принципы построения компилятора. Предположим, что a - массив int, размер int равен 2, а базовый адрес a равен 1000.
Как
a[5]
будет работать ->Это объяснение также является причиной того, почему отрицательные индексы в массивах работают в C.
т.е. если я получу доступ,
a[-5]
он даст мнеОн вернет мне объект в местоположении 990. С помощью этой логики мы можем получить доступ к отрицательным индексам в массиве в C.
источник
Что касается того, зачем кому-то использовать отрицательные индексы, я использовал их в двух контекстах:
Имея таблицу комбинаторных чисел, в которой говорится, что comb [1] [- 1] = 0; вы всегда можете проверить индексы перед доступом к таблице, но так код выглядит чище и выполняется быстрее.
Ставим сантинель в начало таблицы. Например, вы хотите использовать что-то вроде
но тогда вы также должны проверить это
i
положительно.Решение: сделать так , чтобы
a[-1]
это-DBLE_MAX
, так чтоx<a[-1]
всегда будет ложным.источник
источник