Какой современный термин для "эквивалентности массива/указателя"?

Почти все, кто читает это, вероятно, знакомы с этими тремя ключевыми фактами о C:

  • Когда вы указываете имя массива в выражении, он вычисляет (большую часть времени) указатель на первый элемент массива.
  • Оператор [] подстроки массива <работает так же хорошо для указателей, как и для массивов.
  • Параметр функции, который, кажется, представляет собой массив, фактически объявляет указатель.

Эти три факта абсолютно важны для обработки массивов и указателей на C. Они не являются даже тремя отдельными фактами; они взаимосвязанные грани одной центральной концепции. Невозможно выполнить даже довольно базовое программирование на C без надлежащего понимания этой концепции.

Мой вопрос сегодня просто: как называется эта концепция?

Я предположил, что я старомодный, но я всегда называл его "эквивалентность между массивами и указателями в C", или "эквивалентность макета/указателя" для краткости. Но я узнал, что вы почти не можете сказать эти слова на SO; они в значительной степени табу.

Это может показаться абстрактным или философским вопросом, поэтому для более конкретного определения того, что я ищу, это простое существительное или именная фраза, которую я мог бы использовать в предложении "Да, из-за _____, подсчет массива может считаться синтаксическим сахаром для арифметики указателя", в ответ на, скажем, этот вопрос.

(Но, пожалуйста, обратите внимание, что я не ищу ответов на этот вопрос или ответов на вопрос "Что не так со словом" эквивалентность "?" Да, я знаю, он может ввести в заблуждение учащихся, чтобы представить, что массивы и указатели как-то одинаковы. У меня была эта путаница, когда я написал эту запись в списке часто задаваемых вопросов.)

Ответ 1

  1.    Оператор "подписки на массив" [] работает так же хорошо для указателей, как и для массивов.

Нет, на самом деле это работает только для указателей. Всякий раз, когда вы вводите [] в выражении, вы всегда получаете указатель на первый элемент. Это гарантированно произойдет, поскольку arr[i] должен быть эквивалентен *(arr + i). Первый является "синтаксическим сахаром" для второго.

  1. Параметр функции, который выглядит как массив, фактически объявляет указатель.

На самом деле это особый случай, называемый "настройкой массива", когда компилятор неявно изменяет объявление параметра функции типа массива на указатель на первый элемент. Обоснование, безусловно, заключается в том, чтобы сделать функции совместимыми с "распадом массива" выражений, но стандарт C сохраняет термины отдельно.

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


(Мне не нравится термин "эквивалентность", потому что массив может превращаться в указатель, но не наоборот. Действительно, всегда есть бесчисленное множество новичков, которые приходят с запутанными убеждениями, такими как "массивы и указатели - это одно и то же". Вызывать их " Эквивалент "не совсем помогает.)

Ответ 2

В стандарте C нет ни одного слова для этого. Он использует слово "преобразование" при определении поведения (1) в 6.3.2.1p3 "эквивалентно" при определении поведения (2) в 6.5.2.1p2 и "настройке" при определении поведения (3) в 6.7.6.3p7.

Я старомодный, и не думаю, что что-то не так с вызовом этой "эквивалентности/указателя", если в контексте ясно, что вы говорите о выражениях, где (1) происходит или объявляется функция, где (3). Тем не менее, более приемлемый термин для людей, которые не любят "эквивалентность", возможно, будет "преобразованием массива в указатель", поскольку это смущает людей чаще всего, когда это (1), я думаю.

Ответ 3

Я бы пошел с термином распада массива. Этот термин хорошо сочетается с тем, что он предлагает. Стандарт C не говорит об этом в этом контексте, и да, в первый же день, когда я услышал этот термин, я пошел искать его в стандарте, но я не мог его найти (так что это немного запутывает, кто придумал термин и т.д.). Также в качестве альтернативы можно записать из-за "большинство сценариев преобразуется в указатель"... - Нет, это не одно Существительное. Но это не допускает каких-либо неправильных толкований. Сам стандарт говорит, что это "конверсия".

В большинстве случаев я пытаюсь сказать это длинным путем, а затем помещать слово ( "распад массива" ) в скобки. На самом деле есть ответы, в которых я даже не упоминал об этом, и просто пошел со стандартными словами преобразования в указатель.

Ответ 4

Я предлагаю "распад матрицы к указателю" является разумным сокращением, поскольку "распад" является обычным жаргоном в обращении к преобразованию типа, с прецедентом в другом месте в C FAQ: Вопрос 6.12:

Q: Поскольку ссылки массива распадаются на указатели, если arr является массивом, какая разница между arr и & arr?

Расширенное техническое значение "распада", которое включает этот, было принятой в номенклатуру стандартной библиотеки С++ с С++ 11: std::decay

Ответ 5

Нет единственного имени, указанного для трех упомянутых понятий, но я думаю, что их описание, подразумевающее какую-либо "эквивалентность", является контрпродуктивным, по крайней мере, при описании "современного" C. Хотя результаты распада массива обычно ведут себя как указатели, C99 указывает, что указатели, получаемые при распаде массива, не должны вести себя так же, как указатели, достигнутые с помощью других средств. Дано:

char fetch_byte_at(void *p, int x) { return ((char*)p)[x]; }

struct {char arr[5][7];} s;
char test1(int x) { return s.arr[0][x]; }
char test2(int x) { return fetch_byte_at(&s, x); }

В стандарте не указывается какая-либо причина, по которой значение указателя s.arr[0], используемое в test1, не должно быть эквивалентно значению указателя ((char*)(void*)s), используемому при вызове fetch_byte_at из test2. Тем не менее, он одновременно указывает, что test2 должен иметь возможность считывать все байты s [подразумевая, что он должен работать предсказуемо со значениями x, по крайней мере, до 34), говоря, что s.arr[0][x] только значение для значений x до 6.

В то время как ничто в Стандарте не противоречило ни одному из ваших первых двух пунктов в отдельности, невозможно, чтобы оба удерживались. Либо результат распада массива является чем-то иным, чем "обычным" указателем на первый элемент массива, либо применение оператора [] к массиву имеет другую семантику от применения его к указателю. Хотя неясно, какие из № 1 и № 2 были аннулированы C99, они больше не образуют какой-либо "эквивалентности" в современном C.

Если вы признаете различие между традиционным C и "современным" C, может быть полезно установить условия для вещей, которые делают бывшее полезным. Однако такие вещи выходят за пределы того, о которых вы говорите. К сожалению, я не знаю каких-либо стандартных терминов для таких вещей и не буду искать Стандарт для предоставления такой терминологии, когда она больше не поддерживает вовлеченные понятия.

Ответ 6

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

Многие люди серьезно задумались над этим вопросом, и я это ценю. Но на этом этапе я могу только заключить, что нет ответа, по крайней мере, сегодня на вопрос, который я имел в виду.

Довольно много людей предложили "распад массива", и это очень хороший снимок, но он не работает для меня. Это относится главным образом к факту 1 и, возможно, к факту 3, указанному в исходном вопросе, но не фактическому факту 2. Вы не можете сказать "Да, из-за распада массива, подтип массива можно рассматривать как синтаксический сахар для арифметики указателя". (Или, по крайней мере, вы не можете сказать, что если ваше намерение должно быть ясным и поучительным.) Вам нужно было бы сказать что-то вроде "Да, из-за распада массива и способа определения арифметики указателя, чтобы соответствовать он, подстрока массива, может считаться синтаксическим сахаром для арифметики указателя", который, конечно же, представляет собой совершенно другой чайник.

Несмотря на то, что я не сказал этого явно, я искал общий термин, широко распространенное, принятое использование, хотя не было требования, чтобы оно включало слова, фактически используемые в Стандарте. И учитывая, что никто не кашлял такой термин, учитывая, что все участвуют в определенном количестве спекуляций и "Что относительно...?", Я заключаю, что нет единого термина, широко используемого для концепции, лежащей в основе трио связанных факты. (За исключением "эквивалентности", которая исключается.)

Несколько ответчиков и комментаторов сказали это (что нет ни одного ответа) по-разному. Я собираюсь пойти дальше и принять ответ Лундина на этой основе, и потому что другим, похоже, понравилось это лучше всего.

Я, в будущем, я мог бы попробовать использовать "Соответствие между массивами и указателями в C" и посмотреть, будет ли он улавливать. Массивы и указатели отличаются от мужчин и женщин, и они на самом деле довольно далеки друг от друга, но часто обмениваются письмами.: -)

Ответ 7

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

По определению Oxford Online Dictionary слово Similar определяется как:

имеет сходство по внешнему виду, характеру или количеству, не будучи идентичным.

и слово Similitude как:

качество или состояние похожего на что-то.

Поскольку массивы и указатели не идентичны, но иногда обрабатываются аналогично, мы можем сказать:

Да, из-за массива/указателя сходства, подтипирование массива можно рассматривать как синтаксический сахар для арифметики указателя "

Ответ 8

Это может показаться абстрактным или философским вопросом, поэтому для более конкретного определения того, что я ищу, это простое существительное или именная фраза, в которой я мог бы использовать предложение "Да, из-за _____, подписка на массив может быть считающийся синтаксическим сахаром для арифметики указателя", в ответ на, скажем, этот вопрос.

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

Что, конечно, глупо, потому что причиной того, что подписка на массив является синтаксическим сахаром для арифметики указателя, состоит в том, что это именно то, что есть, это не требует дополнительного объяснения, если человек, которого вы так не говорите, знать, что означает "подписка на массив", "арифметика указателей" или "синтаксический сахар". Это не означает, что компилятор не знает разницы двух (он делает, потому что именно тот отвечает за весь синтаксический сахар, который вы получаете в результате).

Этот же вопрос может быть поднят обо всем, что делает любой язык для нас, что мы могли бы сделать сами, используя большее количество инструкций нижнего уровня и, как таковые, могли ссылаться на него с использованием нескольких терминов, которые изменяют только количество синтаксических сахар используется. Все дело в том, чтобы не притворяться, будто они разные (они всегда в пути, но это не так), но чтобы упростить программирование (просто подумайте о написании кода, не имея оператора [] в качестве синтаксического сахара для арифметики указателей и вы быстро понимаете причину своего существования - это не потому, что оно отличается, потому что проще писать, читать и управлять).

(Но, пожалуйста, обратите внимание, что я не ищу ответов на этот вопрос или ответов на вопрос "Что не так со словом" эквивалентность "?" Да, я знаю, он может ввести в заблуждение учащихся, чтобы представить, что массивы и указатели - это то же самое. Я имел это в виду, когда писал эту запись в списке часто задаваемых вопросов.)

Ваш вопрос кажется "Какой современный термин для эквивалентности указателя массива в том смысле, что подписка на массив - это просто синтаксический сахар для арифметики указателей?"

Ответ:

  • "Активация массива", когда вы используете оператор [] для индексации массива.
  • "Арифметика указателей", когда вы вручную перемещаете указатель (в отличие от использования оператора []). Вам также может показаться, что вы используете этот термин для любой математики, которую вы делаете, к значению, которое вы передаете оператору [], но вы на самом деле не выполняете арифметику указателей, а скорее "вычисляете индекс", что является термином для синтаксиса сахара, который автоматически учитывает размер объектов в памяти, которые автоматически учитываются для вас (что опять же не отличается, просто проще писать, читать и управлять, таким образом: синтаксический сахар).

Ответ 9

Стандарт использует термин, преобразованный в. Массив и эквивалентность указателя по-прежнему сохраняются лучше по массиву decay для указателей. Стандарт упоминает этот термин не где, но это просто взаимопонимание между программистами, что, когда речь идет о массивах и указателях, это считается эквивалентом массива и указателя. И что означает эквивалент указателя и массива: арифметика указателя и индексирование массива [,] эквивалентны в C, указатели и массивы разные..

Ответ 10

Я согласен, что такие термины, как "эквивалентность указателя/массива" или "распад массива" (в указатель), являются неточными и могут вводить в заблуждение.

Я бы предложил следующее:

Доступ к массиву с использованием оператора [] с индексом имеет эквивалентное арифметическое выражение указателя. Однако нет эквивалентности между указателем и массивом: я могу с радостью изменить значение указателя (содержимое), возможно, чтобы сохранить отдельный счетчик итераций, но я не могу сделать это с "затухающим" массивом; он неизменен и в некоторых отношениях демонстрирует поведение, аналогичное ссылкам C++.

Оба глагола "распадаться" и "преобразовывать" в английском языке неизменно указывают на то, что оригинал изменяется в процессе. Использование имени массива или унарного оператора '&' не меняет их операнд.

Следовательно, выражение типа "возвращает указатель" или "создает указатель" будет более точным. Это отражается в том факте, что в обоих случаях результирующий указатель является временной вещью, (обычно) сидящей в GP-регистре ЦП. и не может быть назначен на.

По крайней мере, это мое понимание, и мне кажется, что рассмотрение разборок подтверждает это.

Ответ 11

Если вы ссылаетесь на преобразование типа, почему бы не использовать термин литье? Обычно принято понимать, что компилятор принуждается к обработке двух связанных, но не одинаковых типов, как если бы они были желательным типом. Да, здесь есть эквивалентность, но "casting" используется как способ указать, что типы не являются буквально одинаковыми, но что компилятор должен рассматривать тип как другой тип и что процедура приемлема для компилятора, например up-casting for byte- > long

Второй выбор: "Синоним"