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

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

Ответ 1

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

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

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

Ответ 2

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


Об приведенных выше причинах

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

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


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

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

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

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

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

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


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

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

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


Заключение

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


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

enter image description here

Ответ 3

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

Рассмотрим:

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

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

foo[0] 

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

*(foo + 0)

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

Ответ 4

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

array[index]

... будет реализован как...

*(array + index)

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

Ответ 5

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

Ссылка:

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

и

"... это упрощает реализацию..."

Ответ 6

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

Ответ 7

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

Ответ 8

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

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

Ответ 9

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

Ответ 10

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

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

Ответ 11

Предположим, мы хотим создать массив размером 5
массив int [5] = [2,3,5,9,8]

пусть 1-й элемент массива указан в месте 100

и пусть мы считаем, что индексация начинается с 1, а не с 0.

теперь мы должны найти местоположение 1-го элемента с помощью индекса
(помните, что расположение 1-го элемента равно 100)

так как размер целого числа 4-битный
следовательно → с учетом индекса 1 позиция будет
размер индекса (1) * размер целого числа (4) = 4
поэтому фактическая позиция, которую он нам покажет,

100 + 4 = 104

что не соответствует действительности, поскольку первоначальное местоположение было на уровне 100.
 он должен указывать на 100, а не на 104
это неправильно

Теперь предположим, что мы взяли индекс с 0
тогда
позиция 1-го элемента должна быть
размер индекса (0) * размер целого числа (4) = 0

следовательно ->
расположение первого элемента: 100 + 0 = 100

и это было фактическое местоположение элемента
Вот почему индексация начинается с 0;

Я надеюсь, что это прояснит вашу точку зрения.

Ответ 12

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

Основные шаги:

  1. Создание ссылки
  2. Создание массива
  3. Распределение данных в массиве

  • Также обратите внимание, когда массив только что создан... Ноль выделяется все блоки по умолчанию, пока мы не назначим значение для него
  • Массив начинается с нуля, потому что первый адрес будет указывать на ссылка (i: e - X102 + 0 на изображении)

enter image description here

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

Ответ 13

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

ex. int arr[2] = {5,4};

считайте, что массив начинается с адреса 100 поэтому элемент первый элемент будет по адресу 100, а второй будет по адресу 104 в настоящее время, Учтите, что если индекс массива начинается с 1, то

arr[1]:-

это можно записать в выражении указателей, например this-

 arr[1] = *(arr + 1 * (size of single element of array));

рассмотрим размер int 4 байта, теперь,

arr[1] = *(arr + 1 * (4) );
arr[1] = *(arr + 4);

как мы знаем, имя массива содержит адрес его первого элемента, поэтому arr = 100 Теперь,

arr[1] = *(100 + 4);
arr[1] = *(104);

который дает,

arr[1] = 4;

из-за этого выражения мы не можем получить доступ к элементу по адресу 100, который является официальным первым элементом,

Теперь рассмотрим индекс массива, начинающийся с 0, поэтому

arr[0]:-

это будет решено как

arr[0] = *(arr + 0 + (size of type of array));
arr[0] = *(arr + 0 * 4);
arr[0] = *(arr + 0);
arr[0] = *(arr);

теперь мы знаем, что имя массива содержит адрес его первого элемента так,

arr[0] = *(100);

который дает правильный результат

arr[0] = 5;

поэтому индекс массива всегда начинается с 0 в c.

справка: все подробности написаны в книге "Язык программирования С Брайана Кернингхана и Денниса Ричи"

Ответ 14

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

Ответ 15

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