¿Por qué la indexación comienza con cero en ‘C’?

¿Por qué la indexación en una matriz comienza con cero en C y no en 1?

En C, el nombre de una matriz es esencialmente un puntero, una referencia a una ubicación de memoria, por lo que la matriz de expresión [n] se refiere a una ubicación de memoria n-elementos lejos del elemento de inicio. Esto significa que el índice se usa como un desplazamiento. El primer elemento de la matriz se encuentra exactamente en la ubicación de memoria a la que se refiere la matriz (0 elementos de distancia), por lo que debe designarse como matriz [0].

para más información:

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

Esta pregunta fue publicada hace más de un año, pero aquí va …


Sobre los motivos anteriores

Si bien el artículo de Dijkstra (anteriormente mencionado en una respuesta ahora eliminada) tiene sentido desde una perspectiva matemática, no es tan relevante cuando se trata de progtwigción.

La decisión tomada por la especificación del lenguaje y los comstackdores-diseñadores se basa en la decisión tomada por los diseñadores de sistemas informáticos de comenzar a contar en 0.


La razón probable

Citando de una súplica por la paz de Danny Cohen.

  • Enlace IEEE
  • IEN-137

Para cualquier base b, los primeros enteros b ^ N no negativos se representan con exactamente N dígitos (incluidos los ceros a la izquierda) solo si la numeración comienza en 0.

Esto se puede probar con bastante facilidad. En base-2, tome 2^3 = 8 El octavo número es:

  • 8 (binario: 1000) si comenzamos a contar en 1
  • 7 (binario: 111) si comenzamos a contar en 0

111 se puede representar utilizando 3 bits, mientras que 1000 requerirá un bit adicional (4 bits).


Por qué es esto relevante

Las direcciones de memoria de la computadora tienen 2^N celdas dirigidas por N bits. Ahora, si comenzamos a contar a 1, 2^N células necesitarían N+1 líneas de dirección. El bit adicional es necesario para acceder exactamente a 1 dirección. ( 1000 en el caso anterior). Otra forma de resolverlo sería dejar la última dirección inaccesible y usar N líneas de dirección.

Ambas son soluciones por debajo de lo óptimo , en comparación con el recuento de inicio en 0, lo que mantendría todas las direcciones accesibles, ¡usando exactamente N líneas de dirección!


Conclusión

La decisión de comenzar a contar en 0 , desde entonces ha impregnado todos los sistemas digitales , incluido el software que se ejecuta en ellos, porque hace que sea más fácil para el código traducir lo que el sistema subyacente puede interpretar. Si no fuera así, habría una operación de traducción innecesaria entre la máquina y el progtwigdor, para cada acceso a la matriz. Hace la comstackción más fácil.


Citando del periódico:

enter image description here

Porque 0 es qué tan lejos del puntero a la cabeza de la matriz al primer elemento de la matriz.

Considerar:

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

Para acceder a 0 hacemos:

 foo[0] 

Pero foo se descompone en un puntero, y el acceso anterior tiene una forma aritmética de puntero análogo para acceder a él

 *(foo + 0) 

En estos días, la aritmética del puntero no se usa con tanta frecuencia. Sin embargo, mucho antes, era una manera conveniente de tomar una dirección y mover X “ints” lejos de ese punto de partida. Por supuesto, si solo quieres quedarte donde estás, ¡simplemente agrega 0!

Porque el índice basado en 0 permite …

 array[index] 

… para ser implementado como …

 *(array + index) 

Si el índice estuviera basado en 1, el comstackdor necesitaría generar: *(array + index - 1) , y este “-1” dañaría el rendimiento.

Porque hizo el comstackdor y el enlazador más simple (más fácil de escribir).

Referencia :

“… Hacer referencia a la memoria mediante una dirección y un desplazamiento se representa directamente en hardware en prácticamente todas las architectures de la computadora, por lo que este detalle de diseño en C facilita la comstackción”

y

“… esto hace una implementación más simple …”

Por la misma razón que, cuando es miércoles y alguien te pregunta cuántos días hasta el miércoles, dices 0 en lugar de 1, y que cuando es miércoles y alguien te pregunta cuántos días hasta el jueves, dices 1 en lugar de 2.

La explicación más elegante que he leído para la numeración basada en cero es una observación de que los valores no se almacenan en los lugares marcados en la recta numérica, sino más bien en los espacios entre ellos. El primer elemento se almacena entre cero y uno, el siguiente entre uno y dos, etc. El artículo enésimo se almacena entre N-1 y N. Se puede describir un rango de elementos usando los números de cada lado. Los artículos individuales se describen por convención usando los números debajo de él. Si a uno se le da un rango (X, Y), identificar números individuales usando el número a continuación significa que uno puede identificar el primer elemento sin usar ninguna aritmética (es el ítem X) pero debe restar uno de Y para identificar el último ítem (Y -1). Identificar elementos usando el número anterior facilitaría la identificación del último elemento en un rango (sería el elemento Y), pero sería más difícil identificar el primero (X + 1).

Aunque no sería horrible identificar elementos basados ​​en el número que está sobre ellos, definir el primer elemento en el rango (X, Y) como el que está encima de X generalmente funciona mejor que definirlo como el siguiente (X + 1).

El índice de matriz siempre comienza con cero. Supongamos que la dirección base es 2000. Ahora arr[i] = *(arr+i) . Ahora bien, if i= 0 , esto significa que *(2000+0 ) es igual a la dirección base o la dirección del primer elemento en la matriz. este índice se trata como compensación, por lo que el índice predeterminado comienza desde cero.

La razón técnica podría derivar del hecho de que el puntero a una ubicación de memoria de una matriz es el contenido del primer elemento de la matriz. Si declara el puntero con un índice de uno, los progtwigs normalmente agregarían ese valor de uno al puntero para acceder al contenido que no es lo que desea, por supuesto.

Intente acceder a una pantalla de píxeles usando coordenadas X, Y en una matriz basada en 1. La fórmula es completamente compleja. ¿Por qué es complejo? Porque terminas convirtiendo las coordenadas X, Y en un número, el desplazamiento. ¿Por qué necesita convertir X, Y en un desplazamiento? Porque así es como se organiza la memoria dentro de las computadoras, como una stream continua de celdas de memoria (matrices). ¿Cómo manejan las computadoras las celdas de matriz? Usar compensaciones (desplazamientos desde la primera celda, un modelo de indexación basado en cero).

Entonces, en algún punto del código necesita (o el comstackdor necesita) convertir la fórmula de 1 base en una fórmula basada en 0 porque así es como las computadoras manejan la memoria.

El nombre de matriz es un puntero constante que apunta a la dirección base. Cuando usa arr [i] el comstackdor lo manipula como * (arr + i). Dado que el rango int es -128 a 127, el comstackdor cree que -128 a -1 son los números negativos y 0 a 128 son números positivos. Por lo tanto, el índice de matriz siempre comienza con cero.

antes de acceder a los elementos del array, la siguiente fórmula es utilizada por el comstackdor ((dirección base) + índice * tamaño). El elemento fisrt siempre se almacena en la dirección base en matrices … Así que si comenzamos con 1 no podemos acceder al primer elemento dado dirección del elemento sesond … entonces comienza con 0.