it-roy-ru.com

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

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

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

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

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

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

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

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

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

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

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

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

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


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

26
Lundin

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

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

13
zwol

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

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

9
coderredoc

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

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

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

5
Mike Kinghan

Трем упомянутым концепциям не дано ни одного названия, но я думаю, что описывать их как подразумевающие какую-либо «эквивалентность» контрпродуктивно, по крайней мере при описании «современного» 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, может быть полезно установить термины для вещей, которые делают первое полезным. Однако такие вещи выходят за рамки упомянутых вами вопросов. К сожалению, я не знаю каких-либо стандартных терминов для таких вещей и не буду искать Стандарт для предоставления такой терминологии, когда он больше не поддерживает соответствующие концепции.

5
supercat

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

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

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

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

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

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

2
Steve Summit

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

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

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

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

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

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

Ответ:

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

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

По определению Оксфордского онлайн-словаря слово Similar определяется как:

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

и слово Similitude как:

качество или состояние сходства с чем-то.

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

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

1
machine_1

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

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

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

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

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

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

0
GermanNerd

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

0
haccks