2011-01-05 2 views
8

Solo per divertimento, ho avuto un std::list di const char*, ogni elemento che punta a una stringa di testo con terminazione null e ha eseguito uno std::list::sort() su di esso. Accade che, in un certo senso (nessun gioco di parole) non ha ordinato le stringhe. Considerando che stava lavorando a dei puntatori, questo ha senso.Come funzionano gli operatori < and > con i puntatori?

In base allo documentation di std::list::sort(), esso (per impostazione predefinita) utilizza lo operator < tra gli elementi da confrontare.

Dimenticato sull'elenco per un momento, la mia domanda effettiva è: come funzionano questi (>, <,> =, < =) sui puntatori in C++ e C? Confronta semplicemente gli attuali indirizzi di memoria?

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

esempio su un sistema little-endian a 32 bit, p1>p2 perché 0xDAB0BC47>0xBABEC475?

I test sembrano confermarlo, ma ho pensato che sarebbe stato utile inserirlo in StackOverflow per riferimento futuro. C e C++, sia fare un po 'weird things ai puntatori, in modo da non si sa mai ...

+1

Sì, si limitano a confrontare gli indirizzi di memoria. – user168715

+3

L'endiadness non è rilevante qui. p1> p2 se big/low endian. –

+1

Sì, ho notato, ma è stato divertente scrivere DABOBCAT e BABECATS con caratteri esadecimali, quindi ho ignorato la non-grandiosità dell'esempio ... – Oystein

risposta

16

In C++, non è possibile confrontare solo qualsiasi puntatore utilizzando gli operatori relazionali. È possibile confrontare solo due puntatori che puntano a elementi nello stesso array o due puntatori che puntano a membri dello stesso oggetto. (È anche possibile confrontare un puntatore con se stesso, ovviamente.)

È tuttavia possibile utilizzare std::less e gli altri oggetti della funzione di confronto relazionale per confrontare due puntatori. I risultati sono definiti dall'implementazione, ma è garantito che vi è un ordine totale.

Se si dispone di uno spazio di indirizzi flat, è probabile che i confronti tra puntatori confronti solo gli indirizzi come se fossero numeri interi.

(credo che le regole sono le stesse in C, senza gli oggetti funzione di confronto, ma qualcuno dovrà confermare che, io non sono quasi più familiarità con C come lo sono io con C++.)

+0

Il confronto di 2 puntatori confronta sempre gli indirizzi come numeri interi. –

+4

@Zac: un puntatore non è un numero intero e non è possibile confrontarlo come tale. – fredoverflow

+0

È un numero intero che rappresenta una posizione di indirizzo. E puoi (anche se confrontare due indirizzi di entità completamente separate sembra un po 'sciocco) confrontarli. In effetti, ogni volta che fai 'if (p! = NULL)', questo è ESATTAMENTE quello che stai facendo. –

1

Sì, basta confrontare l'indirizzo di memoria.

6

Questo è solo una supplenza.

In C++ 20.3.3/8:

Per modelli maggiori, meno, greater_equal, e less_equal, le specializzazioni per qualsiasi tipo puntatore cedere un ordine totale, anche se il built-in operatori <,>, < =,> = fare non.

In C 6.5.8/5:

Se due puntatori per oggetto o tipi incompleti entrambi verso il stesso oggetto, o entrambi punto uno oltre l'ultimo elemento della stessa matrice oggetto, si confrontano uguali.Se gli oggetti indicavano sono membri della stessa oggetto aggregato , puntatori a membri struttura dichiarata successivamente confronta maggiore di puntatori a membri dichiarati in precedenza nella struttura , e puntatori a matrice elementi con indice valore maggiore confronta maggiore di puntatori agli elementi dello stesso array con valori di pedice inferiori. Tutti i puntatori a membri dello stesso oggetto unione confronto uguale. Se l'espressione P punti ad un elemento di un oggetto array ei punti espressione q l'ultimo elemento dello stesso oggetto array , l'espressione puntatore Q + 1 confronta maggiore di P. In tutti gli altri casi , il comportamento non è definito.

Quindi, penso che il confronto char const* che appartengono a due diverse '\ 0'-terminated-stringa come in questione è un comportamento non definito (in C).