Pourquoi la déclaration de taille de tableau utilise-t-elle “1” comme premier index?

Quelque chose que j’ai remarqué à propos de C # / Java est ce problème apparemment incohérent avec la déclaration de taille de tableau et le premier index par défaut des tailles de tableau.

Lorsque vous travaillez avec des tableaux, supposons que vous vouliez créer un nouveau tableau de taille entière 3 , cela ressemblerait à ceci:

int[] newArray = new int[3] {1, 2, 3};

Totalement trouver et lisible … pas vrai?

La norme avec les langages de programmation semble indiquer que le “premier” index est 0 .

En utilisant cette logique, si je suis intéressé par la création d’un tableau de taille 3 , je devrais vraiment écrire ceci:

int[] newArray = new int[2] {1, 2, 3};

Attendez une minute .. VS génère une erreur, indiquant an array initialize of length 2 is expected .

Il y a donc une incohérence avec le premier index dans la boucle dans un tableau et dans la déclaration de taille de tableau? Le premier utilise un index basé sur 0 ème et le second un index sur 1 ème.

Ce n’est pas un jeu révolutionnaire / qui change de quelque manière que ce soit, mais je suis vraiment curieux de savoir pourquoi il y a une différence ici, ou alors, si c’est un problème du tout (comme je le dis, ce n’est pas une façon de briser le jeu, mais je suis curieux de savoir pourquoi cela se fait de cette façon).

Je peux à présent penser aux raisons pour lesquelles 1 index basé sur le 1 serait utilisé:

Dans une boucle for, vous utiliserez < newArray.Length par opposition à < newArray.Length - 1 ou < newArray.Length .

Travailler avec List s pendant un certain temps, puis revenir à la taille des tableaux dont la taille a besoin d’être déclarée, m’a pris un peu au dépourvu.

Je pense que vous confondez l’indexeur avec la longueur. Vous voulez contenir trois éléments (ou variables) dans votre tableau, notés par

 ...new int[3]... 

et les éléments dans les accolades sont les valeurs, pas l’index. L’index est toujours basé sur 0. Forme longue ressemblerait à ceci:

 int[] newArray = new int[3]; newArray[0] = 1; newArray[1] = 2; newArray[2] = 3; 

Ainsi, vous pouvez voir où se trouve votre index de base zéro par rapport aux valeurs de votre int [].

Parce que vous déclarez le tableau avec le nombre d’éléments qu’il contiendra.

Je ne sais pas à quel point cela est incompatible.

Combien de fois devez-vous scier pour couper une bille en 3 morceaux? Indice: pas 3 fois.

Notez également comment, dans le titre de votre message, vous vous référez incorrectement à la déclaration de taille de tableau sous le nom “index”.

 int[] newArray = new int[2] {1, 2, 3}; 

En anglais, cela vous traduirait “Je veux un conteneur pouvant contenir 2 éléments mais y mettre 3 éléments”. Vous confondez la longueur d’un tableau (le nombre d’éléments qu’il peut contenir) avec l’ index dans le tableau basé sur 0 dans les langages basés sur C (ex. C, C ++, C #, Java, Javascript, Swift).

En outre, considérez ce qu’est réellement un index de tableau (au moins avec des langages de bas niveau comme C); c’est un décalage en mémoire de l’adresse de base de votre variable tableau. Ainsi, arr[n] signifie “prenez l’adresse pour arr , avancez n * (the size of my type) octets en mémoire et donnez-moi la valeur correspondant à l’adresse calculée. Ainsi, lorsque n = 0, vous référencez la valeur à l’adresse mémoire de base (le début du tableau).

La réponse fournie par Wim Hollebrandse est absolument excellente et correcte, mais je voudrais développer un peu pour donner à OP un peu plus de compréhension du fait que les indices commencent par 0 dans la plupart des langues (mais pas toutes).

Comme l’a déclaré Wim, lors de la déclaration, il s’agit du nombre d’éléments stockés dans un tableau, ce qui est tout à fait acceptable pour la compréhension humaine. Ce qui en déconcerte beaucoup, c’est pourquoi le premier élément est en fait désigné par 0 (index 0) … La raison en est le calcul simple qui est nécessaire pour trouver un élément recherché dans un tableau.

Tous les éléments du tableau sont stockés séquentiellement dans un bloc contigu. Si le tableau se trouve par exemple à l’adresse 100 et contient des nombres entiers (chaque nombre entier étant de 4 octets), alors, lors de la recherche du tout premier élément, il se situerait au début du tableau, à l’adresse 100. Le second sera stocké immédiatement après la première adresse, ou 100 + 4 = 104 adresses. Le 3ème article est stocké après le 2ème ou à l’adresse 108.

Donc, pour calculer la position du I-ième élément, si les indices commencent par 0, le calcul est simple:

 I-th-address = address_of_array + I * sizeof(datatype) eg for our example it is 100 + i * 4 

si les indices commencent par 1, alors le calcul nécessite plus d’opérations:

 Ith-address - address of array + (I-1) * sizeof(datatype) 

… qui est moins efficace et inutile que le 0.

Vous mélangez la déclaration du tableau avec la demande d’un élément de tableau. Lors de la déclaration d’un tableau, vous spécifiez la longueur du tableau (nombre d’éléments), et la valeur est 3, correct. Lorsque vous demandez un élément, vous spécifiez l’ index et le premier index est 0. Toutefois, vous ne devez pas mélanger l’index et la longueur du tableau.

Dans une boucle for, vous devez prendre < newArray.Length : si vous avez une longueur de 3, la boucle commencera à 0 et passera par les index 0, 1 et 2. Ensuite, elle s'arrête car 3 n'est pas <3.