2011-01-05 23 views
8

Po prostu dla zabawy, miałem std::list z const char*, każdy element wskazuje na zakończony znakiem NUL ciąg tekstowy i uruchomił na nim std::list::sort(). Tak się składa, że ​​nie jest to sortowanie strun. Biorąc pod uwagę, że pracował nad wskaźnikami, ma to sens.Jak działają operatory ze wskaźnikami?

Zgodnie z documentation z , (domyślnie) używa operator < między elementami do porównania.

Zapominając o liście przez chwilę, moje aktualne pytanie brzmi: Jak operatorzy pracują nad wskaźnikami w C++ i C (>, <,> =, < =)? Czy oni po prostu porównują rzeczywiste adresy pamięci?

char* p1 = (char*) 0xDAB0BC47; 
char* p2 = (char*) 0xBABEC475; 

np. na 32-bitowym, mało-endianowym systemie, p1>p2 ponieważ 0xDAB0BC47>0xBABEC475?

Testy zdają się potwierdzać to, ale pomyślałem, że dobrze byłoby umieścić go na StackOverflow, aby móc z niego skorzystać w przyszłości. C i C++ są przeznaczone na wskaźniki, więc nigdy naprawdę nie wiadomo ...

+1

Tak, po prostu porównują adresy pamięci. – user168715

+3

Endiadness nie ma tutaj zastosowania. p1> p2 czy duży/niski endian. –

+1

Tak, zauważyłem, ale fajnie było pisać DABOBCAT i BABECATS z szesnastkowymi znakami, więc zignorowałem niezbyt wielką wielkość przykładu ... – Oystein

Odpowiedz

16

W C++ nie można porównywać żadnych wskaźników za pomocą operatorów relacyjnych. Można porównać tylko dwa wskaźniki wskazujące elementy w tej samej tablicy lub dwa wskaźniki wskazujące elementy tego samego obiektu. (Oczywiście można również porównać wskaźnik ze sobą.)

Można jednak użyć std::less i innych obiektów funkcji porównywania relacyjnego do porównania dowolnych dwóch wskaźników. Wyniki są definiowane przez implementację, ale gwarantuje się całkowitą kolejność.

Jeśli masz płaską przestrzeń adresową, prawdopodobne jest, że porównania porównań po prostu porównują adresy tak, jakby były liczbami całkowitymi.

(wierzę zasady są takie same w C, bez obiektów funkcyjnych porównanie, ale ktoś będzie musiał potwierdzić, że, nie jestem aż tak obeznany z C, jak jestem z C++).

+0

Porównywanie 2 wskaźników zawsze porównuje adresy jako liczby całkowite. –

+4

@Zac: Wskaźnik nie jest liczbą całkowitą i nie można go porównać jako takiego. – fredoverflow

+0

Jest to liczba całkowita reprezentująca lokalizację adresu. I możesz (chociaż porównywanie 2 adresów całkowicie oddzielnych jednostek wydaje się trochę głupie) porównaj je. W rzeczywistości, za każdym razem, gdy robisz 'if (p! = NULL)', to jest dokładnie to, co robisz. –

6

ten to tylko suplementacja.

C++ 20.3.3/8:

przypadku szablonów większe, mniej greater_equal i less_equal, że specjalności dla każdego rodzaju wskaźnik uzyskując zamówienia, nawet jeśli wbudowany operatorzy: <,>, < =,> = do =,> = do nie.

W C 6.5.8/5:

Jeśli dwa wskaźniki do obiektu lub niekompletnych zarówno punkt do samego obiektu, lub zarówno z punktem obok ostatni element na tej samej macierzy obiekt, porównują równe.Jeśli obiekty wskazał są członkami samym łącznym obiektu, wskaźniki do elementów konstrukcji zgłoszone później porównania większy niż wskaźniki do członków zadeklarowanych wcześniej w strukturze i wskaźniki do tablicy elementy z większym indeksem Wartości porównać większa od wskaźników do elementów tej samej tablicy o niższych wartościach indeksu niższego . Wszystkie wskaźniki do członków tego samego obiektu związku porównać równa. Jeśli wyrażenie P wskazuje na elemencie przedmiotu Tablica i punktami ekspresji Q do ostatni element na tej samej tablicy obiektu, określenie wskaźnik P + 1 porównuje większa niż P. We wszystkich innych przypadkach zachowanie jest niezdefiniowane.

Tak, myślę, że porównując char const* które należą do dwóch różnych „\ 0'zakończonego-string jak w pytaniu jest niezdefiniowane zachowanie (w C).

Powiązane problemy