Недавно я видел ответ на вопрос, где они объяснили, что адресация массивов таким образом <number>[array]
является допустимым кодом C.
Как квадратные скобки работают в C?
Пример:
char x[] = {'A','B','C','D','E','F','G','H','I','J'};
printf("%d\n",5[X]);
//Will print 70 == 'F'
Такие обозначения кажутся громоздкими и потенциально запутанными для всех, включая автора.
Есть ли у такого способа адресации массивов какое-то оправданное преимущество?
или
Могу ли я продолжать свою жизнь, не беспокоясь?
Это чисто вопрос, основанный на мнении.
Проголосовали за закрытие, поскольку в первую очередь основаны на мнении (хотя я думаю, что у большинства людей такое же мнение)
Даже если стиль вашего кода зависит от вашего мнения, есть законные причины использовать определенный синтаксис вместо других. Отсюда вопрос.
@kiranBiradar я не согласен. Универсальные советы относительно чистого кода редко основаны исключительно на мнении. В этом синтаксисе нет преимуществ, а есть только недостатки, поэтому он объективно плох. Кроме того, ОП не спросил, хорошо ли это. ОП спросил, есть ли у него какие-либо преимущества.
@kiranBiradar Я не согласен. ОП явно просит оправданий. Учитывая, что этот синтаксис явно допустим, это правильный вопрос. (И ответ заключается в том, что нет даже веских причин для того, чтобы это было законным. Авторы C просто хотели быть умными: нет никаких причин для операций с индексами поддерживать коммутативный синтаксис)
@kiranBiradar Определенно нет. Возможно, что ответ «нет объективных минусов и плюсов», но это объективный ответ.
Не уверен, что этот вопрос добавляет что-то к каноническому вопросу: stackoverflow.com/questions/381542/…
@RuudHelderman Думаю, да.
C обычно не запрещает активно то, для чего нет технических причин. Эта «функция» в основном существует из-за взаимодействия других языковых функций. Но если вы можете найти вескую причину для его использования, хорошо для вас! C уйдет с вашего пути и позволит вам использовать его.
Связано: Поддерживают ли указатели «индексацию в стиле массива»?
Пользователь на quora.com присвоил этот вопрос плагиату: quora.com/… Я сообщил об этом там.
Да, арифметика указателей коммутативна, потому что сложение коммутативно. Такие ссылки, как a[n]
, преобразуются в *(a+n)
, но также n[a]
преобразуются в *(n+a)
, что идентично. Если вы хотите выиграть соревнования ioccc, вы должны использовать это.
Вы объяснили, почему арифметика указателей коммутативна. Вы нет объяснили, почему индексирование массива является коммутативным: это может быть семантически эквивалентно арифметике указателя + разыменованию, но явно не эквивалентно синтаксически.
Насколько я могу судить, ни у одного из методов нет технических плюсов или минусов. Они 100% эквивалентны. Как сказано в предоставленной вами ссылке, a[i]
= *(p+i)
= [сложение коммутативно] = *(i+p)
= i[a]
.
Что касается субъективных плюсов и минусов, то это сбивает с толку. Таким образом, форма index[array]
полезна для запутывания кода, но кроме этого я не вижу в ней никакого применения.
Одна из причин (но я действительно копаю здесь) для использования стандартного способа заключается в том, что a[b+c]
не эквивалентен b+c[a]
. Вместо этого вам нужно было бы написать (b+c)[a]
, чтобы сделать его эквивалентным. Это может быть особенно важно в макросах. По этой конкретной причине макросы обычно заключают в скобки каждый отдельный аргумент при каждом отдельном использовании.
По сути, это тот же аргумент, что и писать if (2==x)
вместо if (x==2)
. Если вы случайно напишите =
вместо ==
, вы получите ошибку компилятора с первым методом.
Can I continue with my life without worrying?
да.
Я никогда не сталкивался с этим в «реальном коде» (т. е. вне намеренно запутанных вещей и головоломок с искусственными ограничениями), поэтому, похоже, все согласны с тем, что этого делать не следует.
Тем не менее, я могу привести надуманный пример, где некоторые (не обязательно я) могут счесть его более приятным синтаксисом: если у вас есть несколько фрагментов данных, связанных с одним объектом в столбце, и вы представляете строки как разные массивы :
enum { ADA, BRIAN, CLAIRE };
const char *name[] = { "Ada", "Brian", "Claire" };
const unsigned age[] = { 30, 77, 41 };
printf("%s is %u years old\n", ADA[name], ADA[age]);
Я буду первым, кто согласится с тем, что это запутывает синтаксис, создавая впечатление, что люди представляют собой массивы, а не индексы, и в большинстве случаев я бы предпочел массив struct
. Я думаю, что это могло бы быть сделано для более красивого вида, или, возможно, в некоторых случаях это был бы способ поменять местами строки и столбцы (массивы и индексы) с минимальными изменениями в другом месте.
Я думаю, что самое опасное в этом то, что это выглядит разумно. :D
Хм, интересный вариант использования... Предполагая специальную архитектуру с ПЗУ и ОЗУ, а также наборы данных с константными и изменяемыми элементами. Со структурами нам нужно было бы поместить все в ОЗУ, с отдельными массивами мы могли бы поместить константную часть в ПЗУ и оставить в ОЗУ только изменяемые части...
Это почти как начало проектирования сущностных компонентов; в частности, используя структуру массивов, можно добавлять «поля» к ADA
и друзьям, не затрагивая макет данных, которые в настоящее время существуют. На самом деле это выглядит довольно элегантно, как по мне.
Это симпатичный трюк, используемый в запутанных соревнованиях C. Не используйте его в серьезном коде, даже если это позволяет синтаксис.