Обмен идентификаторами и подписками при доступе к встроенным массивам и спискам инициализаторов для многомерных массивов

0

Я надеялся, что кто-то сможет рассказать мне о следующем, казалось бы, любопытном синтаксисе. Я хотел бы понять его потенциальную полезность или механизм, который делает синтаксис действительным.

Если у вас есть

char A[] {'a', 'b', 'c'};

затем 2[A] == 'c'.

Q1: Является ли этот эффект следствием правил синтаксического анализа выражений, которые связаны с доступом к элементам многомерных встроенных массивов? Например, B [i] [j] [k].

Q2: В чем причина

int A[][2] {{1, 2}, {3, 4}};

действительный, но

int A[][] {{1, 2}, {3, 4}};

нет? (ошибка считывает Array has incomplete element type 'int[]')

Заранее спасибо.

Теги:
arrays
multidimensional-array
built-in-types

2 ответа

1
Лучший ответ

Я хотел бы понять его потенциальную полезность

Это бесполезно, кроме обфускации. Это просто причуда [].

механизм, который делает синтаксис действительным

a[b] определяется как эквивалентное *(a+b). Так как сложение коммутативно, это эквивалентно *(b+a) и, следовательно, b[a].

int A[][] {{1, 2}, {3, 4}};

Чтобы объявить массив, тип элемента должен быть полным; то есть он должен быть полностью определен, чтобы компилятор знал свой размер. В противном случае компилятор не может знать, как элементы расположены в памяти, поэтому не может генерировать арифметику указателя, необходимую для доступа к ним. Размер самого массива может быть оставлен неуказанным, поскольку для доступа к элементам этого не требуется.

Многомерный массив представляет собой массив массивов, и применяется одно и то же правило: в то время как размер внешнего массива может быть не указан, внутренний тип массива должен быть полным. Чтобы тип массива был полным, его размер должен быть указан.

  • 0
    Спасибо за ясное объяснение.
1

Это связано с тем, что A[2] совпадает с *(A+2), что в свою очередь совпадает с *(2+A). Помимо использования, чтобы запутать начинающих программистов, он не служит абсолютно никакой полезной цели. Но так как существует, вероятно, НЕКОТОРЫЙ код, который опирается на это, его нельзя удалить.

Q1. Я так не думаю. Заметим, что B[2][3] можно заменить на что-то вроде 3[(B[2])], но никто из здравомыслящих человек не напишет это и надеется, что другие поймут это.

Q2. Это точно так, как определяется язык. Компилятор должен знать размер всех элементов, кроме самого внешнего. Это упрощает запись компилятора, потому что (теоретически) компилятор мог хранить готовое содержимое массива по одному элементу за раз. Конечно, современные компиляторы не обязательно это делают, но если вы хотите написать компилятор C или C++ для работы на машине с ограниченной памятью, вы можете это сделать. С этой точки зрения это можно даже записать в объектный файл.

  • 0
    Спасибо за объяснение и дополнительную информацию. Я хотел бы принять более одного ответа.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню