По-моему, это из электроники, разве нет?
С чего вообще это пошло?
-
9Предположим, что у вас есть массив из целых чисел, каждое по четыре байта. Массив расположен в памяти последовательно. Чтобы получить элемент N, надо взят указатель на массив и прибавить к нему (N - 1) * 4 байт, или, если вести отсчет от нуля, просто N * 4 байта – etki Aug 14 '16 at 18:12
-
1@Etki: А почему не как ответ? – VladD Aug 14 '16 at 18:17
-
В электронике отсчет ножек многих микросхем тоже начинаются с 0. Я думал это связано... – faoxis Aug 14 '16 at 18:17
-
@VladD потому что это просто мои догадки – etki Aug 14 '16 at 18:37
-
1На линейке первая цифра тоже 0! координата первого значения начинается с нулевой точки. – Андрей Шпилевой Aug 14 '16 at 19:09
-
1мне лень переводить, но большинство серьезных причин - приведено здесь https://www.quora.com/Why-do-array-indexes-start-with-0-zero-in-many-programming-languages/answer/Travis-Addair И там ссылка на статью Дейкстры – strangeqargo Aug 14 '16 at 19:38
-
вообще, почему изначально пошло - потому, что математики вряд ли стали бы исключать 0 как точку отсчета, а потом уже обоснования (типа приведенного выше пошли) – strangeqargo Aug 14 '16 at 19:52
-
В первом (или одном из первых) языке ВУ -- Фортране индексы массивов были с 1, в последующем -- (из широко известных) Алголе требовалось явно указывать граничные индексы, а вот в Си (не уверен, что он был первым) все это упростили (сделали с 0) и оно приняло привычные очертания... – avp Aug 14 '16 at 23:19
-
В Lua с 1 начинаются.. – Vladimir Gamalyan Aug 14 '16 at 23:44
1 Answers
В первую очередь потому, что с точки зрения реализации понятие "индекса" элемента в непрерывном агрегате напрямую связано с понятием "смещения" элемента от начала агрегата в памяти. Понятно, что смещение самого первого элемента агрегата равно нулю. Соответственно и индекс его разумно взять равным нулю.
Другими словами, как ни верти, но индекс первого элемента в агрегате все равно придется пересчитывать в значение 0 на машинном уровне. В такой ситуации реализация индексации с ненулевой базой будет всегда волей-неволей подразумевать неявное приведение ее к индексации с нулевой базой. В многих языках программирования просто не считают необходимым это делать. Зачем, действительно?
- 69,346
-
При выделении динамической памяти в C/C++ возвращаемый указатель не обязательно указывает на начало выделенного из кучи участка памяти. – hunter Aug 14 '16 at 23:09
-
@hunter: А какое это имеет значение в данном случае? Главное, чтобы указатель указывал на начало пользовательской области памяти, т.е. на ту точку, от которой будут отсчитываться смещения. А то, что блок может также содерждать какие-то служебные области со служебными данными к данному вопросу не относится никак. Что именно вы хотели сказать? – AnT stands with Russia Aug 14 '16 at 23:11
-
то и хочу сказать что даже при выделении не фрагментированной области памяти из указателя на нулевой элемент рано или поздно может возникнуть необходимость получить указатель на ячейку памяти с меньшим адресом. – hunter Aug 14 '16 at 23:17
-
@hunter: Прекрасно. Но какое это имеет отношение к теме индексации? "Ячейка с меньшим адресом" не является частью пользовательских данных, и доступаться к ней путем отрицательной индексации пользовательских данных никто не будет (в здравом уме). Такая область памяти будет прекрасно доступна путем вычета некоего известного платформе смещения из указателя "пользовательского" уровня и все. Я по прежнему не вижу, какое это все имеет отношение к рассматриваемой теме или к моему ответу. – AnT stands with Russia Aug 14 '16 at 23:22
-
@AnT, первым таким языком (по умолчанию индексы с 0) был Си? Или какой-то до него? – avp Aug 14 '16 at 23:22
-
3@avp: До языка С были языки B и BCPL с той же самой нулевой индексацией. Язык С унаследовал свой подход к массивам именно из B и BCPL, с одним важным изменением. В B и BCPL массивы физически реализовались через обычные указатели. В С физические указатели убрали, но стали их "эмулировать" (пресловутый "array type decay"). А все остальное в С осталось, как в B и BCPL именно для облегчения обратной совместимости с этими языками. – AnT stands with Russia Aug 14 '16 at 23:25
-
"В такой ситуации реализация индексации с ненулевой базой будет всегда волей-неволей подразумевать неявное приведение ее к индексации с нулевой базой." -- для указанного вами непрерывного агрегата это неявное приведение как раз и есть вычитание заранее известного смещения. Оно есть всегда, в т.ч. и при нулевой индексации. Разницы между разными индексациями нет. – hunter Aug 14 '16 at 23:48
-
@hunter: Это откуда же оно возьмется при нулевой индексации-то? Пусть у меня в руках есть указатель
pна начало моего агрегата. Пусть это массив с элементами размераs. Тогда при индексации по базе0доступ к i-тому элементу массива будет делаться по [байтовой] формулеp + i * s. Все. А для индексации по любой другой базеkформула будет иметь видp + (i - k) * sили, эквивалентно,p + i * s - K. Видите дополнительное вычитание? А при нулевой индексации его нет. – AnT stands with Russia Aug 15 '16 at 00:02 -
@AnT, "даже при выделении не фрагментированной области памяти из указателя на нулевой элемент рано или поздно может возникнуть необходимость получить указатель на ячейку памяти с меньшим адресом". В частности функция free() обращается к ячейке памяти с меньшим адресом, получая оттуда информацию о длине массива (благодаря этому ей для освобождения передаётся только указатель без размера освобождаемой памяти). – hunter Aug 15 '16 at 07:30
-
@hunter: И? К чему это? Я по-прежнему в упор не вижу связи того, что вы здесь повторяете, с темой дискуссии. Какое отношение к рассматриваемой теме имеет структура блока, выделенного
mallocи разбираемого потомfree? Мы говорим о доступе к элементам некоего пользовательского агрегата. При чем здесь то, что будет когда-то делатьfree? – AnT stands with Russia Aug 15 '16 at 07:33 -
@AnT, "вычитание заранее известного смещения. Оно есть всегда, в т.ч. и при нулевой индексации". Потому что до нулевого элемента есть полезная информация. "Это откуда же оно возьмется при нулевой индексации-то" -- вот при использовании free и возьмётся. Освобождать память рано или поздно всё равно придётся. – hunter Aug 15 '16 at 07:37
-
@hunter: Мое исходное утверждение заключается в том, что мы работаем с неким массивом
a[100]и в процессе выполняем массовую операцию доступа к элементамa[i]. Вот именно эта операция индексного доступа будет выполняться естественнее при нулевой индексации (по причинам, который я привел выше). А то, что когда-нибудь нам может понадобиться освободитьaчерезfreeи для этого доступиться по отрицательному смещению... нас это совершенно не заботит. Надо - доступимся. Не проблема. Нас эта одноразовая операция совершенно не волнует. Она никак не влияет на доступa[i]. – AnT stands with Russia Aug 15 '16 at 07:45 -
@AnT, "Вот именно эта операция индексного доступа", "Нас эта одноразовая операция совершенно не волнует." -- если вы хотите сказать что операция доступа по индексу выполняется чаще, чем операция освобождения, то вы 1) ограничили множество рассматриваемых программ 2) заставляете программиста выполнять вместо компилятора работу по оптимизации.
Отмечу что тот же Дейкстра (https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html) пишет о том, что такая индексация будет удобнее для человека, а не для компилятора.
– hunter Aug 15 '16 at 07:49 -
@hunter Я хочу сказать только то, что мой ответ базируется, как в нем сказано открытым текстом, именно и только на соображениях естественности реализации доступа к явным элементам пользовательского агрегатного типа. Ни больше, ни меньше. И я разрешаю Дийкстре иметь свои соображения по этому вопросу (пока они не противоречат моим, разумеется :) ) – AnT stands with Russia Aug 15 '16 at 08:02
-
@AnT, я хочу сказать только то, что заставлять программиста использовать определённый тип индексации только потому что он естественен при исполнении -- это всё равно что заставлять программиста писать на asm или сразу на машинных кодах. Всё равно ж компилировать будем в них :) – hunter Aug 15 '16 at 08:07
-
@hunter Сейчас - возможно. Но подход к индексации в языке С зарождался в те времена, когда он был существенно ближе к asm и ничего удивительного в том, чтобы при написании программ на С размышлять в терминах asm, никто не видел. Да и сегодня я не вижу в этом ничего зазорного, когда речь идет о С и С-подобных языках. – AnT stands with Russia Aug 15 '16 at 08:12