Der Zeiger ist (im Sinne eines Laien) im Wesentlichen ein ganzzahliger Wert für die Speicheradresse in Ihrem Computer. Es ist wie ein Vergleich von ganzen Zahlen.
Kemin Zhou
5
@KeminZhou: Dies ist auf den meisten aktuellen Computern wahr, aber im Allgemeinen falsch. Sogar auf dem alten 1980 PC AT 8086 war es falsch
Basile Starynkevitch
108
Für ein paar Fakten hier der relevante Text aus den Spezifikationen
Gleichheitsoperator (== ,! =)
Zeiger auf Objekte des gleichen Typs können auf Gleichheit mit den "intuitiven" erwarteten Ergebnissen verglichen werden:
Aus § 5.10 des C ++ 11-Standards:
Zeiger des gleichen Typs (nach Zeigerkonvertierungen) können auf Gleichheit verglichen werden. Zwei Zeiger desselben Typs werden genau dann gleich verglichen, wenn beide null sind, beide auf dieselbe Funktion zeigen oder beide dieselbe Adresse darstellen ( 3.9.2 ).
(Details zum Vergleich der Zeiger mit dem Element und / oder den Nullzeigerkonstanten werden weggelassen - sie werden in derselben Zeile von 'Do What I Mean' fortgesetzt :)
[...] Wenn beide Operanden null sind, werden sie gleich verglichen. Andernfalls, wenn nur einer null ist, vergleichen sie ungleich. [...]
Die auffälligste Einschränkung hat mit Virtuals zu tun, und es scheint auch logisch zu sein, dies zu erwarten:
[...] Wenn einer der beiden Zeiger auf eine virtuelle Elementfunktion ist, ist das Ergebnis nicht angegeben. Andernfalls vergleichen sie genau dann gleich, wenn sie sich auf dasselbe Mitglied desselben am meisten abgeleiteten Objekts (1.8) oder auf dasselbe Unterobjekt beziehen würden, wenn sie mit einem hypothetischen Objekt des zugeordneten Klassentyps dereferenziert würden. [...]
Vergleichsoperatoren (<,>, <=,> =)
Aus § 5.9 des C ++ 11-Standards:
Zeiger auf Objekte oder Funktionen desselben Typs (nach Zeigerkonvertierungen) können verglichen werden. Das Ergebnis ist wie folgt definiert:
Wenn zwei Zeiger p und q desselben Typ auf das gleiche Objekt oder die Funktion, oder beide eines Punktes hinter dem Ende des gleichen Array oder sind beide null, dann p<=qund p>=qsowohl Ausbeute als die tatsächliche p<qund p>qsowohl Ausbeute als falsch.
Wenn zwei Zeiger p und q desselben Typs auf unterschiedliche Objekte verweisen, die nicht Mitglieder desselben Objekts oder auf Elemente desselben Arrays oder auf unterschiedliche Funktionen sind, oder wenn nur einer von ihnen null ist, sind die Ergebnisse von p<q,p>q,p<=q,und
p>=qnicht angegeben .
Wenn zwei Zeiger rekursiv auf nicht statische Datenelemente desselben Objekts oder auf Unterobjekte oder Array-Elemente solcher Elemente verweisen, ist der Zeiger auf das später deklarierte Element größer, vorausgesetzt, die beiden Elemente haben dieselbe Zugriffssteuerung (Abschnitt 11) und vorausgesetzt, ihre Klasse ist keine Gewerkschaft.
Wenn zwei Zeiger auf nicht statische Datenelemente desselben Objekts mit unterschiedlicher Zugriffssteuerung verweisen (Abschnitt 11), ist das Ergebnis nicht angegeben.
Wenn zwei Zeiger auf nicht statische Datenelemente desselben Vereinigungsobjekts verweisen, werden sie gleich verglichen (nach Konvertierung in void*, falls erforderlich). Wenn zwei Zeiger auf Elemente desselben Arrays oder einen hinter dem Ende des Arrays zeigen, wird der Zeiger auf das Objekt mit dem höheren Index höher verglichen.
Andere Zeigervergleiche sind nicht spezifiziert.
Also, wenn Sie hätten:
int arr[3];
int *a = arr;
int *b = a + 1;
assert(a != b); // OK! well defined
Auch ok:
structX {int x,y; } s;
int *a = &s.x;
int *b = &s.y;
assert(b > a); // OK! well defined
Aber es kommt darauf an, somethingin welcher Frage:
int g;
intmain(){
int h;
int i;
int *a = &g;
int *b = &h; // can't compare a <=> bint *c = &i; // can't compare b <=> c, or a <=> c etc.// but a==b, b!=c, a!=c etc. are supported just fine
}
Bonus: Was gibt es sonst noch in der Standardbibliothek?
§ 20.8.5 / 8 : „Für Vorlagen greater, less, greater_equal, und less_equalergeben die Spezialisierungen für jeden Zeigertyp einen Gesamtauftrag, auch wenn die integrierten Operatoren <, >, <=, >=dies nicht tun.“
So können Sie global jede ungerade bestellen,void* solange Sie std::less<>und Freunde verwenden, nicht nackt operator<.
Der unnachahmliche @ JerryCoffin hat mich heute darauf aufmerksam gemacht, dass die Standardbibliothek strengere Spezifikationen für die in definierten Funktionsobjektvorlagen enthält <functional>. Hinzugefügt.
sehe
Es scheint, dass sich dieses Kapitel im laufenden C ++ - Entwurf geändert hat. Sofern ich es nicht falsch verstehe
Es ist etwas komplizierter, wenn es sich um Mehrfachvererbung handelt.
Fredoverflow
17
Um zusammenzufassen. Wenn wir sehen wollen, ob zwei Zeiger auf denselben Speicherort zeigen, können wir das tun. Auch wenn wir den Inhalt des Speichers vergleichen möchten, auf den zwei Zeiger zeigen, können wir dies auch tun. Denken Sie nur daran, sie zuerst zu dereferenzieren.
Wenn wir haben
int *a = something;
int *b = something;
Das sind zwei Zeiger des gleichen Typs, die wir können:
Einfacher Code zum Überprüfen des Zeiger-Aliasing:
intmain(){
int a = 10, b = 20;
int *p1, *p2, *p3, *p4;
p1 = &a;
p2 = &a;
if(p1 == p2){
std::cout<<"p1 and p2 alias each other"<<std::endl;
}
else{
std::cout<<"p1 and p2 do not alias each other"<<std::endl;
}
//------------------------
p3 = &a;
p4 = &b;
if(p3 == p4){
std::cout<<"p3 and p4 alias each other"<<std::endl;
}
else{
std::cout<<"p3 and p4 do not alias each other"<<std::endl;
}
return0;
}
Ausgabe:
p1 and p2 alias each other
p3 and p4 donot alias each other
Das Vergleichen von Zeigern ist nicht portierbar. Beispielsweise zeigen unter DOS verschiedene Zeigerwerte auf dieselbe Position. Der Vergleich der Zeiger gibt false zurück.
Antworten:
Ja, das ist die Definition der Zeigergleichheit: Beide zeigen auf dieselbe Position (oder sind Zeiger-Aliase ).
quelle
Für ein paar Fakten hier der relevante Text aus den Spezifikationen
Gleichheitsoperator (== ,! =)
Zeiger auf Objekte des gleichen Typs können auf Gleichheit mit den "intuitiven" erwarteten Ergebnissen verglichen werden:
Aus § 5.10 des C ++ 11-Standards:
Vergleichsoperatoren (<,>, <=,> =)
Aus § 5.9 des C ++ 11-Standards:
Also, wenn Sie hätten:
int arr[3]; int *a = arr; int *b = a + 1; assert(a != b); // OK! well defined
Auch ok:
struct X { int x,y; } s; int *a = &s.x; int *b = &s.y; assert(b > a); // OK! well defined
Aber es kommt darauf an,
something
in welcher Frage:int g; int main() { int h; int i; int *a = &g; int *b = &h; // can't compare a <=> b int *c = &i; // can't compare b <=> c, or a <=> c etc. // but a==b, b!=c, a!=c etc. are supported just fine }
Bonus: Was gibt es sonst noch in der Standardbibliothek?
§ 20.8.5 / 8 : „Für Vorlagen
greater
,less
,greater_equal
, undless_equal
ergeben die Spezialisierungen für jeden Zeigertyp einen Gesamtauftrag, auch wenn die integrierten Operatoren<
,>
,<=
,>=
dies nicht tun.“So können Sie global jede ungerade bestellen,
void*
solange Siestd::less<>
und Freunde verwenden, nicht nacktoperator<
.quelle
int *a = arr;
Leitung von einem Verweis auf stackoverflow.com/questions/8412694/address-of-array profitieren ? Ich bin mir nicht sicher, ob es für die gestellte Frage relevant genug ist ...<functional>
. Hinzugefügt.Der
==
Operator für Zeiger vergleicht seine numerische Adresse und bestimmt somit, ob sie auf dasselbe Objekt zeigen.quelle
Um zusammenzufassen. Wenn wir sehen wollen, ob zwei Zeiger auf denselben Speicherort zeigen, können wir das tun. Auch wenn wir den Inhalt des Speichers vergleichen möchten, auf den zwei Zeiger zeigen, können wir dies auch tun. Denken Sie nur daran, sie zuerst zu dereferenzieren.
Wenn wir haben
int *a = something; int *b = something;
Das sind zwei Zeiger des gleichen Typs, die wir können:
Speicheradresse vergleichen:
und Inhalte vergleichen:
quelle
Einfacher Code zum Überprüfen des Zeiger-Aliasing:
int main () { int a = 10, b = 20; int *p1, *p2, *p3, *p4; p1 = &a; p2 = &a; if(p1 == p2){ std::cout<<"p1 and p2 alias each other"<<std::endl; } else{ std::cout<<"p1 and p2 do not alias each other"<<std::endl; } //------------------------ p3 = &a; p4 = &b; if(p3 == p4){ std::cout<<"p3 and p4 alias each other"<<std::endl; } else{ std::cout<<"p3 and p4 do not alias each other"<<std::endl; } return 0; }
Ausgabe:
p1 and p2 alias each other p3 and p4 do not alias each other
quelle
Das Vergleichen von Zeigern ist nicht portierbar. Beispielsweise zeigen unter DOS verschiedene Zeigerwerte auf dieselbe Position. Der Vergleich der Zeiger gibt false zurück.
/*--{++:main.c}--------------------------------------------------*/ #include <dos.h> #include <stdio.h> #include <stdlib.h> int main(void) { int val_a = 123; int * ptr_0 = &val_a; int * ptr_1 = MK_FP(FP_SEG(&val_a) + 1, FP_OFF(&val_a) - 16); printf(" val_a = %d -> @%p\n", val_a, (void *)(&val_a)); printf("*ptr_0 = %d -> @%p\n", *ptr_0, (void *)ptr_0); printf("*ptr_1 = %d -> @%p\n", *ptr_1, (void *)ptr_1); /* Check what returns the pointers comparison: */ printf("&val_a == ptr_0 ====> %d\n", &val_a == ptr_0); printf("&val_a == ptr_1 ====> %d\n", &val_a == ptr_1); printf(" ptr_0 == ptr_1 ====> %d\n", ptr_0 == ptr_1); printf("val_a = %d\n", val_a); printf(">> *ptr_0 += 100;\n"); *ptr_0 += 100; printf("val_a = %d\n", val_a); printf(">> *ptr_1 += 500;\n"); *ptr_1 += 500; printf("val_a = %d\n", val_a); return EXIT_SUCCESS; } /*--{--:main.c}--------------------------------------------------*/
Kompilieren Sie es unter Borland C 5.0, hier ist das Ergebnis:
/*--{++:result}--------------------------------------------------*/ val_a = 123 -> @167A:0FFE *ptr_0 = 123 -> @167A:0FFE *ptr_1 = 123 -> @167B:0FEE &val_a == ptr_0 ====> 1 &val_a == ptr_1 ====> 0 ptr_0 == ptr_1 ====> 0 val_a = 123 >> *ptr_0 += 100; val_a = 223 >> *ptr_1 += 500; val_a = 723 /*--{--:result}--------------------------------------------------*/
quelle