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

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

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

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[]')

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

0

Решение

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

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

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

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

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

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

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

1

Другие решения

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

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

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

1

По вопросам рекламы [email protected]