Почему индексирование начинается с нуля в ‘C’?

Почему индексирование в массиве начинается с нуля в C, а не с 1?

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

для получения дополнительной информации:

http://developeronline.blogspot.com/2008/04/why-array-index-should-start-from-0.html

Этот вопрос был опубликован более года назад, но здесь идет …


По вышеуказанным причинам

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

Решение, принятое спецификацией языка и составителями-компиляторами, основано на решении, принятом компьютерными системными дизайнерами, начать отсчет в 0.


Вероятная причина

Цитата из просьбы о помощи Дэнни Коэна.

  • IEEE Link
  • МЭС-137

Для любой базы b первые b ^ N неотрицательные целые числа представлены ровно N числами (включая начальные нули), только если нумерация начинается с 0.

Это можно протестировать довольно легко. В базе-2 возьмите 2^3 = 8 е число:

  • 8 (двоичный: 1000), если мы начнем считать 1
  • 7 (двоичный: 111), если мы начнем считать 0

111 может быть представлено с использованием 3 бит, тогда как 1000 потребует дополнительный бит (4 бита).


Почему это релевантно

Адреса компьютерной памяти имеют ячейки 2^N адресуемые N битами. Теперь, если мы начнем считать в ячейках 1, 2^N , потребуется N+1 адресных строк. Дополнительный бит необходим для доступа только к одному адресу. ( 1000 в вышеуказанном случае). Другим способом решения этого вопроса было бы оставить последний адрес недоступным и использовать N адресных строк.

Оба являются субоптимальными решениями по сравнению с начальным счетом в 0, что позволило бы сохранить все адреса, используя ровно N адресных строк!


Вывод

Решение начать отсчет в 0 , с тех пор пронизывает все цифровые системы , включая программное обеспечение, запущенное на них, потому что это упрощает перевод кода на то, что может интерпретировать базовая система. Если бы это было не так, была бы одна ненужная операция перевода между машиной и программистом для каждого доступа к массиву. Это облегчает компиляцию.


Цитата из статьи:

введите описание изображения здесь

Потому что 0 – это то, как далеко от указателя на голову массива к первому элементу массива.

Рассматривать:

 int foo[5] = {1,2,3,4,5}; 

Для доступа к 0 мы делаем:

 foo[0] 

Но foo распадается на указатель, а вышеприведенный доступ имеет аналогичный арифметический способ указателя на доступ к нему

 *(foo + 0) 

В наши дни арифметика указателей не используется так часто. Если вернуться назад, это был удобный способ взять адрес и переместить X «ints» в сторону от этой начальной точки. Конечно, если вы хотите просто остаться там, где находитесь, просто добавьте 0!

Потому что индекс, основанный на 0, позволяет …

 array[index] 

… для реализации …

 *(array + index) 

Если индекс был основан на 1, компилятор должен был бы генерировать: *(array + index - 1) , и этот «-1» повредил бы производительность.

Потому что это упростило компилятор и компоновщик (проще писать).

Ссылка :

«… Ссылка на память по адресу и смещению представляется непосредственно в аппаратных средствах практически на всех компьютерных архитектурах, поэтому эта деталь дизайна на C упрощает компиляцию»

а также

«… это упрощает реализацию …»

По той же причине, когда в среду, и кто-то спрашивает вас, сколько дней до среды, вы говорите 0, а не 1, и что, когда в среду, и кто-то спрашивает вас, сколько дней до четверга, вы говорите 1, а не 2.

Наиболее изящное объяснение, которое я прочитал для нулевой нумерации, – это наблюдение, что значения не сохраняются в отмеченных местах на числовой строке, а в промежутках между ними. Первый элемент хранится между нулем и одним, следующим между одним и двумя и т. Д. N-й элемент хранится между N-1 и N. Диапазон номеров может быть описан с использованием номеров с обеих сторон. Отдельные предметы описываются по номерам, приведенным ниже. Если задан диапазон (X, Y), идентификация отдельных чисел с использованием номера ниже означает, что можно идентифицировать первый элемент без использования какой-либо арифметики (это элемент X), но нужно вычесть один из Y для определения последнего элемента (Y -1). Идентификация элементов с использованием приведенного выше номера упростит идентификацию последнего элемента в диапазоне (это будет элемент Y), но сложнее определить первый (X + 1).

Хотя было бы нехорошо идентифицировать элементы, основанные на числе выше них, определение первого элемента в диапазоне (X, Y) как одного из выше X обычно работает более красиво, чем определение его как следующего ниже (X + 1).

Индекс массива всегда начинается с нуля. Предположим, что базовый адрес равен 2000. Теперь arr[i] = *(arr+i) . Теперь, if i= 0 , это означает, что *(2000+0 ) равен базовому адресу или адресу первого элемента в массиве. этот индекс обрабатывается как смещение, поэтому индекс bydeafault начинается с нуля.

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

Попробуйте получить доступ к экрану пикселей, используя координаты X, Y в матрице на основе 1. Формула совершенно сложна. Почему сложно? Поскольку вы в конечном итоге конвертируете координаты X, Y в одно число, смещение. Почему вам нужно преобразовать X, Y в смещение? Так как память организована внутри компьютеров, как непрерывный stream ячеек памяти (массивов). Как компьютеры работают с ячейками массива? Использование смещений (перемещение из первой ячейки, модель индексации на основе нуля).

Поэтому в какой-то момент кода, который вам нужен (или компилятор), чтобы преобразовать формулу 1-base в формулу, основанную на 0, потому что это то, как компьютеры справляются с памятью.

Имя массива – это указатель константы, указывающий на базовый адрес. Когда вы используете arr [i], компилятор манипулирует им как * (arr + i). Поскольку диапазон int от -128 до 127, компилятор считает, что -128 -1 отрицательные числа и от 0 до 128 – положительные числа. Индекс массива всегда начинается с нуля.

becoz, когда мы обращаемся к элементам массива, следующая формула используется компилятором ((базовый адрес) + индекс * размер). Элемент fisrt всегда хранится в базовом адресе в массивах … Поэтому, если мы начинаем с 1, мы не можем получить доступ к первому элементу, поскольку он дает адрес элемента sesond … поэтому он начинается с 0.

  • Как работает sizeof (Array)
  • Давайте будем гением компьютера.