L'incrémentation des pointeurs est idiomatique en C ++, car la sémantique des pointeurs reflète un aspect fondamental de la philosophie de conception derrière la bibliothèque standard C ++ (basée sur la STL d'Alexander Stepanov )
Le concept important ici est que la STL est conçue autour de conteneurs, d'algorithmes et d'itérateurs. Les pointeurs sont simplement des itérateurs .
Bien sûr, la possibilité d'incrémenter (ou d'ajouter / de soustraire) des pointeurs remonte à C. De nombreux algorithmes de manipulation de chaîne C peuvent être écrits simplement en utilisant l'arithmétique des pointeurs. Considérez le code suivant:
char string1[4] = "abc";
char string2[4];
char* src = string1;
char* dest = string2;
while ((*dest++ = *src++));
Ce code utilise l'arithmétique du pointeur pour copier une chaîne C terminée par un caractère nul. La boucle se termine automatiquement lorsqu'elle rencontre le null.
Avec C ++, la sémantique des pointeurs est généralisée au concept d' itérateurs . La plupart des conteneurs C ++ standard fournissent des itérateurs, accessibles via les fonctions membres begin
et end
. Les itérateurs se comportent comme des pointeurs, en ce sens qu'ils peuvent être incrémentés, déréférencés et parfois décrémentés ou avancés.
Pour parcourir un std::string
, nous dirions:
std::string s = "abcdef";
std::string::iterator it = s.begin();
for (; it != s.end(); ++it) std::cout << *it;
Nous incrémentons l'itérateur comme nous incrémenterions un pointeur sur une chaîne en C simple. La raison pour laquelle ce concept est puissant est que vous pouvez utiliser des modèles pour écrire des fonctions qui fonctionneront pour tout type d'itérateur qui répond aux exigences de concept nécessaires. Et c'est la puissance de la STL:
std::string s1 = "abcdef";
std::vector<char> buf;
std::copy(s1.begin(), s1.end(), std::back_inserter(buf));
Ce code copie une chaîne dans un vecteur. La copy
fonction est un modèle qui fonctionnera avec tout itérateur qui prend en charge l'incrémentation (qui inclut des pointeurs simples). Nous pourrions utiliser la même copy
fonction sur une chaîne C simple:
const char* s1 = "abcdef";
std::vector<char> buf;
std::copy(s1, s1 + std::strlen(s1), std::back_inserter(buf));
Nous pourrions utiliser copy
sur un std::map
ou un std::set
ou tout conteneur personnalisé prenant en charge les itérateurs.
Notez que les pointeurs sont un type spécifique d'itérateur: itérateur à accès aléatoire , ce qui signifie qu'ils prennent en charge l'incrémentation, la décrémentation et l'avancement avec l' opérateur +
et -
. D'autres types d'itérateurs ne prennent en charge qu'un sous-ensemble de sémantique de pointeur: un itérateur bidirectionnel prend en charge au moins l'incrémentation et la décrémentation; un itérateur direct prend en charge au moins l'incrémentation. (Tous les types d'itérateurs prennent en charge le déréférencement.) La copy
fonction nécessite un itérateur qui prend au moins en charge l'incrémentation.
Vous pouvez lire sur les différents concepts de iterator ici .
Ainsi, l'incrémentation de pointeurs est une façon idiomatique C ++ d'itérer sur un tableau C ou d'accéder à des éléments / décalages dans un tableau C.