Jeśli mam dwie zmienne wskaźnikowe, aib, co to znaczy używać instrukcji "a < b"? Czy powinno to porównywać wartości ich adresów pamięci? Jeśli tak, jaka byłaby kolejność adresów pamięci w komputerze?Co to znaczy porównywanie wskaźników za pomocą operatorów relacyjnych?
Odpowiedz
W językach C i C++ porównywanie wskaźników za pomocą operatorów relacyjnych jest dozwolone w przypadku, gdy masz dwa wskaźniki w tej samej tablicy i chcesz zobaczyć ich względną kolejność (istnieje wyjątek od tej reguły, o którym powiem w niewielkim stopniu kawałek). Na przykład, wyobraźmy sobie, że p
i q
każdy punkt gdzieś w środku tablicy arr
, jak pokazano poniżej:
int arr[9];
int* p = &arr[1];
int* q = &arr[4];
+-----+-----+-----+-----+-----+-----+-----+-----+-----+
arr | | | | | | | | | |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+
^ ^
| |
p q
W tym przypadku, wyrażenie p < q
pyta „jest indeksem w tablicy, która p
wskazuje na niższy niż indeks w tablicy, który wskazuje na q
? " W powyższym kontekście odpowiedź brzmi "tak". Jeśli p
i q
zostały odwrócone lub wskazały dokładnie ten sam element, odpowiedź brzmiałaby "nie".
Standardy językowe w językach C i C++ mówią, że wynik porównania wskaźników, które nie wskazują tej samej tablicy, jest nieokreślony, co intuicyjnie ma sens, ponieważ niepowiązane obiekty mogą być rozmieszczone dość losowo w pamięci lub być powiązane w sposób zależny od implementacji (czy twój stos rośnie lub spada?)
Jedynym wyjątkiem jest to, że możesz porównywać wskaźnik jednego obiektu za koniec tablicy ze wskaźnikiem w szyk. Na przykład, spójrz na tej konfiguracji:
int arr[9];
int* p = &arr[1];
int* q = &arr[9];
+-----+-----+-----+-----+-----+-----+-----+-----+-----+
arr | | | | | | | | | |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+
^ ^
| |
p q
Tutaj q nie wskazuje na tablicy arr
. Jednak specyfikacja językowa pozwala ci bezpiecznie porównać p i q. Dlatego na przykład można bezpiecznie używać tej pętli w stylu iteratora w C++:
for (int* itr = arr; itr != arr + /* arr's size */; itr++) {
...
}
Aby dodać: "... w przypadku, gdy masz dwa wskaźniki w tej samej tablicy _lub obiekt_". Ta dyskusja tablicowa odnosi się również do pojedynczego obiektu, tak jakby była tablicą jednego. 'some_type x;' '& x + 1> & x' jest dobrze zdefiniowane. §6.5.8 4 – chux
Można również porównywać wskaźniki do elementów tego samego obiektu zbiorczego, np. Wskaźnik do 'int a' w obiekcie struct ze wskaźnikiem do' double b' w tym samym obiekcie. –
@EricPostpischil Nie wiedziałem, że możesz to zrobić. Zakładam, że musisz użyć jakiegoś smaku wskaźników "char *" na obiektach różnych typów, aby uniknąć poważnych naruszeń aliasingu? – templatetypedef
Podejrzewam, że coś takiego będzie bardzo specyficzne dla języka. W niektórych naiwnych przypadkach wskaźniki są dosłownie (lub mogą być traktowane jak pamięć). W innych przypadkach są to bardzo specyficzne typy, a operatorzy będą zachowywać się specyficznie. – jdv
Powiązane [Biorąc pod uwagę, że p jest wskaźnikiem jest "p> nullptr" dobrze sformułowane?] (Https://stackoverflow.com/q/26590267/1708801) –
Moja odpowiedź do [Uzasadnienie do porównania wskaźnika poza tablicą do UB ] (https://stackoverflow.com/a/31151779/1708801) jest również powiązany. –