Zwiększanie wskaźników to idiomatyczne C ++, ponieważ semantyka wskaźników odzwierciedla podstawowy aspekt filozofii projektowania stojącej za standardową biblioteką C ++ (opartą na STL Aleksandra Stepanowa )
Ważną koncepcją jest to, że STL jest zaprojektowany wokół kontenerów, algorytmów i iteratorów. Wskaźniki są po prostu iteratorami .
Oczywiście, zdolność do zwiększania (lub dodawania / odejmowania) wskaźników wraca do C. Wiele algorytmów manipulacji ciągiem C można zapisać po prostu za pomocą arytmetyki wskaźnika. Rozważ następujący kod:
char string1[4] = "abc";
char string2[4];
char* src = string1;
char* dest = string2;
while ((*dest++ = *src++));
Ten kod używa arytmetyki wskaźnika do kopiowania łańcucha C zakończonego znakiem null. Pętla automatycznie kończy się, gdy napotka zero.
W C ++ semantyka wskaźników jest uogólniona na pojęcie iteratorów . Większość standardowych kontenerów C ++ zapewnia iteratory, do których można uzyskać dostęp za pomocą funkcji begin
i end
członków. Iteratory zachowują się jak wskaźniki, ponieważ mogą być zwiększane, usuwane, a czasem zmniejszane lub rozszerzane.
Aby powtórzyć std::string
, powiedzielibyśmy:
std::string s = "abcdef";
std::string::iterator it = s.begin();
for (; it != s.end(); ++it) std::cout << *it;
Zwiększamy iterator tak samo, jak zwiększamy wskaźnik do zwykłego ciągu C. Powodem, dla którego ta koncepcja jest potężna, jest to, że można używać szablonów do pisania funkcji, które będą działać dla dowolnego typu iteratora, który spełnia niezbędne wymagania dotyczące koncepcji. A to jest siła STL:
std::string s1 = "abcdef";
std::vector<char> buf;
std::copy(s1.begin(), s1.end(), std::back_inserter(buf));
Ten kod kopiuje ciąg do wektora. Ta copy
funkcja jest szablonem, który będzie działał z dowolnym iteratorem obsługującym inkrementację (w tym zwykłe wskaźniki). Możemy użyć tej samej copy
funkcji na zwykłym łańcuchu C:
const char* s1 = "abcdef";
std::vector<char> buf;
std::copy(s1, s1 + std::strlen(s1), std::back_inserter(buf));
Mogliśmy korzystać copy
na zasadzie std::map
albo std::set
czy jakiejkolwiek niestandardowego kontenera, który obsługuje iteratorów.
Zauważ, że wskaźniki są specyficznym typem iteratora: iterator o dostępie swobodnym , co oznacza, że obsługują one zwiększanie, zmniejszanie i przyspieszanie z operatorem +
i -
. Inne typy iteratorów obsługują tylko podzbiór semantyki wskaźnika: dwukierunkowy iterator obsługuje co najmniej zwiększanie i zmniejszanie; A forward iteracyjnej podpory przynajmniej zwiększany. (Wszystkie typy iteratorów obsługują dereferencje). Ta copy
funkcja wymaga iteratora, który przynajmniej obsługuje inkrementację.
Możesz przeczytać o różnych koncepcjach iteratora tutaj .
Zatem zwiększanie wskaźników jest idiomatycznym sposobem C ++ do iteracji po tablicy C lub uzyskiwania dostępu do elementów / przesunięć w tablicy C.