2 votes

Comment les itérateurs trouvent l'adresse suivante dans une liste chaînée.

Je viens d'un milieu C.

Lorsque l'on itère dans un conteneur tel qu'un vecteur ou un deque qui contient des éléments dans une mémoire contiguë, il est facile de comprendre qu'en incrémentant l'itérateur pour pointer sur l'élément suivant dans le vecteur, comme dans la boucle ci-dessous, on peut juste augmenter l'adresse de l'itérateur par la taille de l'élément dans le vecteur, dans ce cas int.

vector<int> vec;
vector<int>::iterator it;

for (it = vec.begin; it != vec.end(); it++)
{
    // do something on each element

}

L'avantage de l'utilisation des itérateurs est que nous pouvons découpler le code de l'algorithme du type de conteneur réel. Ainsi, si nous décidons plus tard d'utiliser une liste au lieu d'un vecteur, nous pouvons utiliser le même code d'itération que ci-dessus sur la liste.

Il est possible d'itérer dans une liste exactement de la même manière, mais une liste aura des éléments qui ne se trouvent pas dans des emplacements mémoire contigus, alors comment l'itérateur s'incrémente-t-il et trouve-t-il l'adresse correcte de l'élément suivant ?

D'après ce que j'ai compris de l'implémentation des listes liées en C, nous vérifions le pointeur dans le nœud, éventuellement appelé "next", qui pointe vers le nœud suivant de la liste.

Est-ce que c'est exactement ce qui se passe ici en C++ dans les coulisses lors de l'utilisation des itérateurs de liste ? Par conséquent, lorsqu'un itérateur pointe sur un élément de liste, afin de pointer sur l'élément suivant, le compilateur génère un code complètement différent de celui qui pointe sur l'élément suivant dans un vecteur ? Merci d'avance.

1voto

Davis Herring Points 7254

Vous avez la bonne idée. Le point critique est ici :

quand un itérateur pointe sur un élément de liste

Une meilleure formulation serait "pour une genre d'itérateur utilisé avec une liste chaînée" : aucun itérateur ne peut indiquer un élément d'une liste chaînée vector ou a list .

Parce que chaque type de conteneur possède son propre itérateur type et le type utilisé est toujours connu du compilateur, le code correct peut être généré (et optimisé !) dans tous les cas. (Le code générique peut être écrit sans types explicites, mais les types doivent être spécifiés (ou dans certains cas déduits par le compilateur) pour chaque utilisation).

Notez que tous les types d'itérateurs ne sont pas implémentés en utilisant (uniquement) un pointeur : par exemple, un itérateur de type deque<T>::iterator regroupe généralement un pointeur vers un tableau court et un index dans ce tableau. Le système de modèles prend également en charge cette variation de taille et de composition entre les types de données avec les opérations correspondantes.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X