Pourquoi l’indexation commence-t-elle par zéro dans ‘C’?

Pourquoi l’indexation dans un tableau commence-t-elle par zéro dans C et non par 1?

Dans C, le nom d’un tableau est essentiellement un pointeur, une référence à un emplacement de mémoire, et le tableau d’expression [n] fait référence à un emplacement mémoire de n éléments à partir de l’élément de départ. Cela signifie que l’index est utilisé comme décalage. Le premier élément du tableau est exactement contenu dans l’emplacement de mémoire auquel le tableau fait référence (0 éléments à distance), il convient donc de le nommer array [0].

pour plus d’informations:

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

Cette question a été postée il y a plus d’un an, mais voilà …


À propos des raisons ci-dessus

Bien que l’article de Dijkstra (précédemment référencé dans une réponse maintenant supprimée) ait du sens d’un sharepoint vue mathématique, il n’est pas aussi pertinent en matière de programmation.

La décision prise par les spécifications de langage et les concepteurs-compilateurs repose sur la décision prise par les concepteurs de systèmes informatiques de commencer à compter à 0.


La raison probable

Citant un plaidoyer pour la paix de Danny Cohen.

  • Lien IEEE
  • IEN-137

Pour toute base b, les premiers nombres entiers non négatifs b ^ N sont représentés par exactement N chiffres (zéros compris) uniquement si la numérotation commence à 0.

Cela peut être testé assez facilement. En base 2, prenez 2^3 = 8 Le 8ème chiffre est:

  • 8 (binary: 1000) si on commence à compter à 1
  • 7 (binary: 111) si on commence à compter à 0

111 peut être représenté en utilisant 3 bits, tandis que 1000 nécessitera un bit supplémentaire (4 bits).


Pourquoi est-ce pertinent

Les adresses de mémoire de l’ordinateur ont 2^N cellules adressées par N bits. Maintenant, si on commence à compter à 1, 2^N cellules auront besoin de N+1 lignes d’adresse. Le bit supplémentaire est nécessaire pour accéder exactement à 1 adresse. ( 1000 dans le cas ci-dessus.). Une autre manière de le résoudre serait de laisser la dernière adresse inaccessible et d’utiliser les lignes d’adresse N

Les deux sont des solutions sous-optimales , comparées au compte initial à 0, ce qui permettrait de garder toutes les adresses accessibles, en utilisant exactement N lignes d’adresse!


Conclusion

La décision de commencer à compter à 0 , a depuis imprégné tous les systèmes numériques , y compris les logiciels qui les exécutent, car cela simplifie la traduction du code en fonction de ce que le système sous-jacent peut interpréter. Si ce n’était pas le cas, il y aurait une opération de traduction inutile entre la machine et le programmeur, pour chaque access au tableau. Cela facilite la compilation.


Citation de l’article:

entrer la description de l'image ici

Parce que 0 est la distance entre le pointeur vers la tête du tableau et le premier élément du tableau.

Considérer:

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

Pour accéder à 0 on fait:

 foo[0] 

Mais foo se décompose en un pointeur, et l’access ci-dessus a une manière arithmétique de pointeur analogue pour y accéder

 *(foo + 0) 

Ces jours-ci, l’arithmétique du pointeur n’est pas utilisée aussi fréquemment. Il y a longtemps, cependant, c’était un moyen pratique de prendre une adresse et de déplacer X “ints” loin de ce sharepoint départ. Bien sûr, si vous vouliez simplement restr où vous êtes, il vous suffit d’append 0!

Parce que l’index basé sur 0 permet …

 array[index] 

… à mettre en oeuvre comme …

 *(array + index) 

Si index était basé sur 1, le compilateur devrait générer: *(array + index - 1) , et ce “-1” nuirait aux performances.

Parce que cela simplifiait le compilateur et l’éditeur de liens (plus facile à écrire).

Référence :

“… Le référencement de la mémoire par une adresse et un décalage est représenté directement dans le matériel sur quasiment toutes les architectures informatiques, ce qui facilite la compilation dans ce détail de conception en C”

et

“… cela permet une implémentation plus simple …”

Pour la même raison que mercredi et que quelqu’un vous demande combien de jours jusqu’à mercredi, vous dites 0 plutôt que 1, et que mercredi et que quelqu’un vous demande combien de jours jusqu’à jeudi, vous dites 1 plutôt que 2.

L’explication la plus élégante que j’ai lue pour la numérotation basée sur zéro est une observation selon laquelle les valeurs ne sont pas stockées aux endroits marqués sur la droite numérique, mais plutôt dans les espaces entre elles. Le premier élément est stocké entre zéro et un, le prochain entre un et deux, etc. Le Nième élément est stocké entre N-1 et N. Une série d’éléments peut être décrite en utilisant les nombres de chaque côté. Les articles individuels sont décrits par convention en utilisant les chiffres ci-dessous. Si on donne une plage (X, Y), identifier des nombres individuels en utilisant le nombre ci-dessous signifie que l’on peut identifier le premier object sans utiliser d’arithmétique (c’est l’article X) mais il faut en soustraire un. -1). Identifier les éléments à l’aide du numéro ci-dessus faciliterait l’identification du dernier élément d’une plage (ce serait l’article Y), mais plus difficile d’identifier le premier (X + 1).

Bien qu’il ne soit pas horrible d’identifier les éléments en fonction du nombre au-dessus d’eux, définir le premier élément de la plage (X, Y) comme étant au-dessus de X est généralement plus intéressant que de le définir ci-dessous (X + 1).

L’index de tableau commence toujours par zéro. Supposons que l’adresse de base est 2000. Maintenant arr[i] = *(arr+i) . Maintenant, if i= 0 , cela signifie que *(2000+0 ) est égal à l’adresse de base ou l’adresse du premier élément du tableau. cet index est traité comme un offset, donc l’index bydeafault commence à zéro.

La raison technique peut provenir du fait que le pointeur sur un emplacement mémoire d’un tableau est le contenu du premier élément du tableau. Si vous déclarez le pointeur avec un index de un, les programmes appendaient normalement cette valeur de un au pointeur pour accéder au contenu qui n’est pas ce que vous voulez, bien sûr.

Essayez d’accéder à un écran de pixels en utilisant les coordonnées X, Y sur une masortingce à 1 base. La formule est extrêmement complexe. Pourquoi est complexe? Parce que vous finissez par convertir les coordonnées X, Y en un seul nombre, le décalage. Pourquoi devez-vous convertir X, Y en offset? Parce que c’est ainsi que la mémoire est organisée à l’intérieur des ordinateurs, sous la forme d’un stream continu de cellules mémoire (tableaux). Comment les ordinateurs traitent-ils les cellules de tableau? Utiliser des décalages (déplacements de la première cellule, modèle d’indexation basé sur zéro).

Donc, à un moment donné du code, vous avez besoin (ou du compilateur) pour convertir la formule à une base en une formule à base de 0, car c’est ainsi que les ordinateurs traitent la mémoire.

Le nom du tableau est un pointeur constant qui pointe vers l’adresse de base. Lorsque vous utilisez arr [i], le compilateur le manipule comme * (arr + i). Puisque la plage int est comprise entre -128 et 127, le compilateur pense que -128 à -1 les nombres négatifs et 0 à 128 sont des nombres positifs. L’index du tableau commence toujours par zéro.

becoz quand on accède aux éléments du tableau La formule suivante est utilisée par le compilateur ((adresse de base) + taille de l’index *) L’élément fisrt est toujours stocké à l’adresse de base dans les tableaux … adresse de l’élément sesond … donc ça commence par 0.